__author__ = 'Shamal Faily'

RMFRAME_MENU_EXPORT = 88
RMFRAME_MENU_IMPORT = 89
RMFRAME_MENU_EXPORTMODEL = 90
RMFRAME_MENU_IMPORTMODEL = 91
RMFRAME_MENU_NEW = 96
RMFRAME_MENU_OPEN = 97
RMFRAME_MENU_SAVE = 98
RMFRAME_MENU_EXPORTPROJECT = 94
RMFRAME_MENU_IMPORTPROJECT = 93
RMFRAME_MENU_SETTINGS = 99
RMFRAME_MENU_EXIT = 100
RMFRAME_TOOL_NEW = 101
RMFRAME_TOOL_SAVE = 102
RMFRAME_TOOL_FIND = 103
RMFRAME_TOOL_COMMITREQUIREMENTS = 110
RMFRAME_TOOL_OPEN = 111
RMFRAME_TOOL_ADD = 120
RMFRAME_TOOL_DELETE = 121
RMFRAME_TOOL_DOMAINPROPERTIES = 122
RMFRAME_TOOL_GOALS = 123
RMFRAME_TOOL_OBSTACLES = 124
RMFRAME_TOOL_SETTINGS = 125
RMFRAME_TOOL_CON = 126
RMFRAME_TOOL_COM = 87
RMFRAME_TOOL_DEPENDENCIES = 127
RMFRAME_TOOL_CLASSASSOCIATIONS = 128
RMFRAME_TOOL_GOALASSOCIATIONS = 129
RMFRAME_TOOL_ASSETS = 130
RMFRAME_TOOL_ATTACKERS = 131
RMFRAME_TOOL_THREATS = 132
RMFRAME_TOOL_VULNERABILITIES = 133
RMFRAME_TOOL_RISKS = 134
RMFRAME_TOOL_RESPONSES = 135
RMFRAME_TOOL_COUNTERMEASURES = 136
RMFRAME_TOOL_ENVIRONMENTMODEL = 140
RMFRAME_TOOL_ASSETMODEL = 141
RMFRAME_TOOL_GOALMODEL = 142
RMFRAME_TOOL_OBSTACLEMODEL = 143
RMFRAME_TOOL_RESPONSIBILITYMODEL = 144
RMFRAME_TOOL_TASKMODEL = 145
RMFRAME_TOOL_APMODEL = 146
RMFRAME_TOOL_ATMODEL = 92
RMFRAME_TOOL_CMMODEL = 222
RMFRAME_TOOL_COMPONENTMODEL = 223
RMFRAME_TOOL_LOCATIONMODEL = 224
RMFRAME_TOOL_RISKSCATTER = 147
RMFRAME_TOOL_PERSONAS = 149
RMFRAME_TOOL_ROLES = 150
RMFRAME_TOOL_TASKS = 151
RMFRAME_TOOL_USECASES = 95
RMFRAME_TOOL_DOCUMENTATION = 152
RMFRAME_TOOL_COMBOOBJECT = 153
RMFRAME_TOOL_COMBOENVIRONMENT = 154
RMFRAME_MENU_OPTIONS_ASSETS = 155
RMFRAME_MENU_OPTIONS_THREATS = 156
RMFRAME_MENU_OPTIONS_RISKS = 157
RMFRAME_MENU_OPTIONS_COUNTERMEASURES = 158
RMFRAME_MENU_OPTIONS_CAPABILITIES = 159
RMFRAME_MENU_OPTIONS_MOTIVATIONS = 160
RMFRAME_MENU_OPTIONS_ASSETTYPES = 161
RMFRAME_MENU_OPTIONS_VULNERABILITYTYPES = 162
RMFRAME_MENU_OPTIONS_THREATTYPES = 163
RMFRAME_MENU_OPTIONS_SEVERITIES = 164
RMFRAME_MENU_OPTIONS_LIKELIHOODS = 165
RMFRAME_MENU_OPTIONS_TEMPLATEASSETS = 166
RMFRAME_MENU_OPTIONS_TEMPLATEREQUIREMENTS = 254
RMFRAME_MENU_OPTIONS_SECURITYPATTERNS = 167
RMFRAME_MENU_OPTIONS_EXTERNALDOCUMENTS = 168
RMFRAME_MENU_OPTIONS_DOCUMENTREFERENCES = 169
RMFRAME_MENU_OPTIONS_CONCEPTREFERENCES = 170
RMFRAME_MENU_OPTIONS_PERSONACHARACTERISTICS = 171
RMFRAME_MENU_OPTIONS_TASKCHARACTERISTICS = 253
RMFRAME_MENU_OPTIONS_IMPORTDIRECTORIES = 172
RMFRAME_MENU_OPTIONS_IMPORTTVTYPES = 218
RMFRAME_MENU_OPTIONS_EXPORTTVTYPES = 300
RMFRAME_MENU_OPTIONS_IMPORTDOMAINVALUES = 310
RMFRAME_MENU_OPTIONS_EXPORTDOMAINVALUES = 311
RMFRAME_MENU_OPTIONS_IMPORTPROCESSES = 312
RMFRAME_MENU_OPTIONS_EXPORTPROCESSES = 313
RMFRAME_MENU_OPTIONS_EXPORTIMPLIEDSPEC = 314
RMFRAME_MENU_OPTIONS_EXPORTARCHITECTURALPATTERN = 315
RMFRAME_MENU_OPTIONS_IMPORTTEMPLATEASSETS = 220
RMFRAME_MENU_OPTIONS_IMPORTSECURITYPATTERNS = 221
RMFRAME_MENU_OPTIONS_IMPORTCOMPONENTVIEW = 260
RMFRAME_MENU_OPTIONS_IMPORTSYNOPSES = 265
RMFRAME_MENU_OPTIONS_IMPORTATTACKPATTERN = 266
RMFRAME_MENU_OPTIONS_IMPORTASSETS = 267
RMFRAME_MENU_OPTIONS_ACCESSRIGHTS = 261
RMFRAME_MENU_OPTIONS_PROTOCOLS = 262
RMFRAME_MENU_OPTIONS_PRIVILEGES = 263
RMFRAME_MENU_OPTIONS_SURFACETYPES = 264
RMFRAME_MENU_VIEW_ENVIRONMENT = 174
RMFRAME_MENU_VIEW_TRACEABILITY = 175
RMFRAME_MENU_VIEW_ASSETMODEL = 176
RMFRAME_MENU_VIEW_GOALMODEL = 177
RMFRAME_MENU_VIEW_OBSTACLEMODEL = 178
RMFRAME_MENU_VIEW_RESPONSIBILITYMODEL = 179
RMFRAME_MENU_VIEW_TASKMODEL = 180
RMFRAME_MENU_VIEW_APMODEL = 181
RMFRAME_MENU_VIEW_ATMODEL = 255
RMFRAME_MENU_RIMAN_ASSETS = 182
RMFRAME_MENU_RIMAN_CLASSASSOCIATIONS = 183
RMFRAME_MENU_RIMAN_GOALASSOCIATIONS = 184
RMFRAME_MENU_RIMAN_ATTACKERS = 185
RMFRAME_MENU_RIMAN_THREATS = 186
RMFRAME_MENU_RIMAN_VULNERABILITIES = 187
RMFRAME_MENU_RIMAN_RISKS = 188
RMFRAME_MENU_RIMAN_RESPONSES = 189
RMFRAME_MENU_RIMAN_COUNTERMEASURES = 190
RMFRAME_MENU_RIMAN_EXPORTRA = 8040
RMFRAME_MENU_RIMAN_IMPORTRA = 8050
RMFRAME_MENU_IRIS_NEWENVIRONMENT = 191
RMFRAME_MENU_IRIS_DOMAINPROPERTIES = 192
RMFRAME_MENU_IRIS_GOALS = 193
RMFRAME_MENU_IRIS_OBSTACLES = 194
RMFRAME_MENU_IRIS_PERSONAS = 195
RMFRAME_MENU_IRIS_ROLES = 196
RMFRAME_MENU_IRIS_TASKS = 197
RMFRAME_MENU_IRIS_USECASES = 198
RMFRAME_MENU_IRIS_EXPORTUD = 8051
RMFRAME_MENU_IRIS_EXPORTMUD = 8056
RMFRAME_MENU_IRIS_EXPORTPERSONA = 8052
RMFRAME_MENU_IRIS_IMPORTUD = 8053
RMFRAME_MENU_IRIS_EXPORTASSOCIATIONS = 8054
RMFRAME_MENU_IRIS_IMPORTASSOCIATIONS = 8055
RMFRAME_MENU_UTILS_ARTIFACTS = 200
RMFRAME_MENU_REMAN_PROPERTIES = 211
RMFRAME_MENU_REMAN_SAVE = 212
RMFRAME_MENU_REMAN_ADD = 214
RMFRAME_MENU_REMAN_CHILD = 215
RMFRAME_MENU_REMAN_DELETE = 216
RMFRAME_MENU_IRIS_FIND = 217
RMFRAME_MENU_REMAN_EXPORT = 251
RMFRAME_MENU_REMAN_IMPORT = 252
RMFRAME_MENU_HELP_ABOUT = 230
RMFRAME_MENU_GRID_REQUIREMENTS = 256
RMFRAME_MENU_GRID_GOALS = 257
RMFRAME_MENU_GRID_OBSTACLES = 258
RMFRAME_MENU_RELABEL_OBJECTS = 259

RMPANEL_ID = 1000

NEWENVIRONMENT_ID = 4000
NEWENVIRONMENT_TEXTNAME_ID = 4010
NEWENVIRONMENT_TEXTSHORTCODE_ID = 4020
NEWENVIRONMENT_TEXTDESCRIPTION_ID = 4030
NEWENVIRONMENT_BUTTONCOMMIT_ID = 4040

OPENENVIRONMENT_ID = 3000
OPENENVIRONMENT_ENVIRONMENTLIST_ID = 3010
OPENENVIRONMENT_BUTTONOPEN_ID = 3020

ID_REQGRID = 5000

TRACE_MENUTRACE_FROM_ID = 5010
TRACE_MENUTRACE_TO_ID = 5020
TRACE_MENUTRACE_GENERATESPECIFIC_ID = 5030
TRACE_MENUTRACE_GENERATEFROMTEMPLATE_ID = 5031
TRACE_MENUTRACE_GENERATEPATTERN_ID = 5032
TRACE_MENUTRACE_REMOVEPATTERN_ID = 5033
TRACE_MENUTRACE_TURNTOGOAL_ID = 5034
TRACE_MENUTRACE_ASSOCIATESITUATED_ID = 5035
TRACE_MENUSUPPORTEDBY_ID = 5040
TRACE_MENUCONTRIBUTESTO_ID = 5050
TRACE_MENUTRACE_HISTORY_ID = 5060
TRACE_MENUTRACE_REASSOCIATE_ID = 5070

ATTACKERS_ID = 6000
ATTACKERS_ATTACKERLIST_ID = 6010
ATTACKERS_BUTTONADD_ID = 6020
ATTACKERS_BUTTONDELETE_ID = 6030

ATTACKER_ID = 7000
ATTACKER_TEXTNAME_ID = 7010
ATTACKER_TAGS_ID = 7013
ATTACKER_TEXTDESCRIPTION_ID = 7011
ATTACKER_IMAGEATTACKERIMAGE_ID = 7012
ATTACKER_PANELENVIRONMENT_ID = 7020
ATTACKER_BUTTONCOMMIT_ID = 7050

ATTACKERENVIRONMENT_LISTENVIRONMENTS_ID = 7110
ATTACKERENVIRONMENT_LISTROLES_ID = 7120
ATTACKERENVIRONMENT_LISTMOTIVES_ID = 7130
ATTACKERENVIRONMENT_LISTCAPABILITIES_ID = 7140

ASSETS_ID = 8000
ASSETS_ASSETLIST_ID = 8010
ASSETS_BUTTONADD_ID = 8020
ASSETS_BUTTONDELETE_ID = 8030

ASSET_ID = 9000
ASSET_NOTEBOOKSUMMARY_ID = 9010
ASSET_NOTEBOOKENVIRONMENT_ID = 9020
ASSET_TEXTNAME_ID = 9030
ASSET_TAGS_ID = 9032
ASSET_TEXTSHORTCODE_ID = 9031
ASSET_CHECKDIRECT_ID = 9040
ASSET_TEXTDESCRIPTION_ID = 9050
ASSET_TEXTSIGNIFICANCE_ID = 9060
ASSET_COMBOTYPE_ID = 9070
ASSET_CHECKCRITICAL_ID = 9071
ASSET_TEXTCRITICALRATIONALE_ID = 9072
ASSET_COMBOSURFACETYPE_ID = 9073
ASSET_COMBOACCESSRIGHT_ID = 9074
ASSET_LISTENVIRONMENTS_ID = 9080
ASSET_PANELENVIRONMENT_ID = 9090
ASSET_LISTASSOCIATIONS_ID = 9091
ASSET_PAGEINTERFACE_ID = 9096
ASSET_BUTTONCOMMIT_ID = 9095

ASSETENVIRONMENT_LISTENVIRONMENTS_ID = 9100
ASSETENVIRONMENT_LISTPROPERTIES_ID = 9110
ASSETENVIRONMENT_LISTASSOCIATIONS_ID = 9120

THREATS_ID = 10200
THREATS_THREATLIST_ID = 10210
THREATS_BUTTONADD_ID = 10220
THREATS_BUTTONDELETE_ID = 10230

THREAT_ID = 10300
THREAT_TEXTNAME_ID = 10310
THREAT_TAGS_ID = 10315
THREAT_THREATTYPE_ID = 10320
THREAT_TEXTMETHOD_ID = 10330
THREAT_PANELENVIRONMENT_ID = 10340
THREAT_BUTTONCOMMIT_ID = 10350

THREATENVIRONMENT_LISTENVIRONMENTS_ID = 10351
THREATENVIRONMENT_COMBOLIKELIHOOD_ID = 10352
THREATENVIRONMENT_LISTATTACKERS_ID = 10353
THREATENVIRONMENT_LISTASSETS_ID = 10354
THREATENVIRONMENT_LISTPROPERTIES_ID = 10355

VULNERABILITIES_ID = 10400
VULNERABILITIES_VULNERABILITYLIST_ID = 10410
VULNERABILITIES_BUTTONADD_ID = 10420
VULNERABILITIES_BUTTONDELETE_ID = 10430

VULNERABILITY_ID = 10500
VULNERABILITY_TEXTNAME_ID = 10510
VULNERABILITY_TAGS_ID = 10512
VULNERABILITY_COMBOTYPE_ID = 10511
VULNERABILITY_TEXTDESCRIPTION_ID = 10520
VULNERABILITY_PANELENVIRONMENT_ID = 10530
VULNERABILITY_BUTTONCOMMIT_ID = 10540

VULNERABILITYENVIRONMENT_LISTENVIRONMENTS_ID = 10550
VULNERABILITYENVIRONMENT_COMBOSEVERITY_ID = 10551
VULNERABILITYENVIRONMENT_LISTASSETS_ID = 10552

PERSONAS_ID = 10600
PERSONAS_PERSONALIST_ID = 10610
PERSONAS_BUTTONADD_ID = 10620
PERSONAS_BUTTONDELETE_ID = 10630

PERSONA_ID = 10700
PERSONA_NOTEBOOKSUMMARY_ID = 10701
PERSONA_NOTEBOOKENVIRONMENT_ID = 10702
PERSONA_TEXTNAME_ID = 10709
PERSONA_TAGS_ID = 10725
PERSONA_COMBOTYPE_ID = 10710
PERSONA_CHECKASSUMPTION_ID = 10711
PERSONA_TEXTACTIVITIES_ID = 10712
PERSONA_TEXTATTITUDES_ID = 10713
PERSONA_TEXTAPTITUDES_ID = 10714
PERSONA_TEXTMOTIVATIONS_ID = 10715
PERSONA_TEXTSKILLS_ID = 10716
PERSONA_TEXTINTRINSIC_ID = 10717
PERSONA_TEXTCONTEXTUAL_ID = 10718
PERSONA_IMAGEPERSONAIMAGE_ID = 10719
PERSONA_PANELENVIRONMENT_ID = 10720
PERSONA_LISTENVIRONMENTS_ID = 10721
PERSONA_LISTROLES_ID = 10722
PERSONA_TEXTNARRATIVE_ID = 10723
PERSONA_CHECKDIRECT_ID = 10724
PERSONA_BUTTONCOMMIT_ID = 10725

TASK_ID = 10800
TASK_NOTEBOOKENVIRONMENT_ID = 10801
TASK_TEXTNAME_ID = 10810
TASK_TAGS_ID = 10825
TASK_TEXTSHORTCODE_ID = 10812
TASK_TEXTAUTHOR_ID = 10811
TASK_TEXTOBJECTIVE_ID = 10819
TASK_CHECKASSUMPTION_ID = 10820
TASK_TEXTDEPENDENCIES_ID = 10821
TASK_PANELENVIRONMENT_ID = 10822
TASK_LISTENVIRONMENTS_ID = 10823
TASK_TEXTRISK_ID = 10830
TASK_TEXTTHREAT_ID = 10840
TASK_TEXTLIKELIHOOD_ID = 10841
TASK_TEXTVULNERABILITY_ID = 10850
TASK_TEXTSEVERITY_ID = 10851
TASK_TEXTSCORE_ID = 10860
TASK_LISTATTACKERS_ID = 10870
TASK_LISTASSETS_ID = 10880
TASK_LISTPERSONAS_ID = 10890
TASK_TEXTNARRATIVE_ID = 10891
TASK_TEXTCONSEQUENCES_ID = 10892
TASK_TEXTBENEFITS_ID = 10893
TASK_LISTCONCERNASSOCIATIONS_ID = 10894
TASK_BUTTONCOMMIT_ID = 10895

TASKS_ID = 10900
TASKS_TASKLIST_ID = 10910
TASKS_MENUTRACE_ENVIRONMENT_ID = 10920
TASKS_BUTTONADD_ID = 10930
TASKS_BUTTONDELETE_ID = 10940

DIMLIST_MENUADD_ID = 10950
DIMLIST_MENUDELETE_ID = 10960
DIMLIST_MENUGENERATE_ID = 10961
ENVLIST_MENUNEWENVIRONMENT_ID = 10970
ENVLIST_MENUINHERITENVIRONMENT_ID = 10980

DIMNAME_ID = 11000
DIMNAME_LISTDIM_ID = 11010
DIMNAME_BUTTONACTION_ID = 11020

TRACE_ID = 11100
TRACE_LISTDIM_ID = 11110
TRACE_LISTVALUES_ID = 11120
TRACE_TEXTLABEL_ID = 11125
TRACE_BUTTONADD_ID = 11130

RISKS_ID = 11200
RISKS_LISTRISKS_ID = 11210
RISKS_BUTTONADD_ID = 11220
RISKS_BUTTONDELETE_ID = 11230

RISK_ID = 11300
RISK_TEXTNAME_ID = 11310
RISK_TAGS_ID = 11315
RISK_COMBOTHREAT_ID = 11320
RISK_COMBOVULNERABILITY_ID = 11330
RISK_LISTENVIRONMENTS_ID = 11340
RISK_TEXTRATING_ID = 11350
RISK_LISTSCORE_ID = 11360
RISK_BUTTONDETAILS_ID = 11370
RISK_TEXTSCOREDETAILS_ID = 11380
RISK_BUTTONMISUSECASE_ID = 11389
RISK_BUTTONCOMMIT_ID = 11390

RESPONSES_ID = 11400
RESPONSES_LISTRESPONSES_ID = 11410
RESPONSES_BUTTONADD_ID = 11420
RESPONSES_BUTTONDELETE_ID = 11430

RESPONSE_ID = 11500
RESPONSE_TEXTNAME_ID = 11501
RESPONSE_TAGS_ID = 11504
RESPONSE_COMBORISK_ID = 11502
RESPONSE_BUTTONCOMMIT_ID = 11503

ACCEPT_PANELENVIRONMENT_ID = 11510
ACCEPT_LISTENVIRONMENTS_ID = 11511
ACCEPT_COMBOCOST_ID = 11512
ACCEPT_TEXTRATIONALE_ID = 11513

TRANSFER_PANELENVIRONMENT_ID = 11520
TRANSFER_LISTENVIRONMENTS_ID = 11521
TRANSFER_COMBOCOST_ID = 11522
TRANSFER_LISTROLES_ID = 11523
TRANSFER_TEXTRATIONALE_ID = 11524

MITIGATE_PANELENVIRONMENT_ID = 11530
MITIGATE_LISTENVIRONMENTS_ID = 11531
MITIGATE_COMBOTYPE_ID = 11532
MITIGATE_COMBODETECTIONPOINT_ID = 11533
MITIGATE_LISTDETMECH_ID = 11534

COUNTERMEASURE_ID = 11540
COUNTERMEASURE_NOTEBOOKENVIRONMENT_ID = 11541
COUNTERMEASURE_TEXTNAME_ID = 11542
COUNTERMEASURE_TAGS_ID = 11555
COUNTERMEASURE_COMBOTYPE_ID = 11543
COUNTERMEASURE_TEXTDESCRIPTION_ID = 11544
COUNTERMEASURE_PANELENVIRONMENT_ID = 11545
COUNTERMEASURE_LISTENVIRONMENTS_ID = 11546
COUNTERMEASURE_LISTREQUIREMENTS_ID = 11547
COUNTERMEASURE_LISTTARGETS_ID = 11548
COUNTERMEASURE_LISTPROPERTIES_ID = 11549
COUNTERMEASURE_COMBOCOST_ID = 11550
COUNTERMEASURE_LISTROLES_ID = 11551
COUNTERMEASURE_LISTTASKS_ID = 11552
COUNTERMEASURE_LISTPERSONAS_ID = 11553
COUNTERMEASURE_BUTTONCOMMIT_ID = 11554

REQUIREMENT_ID = 11600
REQUIREMENT_TEXTLABEL_ID = 11610
REQUIREMENT_TEXTDESCRIPTION_ID = 11620
REQUIREMENT_TEXTPRIORITY_ID = 11630
REQUIREMENT_TEXTRATIONALE_ID = 11640
REQUIREMENT_TEXTFITCRITERION_ID = 11650
REQUIREMENT_TEXTORIGINATOR_ID = 11660

TRACES_ID = 11700
TRACES_LISTTRACES_ID = 11710
TRACES_BUTTONADD_ID = 11720
TRACES_BUTTONDELETE_ID = 11730

TRACE_ID = 11800
TRACEDIALOG_ID = 11801
TRACE_COMBOFROMOBJECT_ID = 11810
TRACE_COMBOFROMNAME_ID = 11820
TRACE_COMBOTOOBJECT_ID = 11830
TRACE_COMBOTONAME_ID = 11840
TRACE_BUTTONCOMMIT_ID = 11850

SELECTPARENT_ID = 11900
SELECTPARENT_LISTREQUIREMENTS_ID = 11910
SELECTPARENT_BUTTONSELECT_ID = 11920

ENVIRONMENTDIALOG_ID = 12000
ENVIRONMENTDIALOG_TREEENVIRONMENT_ID = 12010

CADDIALOG_ID = 12100
CADDIALOG_TREEENVIRONMENT_ID = 12110
CADDIALOG_BUTTONDETAILS_ID = 12120
CADDIALOG_BUTTONCONFIRM_ID = 12130

DEPENDENTS_ID = 12200
DEPENDENTS_BUTTONCONFIRM_ID = 12220

MODELVIEWER_ID = 12300
MODELVIEWER_COMBONODEIDS_ID = 12310
MODELVIEWER_TEXTNODENAME_ID = 12320

ENVIRONMENTS_ID = 12400
ENVIRONMENTS_LISTENVIRONMENTS_ID = 12410
ENVIRONMENTS_BUTTONADD_ID = 12420
ENVIRONMENTS_BUTTONDELETE_ID = 12430

ENVIRONMENT_ID = 12500
ENVIRONMENT_TEXTNAME_ID = 12510
ENVIRONMENT_TEXTSHORTCODE_ID = 12520
ENVIRONMENT_LISTENVIRONMENTS_ID = 12530
ENVIRONMENT_PANELENVIRONMENTPROPERTIES_ID = 12540
ENVIRONMENT_RADIOOVERRIDE_ID = 12550
ENVIRONMENT_COMBOOVERRIDE_ID = 12560
ENVIRONMENT_RADIOMAXIMISE_ID = 12570
ENVIRONMENT_TEXTDESCRIPTION_ID = 12580
ENVIRONMENT_BUTTONCOMMIT_ID = 12590

PROPERTIESLISTCTRL_MENUADD_ID = 12600
PROPERTIESLISTCTRL_MENUDELETE_ID = 12610

PROPERTY_ID = 12700
PROPERTY_COMBOPROPERTY_ID = 12710
PROPERTY_COMBOVALUE_ID = 12720
PROPERTY_TEXTRATIONALE_ID = 12725
PROPERTY_BUTTONADD_ID = 12730

INCONSISTENCIES_ID = 12800
INCONSISTENCIES_LISTINCONSISTENCIES_ID = 12810
INCONSISTENCIES_BUTTONADD_ID = 12820
INCONSISTENCIES_BUTTONDELETE_ID = 12330

ROLES_ID = 12900
ROLES_LISTROLES_ID = 12910
ROLES_BUTTONADD_ID = 12920
ROLES_BUTTONDELETE_ID = 12930

ROLE_ID = 13000
ROLE_TEXTNAME_ID = 13010
ROLE_TAGS_ID = 13025
ROLE_COMBOTYPE_ID = 13011
ROLE_TEXTSHORTCODE_ID = 13012
ROLE_TEXTDESCRIPTION_ID = 13020
ROLE_PANELENVIRONMENT_ID = 13021
ROLE_LISTENVIRONMENTS_ID = 13022
ROLE_LISTRESPONSES_ID = 13023
ROLE_LISTCOUNTERMEASURES_ID = 13024
ROLE_BUTTONCOMMIT_ID = 13040

TARGETLISTCTRL_MENUADD_ID = 13100
TARGETLISTCTRL_MENUDELETE_ID = 13110

TARGET_ID = 13200
TARGET_COMBOTARGET_ID = 13210
TARGET_COMBOEFFECTIVENESS_ID = 13220
TARGET_TEXTRATIONALE_ID = 13225
TARGET_BUTTONCOMMIT_ID = 13330

ARTIFACTS_ID = 13300
ARTIFACTS_COMBOARTIFACTTYPE_ID = 13310
ARTIFACTS_GRIDARTIFACTS_ID = 13320
ARTIFACTS_BUTTONUPDATE_ID = 13330

DIMUPDATE_ID = 13400
DIMUPDATE_LISTDIM_ID = 13410
DIMUPDATE_BUTTONADD_ID = 13420
DIMUPDATE_BUTTONDELETE_ID = 13430
DIMUPDATE_BUTTONUPDATE_ID = 13440

PROPUPDATE_ID = 13500
PROPUPDATE_LISTPROPERTIES_ID = 13510
PROPUPDATE_BUTTONUPDATE_ID = 13520

COSTLISTCTRL_MENUADD_ID = 13600
COSTLISTCTRL_MENUDELETE_ID = 13610

ROLECOST_ID = 13700
ROLECOST_COMBOROLE_ID = 13710
ROLECOST_COMBOCOST_ID = 13720
ROLECOST_BUTTONADD_ID = 13730

RESPONSECOST_ID = 13800
RESPONSECOST_COMBORESPONSE_ID = 13810
RESPONSECOST_COMBOCOST_ID = 13820
RESPONSECOST_BUTTONADD_ID = 13830

CAPABILITIESLISTCTRL_MENUADD_ID = 13900
CAPABILITIESLISTCTRL_MENUDELETE_ID = 13910

CAPABILITY_ID = 14000
CAPABILITY_COMBOCAPABILITY_ID = 14010
CAPABILITY_COMBOVALUE_ID = 14020
CAPABILITY_BUTTONADD_ID = 14030

COUNTERMEASURES_ID = 14100
COUNTERMEASURES_LISTCOUNTERMEASURES_ID = 14110
COUNTERMEASURES_BUTTONADD_ID = 14120
COUNTERMEASURES_BUTTONDELETE_ID = 14130

TRACEABILITY_ID = 15000
TRACEABILITY_COMBOENVIRONMENT_ID = 15010
TRACEABILITY_BUTTONDELETE_ID = 15020
TRACEABILITY_LISTTRACES_ID = 15030

GOALS_ID = 15100
GOALS_GOALLIST_ID = 15110
GOALS_BUTTONADD_ID = 15120
GOALS_BUTTONDELETE_ID = 15130

GOAL_ID = 15200
GOAL_NOTEBOOKENVIRONMENT_ID = 15201
GOAL_PANELSUMMARY_ID = 15202
GOAL_TEXTNAME_ID = 15210
GOAL_TAGS_ID = 15215
GOAL_TEXTORIGINATOR_ID = 15211
GOAL_PANELENVIRONMENT_ID = 15220
GOAL_LISTENVIRONMENTS_ID = 15230
GOAL_TEXTDEFINITION_ID = 15240
GOAL_COMBOCONTRIBUTIONTYPE_ID = 15241
GOAL_TEXTLABEL_ID = 15242
GOAL_COMBOCATEGORY_ID = 15250
GOAL_COMBOPRIORITY_ID = 15260
GOAL_TEXTFITCRITERION_ID = 15270
GOAL_TEXTISSUE_ID = 15280
GOAL_LISTGOALREFINEMENTS_ID = 15281
GOAL_LISTSUBGOALREFINEMENTS_ID = 15282
GOAL_LISTCONCERNS_ID = 15283
GOAL_LISTCONCERNASSOCIATIONS_ID = 15284
GOAL_BUTTONCOMMIT_ID = 15290

MISUSECASE_ID = 16000
MISUSECASE_TEXTNAME_ID = 16100
MISUSECASE_TEXTRISK_ID = 16110
MISUSECASE_NOTEBOOK_ID = 16111
MISUSECASE_TEXTOBJECTIVE_ID = 16120
MISUSECASE_LISTATTACKERS_ID = 16130
MISUSECASE_LISTASSETS_ID = 16140
MISUSECASE_TEXTTHREAT_ID = 16150
MISUSECASE_TEXTLIKELIHOOD_ID = 16160
MISUSECASE_TEXTVULNERABILITY_ID = 16170
MISUSECASE_TEXTSEVERITY_ID = 16180
MISUSECASE_PANELENVIRONMENT_ID = 16190
MISUSECASE_LISTENVIRONMENTS_ID = 16200
MISUSECASE_BUTTONCOMMIT_ID = 16210
MISUSECASE_TEXTSCORE_ID = 16220
MISUSECASE_TEXTNARRATIVE_ID = 16230

TASKPERSONA_ID = 16300
TASKPERSONA_COMBONAME_ID = 16310
TASKPERSONA_COMBODURATION_ID = 16320
TASKPERSONA_COMBOFREQUENCY_ID = 16330
TASKPERSONA_COMBODEMANDS_ID = 16340
TASKPERSONA_COMBOGOALSUPPORT_ID = 16350
TASKPERSONA_BUTTONADD_ID = 16360

TASKPERSONALISTCTRL_MENUADD_ID = 16400
TASKPERSONALISTCTRL_MENUDELETE_ID = 16410

COUNTERMEASURETASKPERSONA_ID = 16500
COUNTERMEASURETASKPERSONA_TEXTTASK_ID = 16510
COUNTERMEASURETASKPERSONA_TEXTPERSONA_ID = 16520
COUNTERMEASURETASKPERSONA_COMBODURATION_ID = 16530
COUNTERMEASURETASKPERSONA_COMBOFREQUENCY_ID = 16540
COUNTERMEASURETASKPERSONA_COMBODEMANDS_ID = 16550
COUNTERMEASURETASKPERSONA_COMBOGOALSUPPORT_ID = 16560
COUNTERMEASURETASKPERSONA_BUTTONADD_ID = 16570

CLASSASSOCIATION_ID = 16600
CLASSASSOCIATION_COMBOENVIRONMENT_ID = 16610
CLASSASSOCIATION_COMBOHEADASSET_ID = 16620
CLASSASSOCIATION_COMBOHEADNAV_ID = 16621
CLASSASSOCIATION_COMBOHEADTYPE_ID = 16630
CLASSASSOCIATION_COMBOHEADMULTIPLICITY_ID = 16640
CLASSASSOCIATION_TEXTHEADROLE_ID = 16650
CLASSASSOCIATION_TEXTTAILROLE_ID = 16660
CLASSASSOCIATION_COMBOTAILMULTIPLICITY_ID = 16670
CLASSASSOCIATION_COMBOTAILTYPE_ID = 16680
CLASSASSOCIATION_COMBOTAILNAV_ID = 16681
CLASSASSOCIATION_COMBOTAILASSET_ID = 16690
CLASSASSOCIATION_BUTTONCOMMIT_ID = 16700

CLASSASSOCIATIONS_ID = 16700
CLASSASSOCIATIONS_CLASSASSOCIATIONLIST_ID = 16710
CLASSASSOCIATIONS_BUTTONADD_ID = 16720
CLASSASSOCIATIONS_BUTTONDELETE_ID = 16730

GOALASSOCIATION_ID = 16800
GOALASSOCIATION_COMBOENVIRONMENT_ID = 16810
GOALASSOCIATION_COMBOGOALDIM_ID = 16811
GOALASSOCIATION_COMBOGOAL_ID = 16820
GOALASSOCIATION_CHECKALTERNATIVE_ID = 16830
GOALASSOCIATION_COMBOATYPE_ID = 16840
GOALASSOCIATION_COMBOSUBGOALDIM_ID = 16841
GOALASSOCIATION_COMBOSUBGOAL_ID = 16850
GOALASSOCIATION_TEXTRATIONALE_ID = 16860
GOALASSOCIATION_BUTTONCOMMIT_ID = 16870

GOALASSOCIATIONS_ID = 16900
GOALASSOCIATIONS_GOALASSOCIATIONLIST_ID = 16910
GOALASSOCIATIONS_BUTTONADD_ID = 16920
GOALASSOCIATIONS_BUTTONDELETE_ID = 16930

PIV_MENULOAD_LOADIMAGE_ID = 17000

DOMAINPROPERTIES_ID = 17010
DOMAINPROPERTIES_DOMAINPROPERTYLIST_ID = 17020
DOMAINPROPERTIES_BUTTONADD_ID = 17030
DOMAINPROPERTIES_BUTTONDELETE_ID = 17040

DOMAINPROPERTY_ID = 17100
DOMAINPROPERTY_TEXTNAME_ID = 17110
DOMAINPROPERTY_TAGS_ID = 17115
DOMAINPROPERTY_COMBODOMAIN_ID = 17120
DOMAINPROPERTY_COMBOTYPE_ID = 17130
DOMAINPROPERTY_TEXTORIGINATOR_ID = 17131
DOMAINPROPERTY_TEXTDESCRIPTION_ID = 17140
DOMAINPROPERTY_BUTTONCOMMIT_ID = 17150

OBSTACLES_ID = 17200
OBSTACLES_OBSTACLELIST_ID = 17210
OBSTACLES_BUTTONADD_ID = 17220
OBSTACLES_BUTTONDELETE_ID = 17230

OBSTACLE_ID = 17300
OBSTACLE_TEXTNAME_ID = 17310
OBSTACLE_TAGS_ID = 17312
OBSTACLE_TEXTORIGINATOR_ID = 17315
OBSTACLE_PANELENVIRONMENT_ID = 17320
OBSTACLE_NOTEBOOKENVIRONMENT_ID = 17330
OBSTACLE_LISTENVIRONMENTS_ID = 17340
OBSTACLE_TEXTDEFINITION_ID = 17350
OBSTACLE_TEXTLABEL_ID = 17351
OBSTACLE_TEXTPROBABILITY_ID = 17352
OBSTACLE_COMBOCATEGORY_ID = 17360
OBSTACLE_LISTGOALS_ID = 17365
OBSTACLE_LISTSUBGOALS_ID = 17370
OBSTACLE_LISTCONCERNS_ID = 17371
OBSTACLE_BUTTONCOMMIT_ID = 17380

SGA_MENUADD_ID = 17400
SGA_MENUDELETE_ID = 17410

GOALREFINEMENT_ID = 17500
GOALREFINEMENT_COMBOGOAL_ID = 17510
GOALREFINEMENT_COMBOGOALDIMENSION_ID = 17520
GOALREFINEMENT_COMBOREFINEMENT_ID = 17530
GOALREFINEMENT_COMBOALTERNATE_ID = 17540
GOALREFINEMENT_TEXTRATIONALE_ID = 17550
GOALREFINEMENT_BUTTONCOMMIT_ID = 17560

ASSETASSOCIATION_ID = 17600
ASSETASSOCIATION_COMBOHEADNAV_ID = 17601
ASSETASSOCIATION_COMBOHEADTYPE_ID = 17610
ASSETASSOCIATION_COMBOHEADMULTIPLICITY_ID = 17620
ASSETASSOCIATION_TEXTHEADROLE_ID = 17630
ASSETASSOCIATION_TEXTTAILROLE_ID = 17640
ASSETASSOCIATION_COMBOTAILMULTIPLICITY_ID = 17650
ASSETASSOCIATION_COMBOTAILTYPE_ID = 17660
ASSETASSOCIATION_COMBOTAILNAV_ID = 17661
ASSETASSOCIATION_COMBOTAILASSET_ID = 17670
ASSETASSOCIATION_BUTTONCOMMIT_ID = 17680

AA_MENUADD_ID = 17700
AA_MENUDELETE_ID = 17710

GENDOCDIALOG_ID = 17800

GENDOCPANEL_ID = 17900
GENDOCPANEL_COMBODOCTYPE_ID = 17910
GENDOCPANEL_CHECKHTML_ID = 17920
GENDOCPANEL_CHECKRTF_ID = 17930
GENDOCPANEL_CHECKPDF_ID = 17940
GENDOCPANEL_BUTTONGENERATE_ID = 17950

REQDOCPANEL_ID = 18000
REQDOCPANEL_CHECKPROJECTPURPOSE_ID = 18010
REQDOCPANEL_CHECKENVIRONMENTS_ID = 18020
REQDOCPANEL_CHECKSTAKEHOLDERS_ID = 18030
REQDOCPANEL_CHECKMANDATEDCONSTRAINTS_ID = 18040
REQDOCPANEL_CHECKNAMINGCONVENTIONS_ID = 18050
REQDOCPANEL_CHECKPROJECTSCOPE_ID = 18060
REQDOCPANEL_CHECKASSETS_ID = 18070
REQDOCPANEL_CHECKTASKS_ID = 18080
REQDOCPANEL_CHECKUSECASES_ID = 18081
REQDOCPANEL_CHECKGOALS_ID = 18090
REQDOCPANEL_CHECKRESPONSIBILITIES_ID = 18100
REQDOCPANEL_CHECKREQUIREMENTS_ID = 18110
REQDOCPANEL_CHECKOBSTACLES_ID = 18120
REQDOCPANEL_CHECKVULNERABILITIES_ID = 18130
REQDOCPANEL_CHECKATTACKERS_ID = 18140
REQDOCPANEL_CHECKTHREATS_ID = 18150
REQDOCPANEL_CHECKRISKS_ID = 18160
REQDOCPANEL_CHECKMISUSECASES_ID = 18170
REQDOCPANEL_CHECKRESPONSES_ID = 18180
REQDOCPANEL_CHECKCOUNTERMEASURES_ID = 18190

REQDOC_PROJECTPURPOSE_ID = 0
REQDOC_ENVIRONMENTS_ID = 1
REQDOC_STAKEHOLDERS_ID = 2
REQDOC_MANDATEDCONSTRAINTS_ID = 3
REQDOC_NAMINGCONVENTIONS_ID = 4
REQDOC_PROJECTSCOPE_ID = 5
REQDOC_ASSETS_ID = 6
REQDOC_TASKS_ID = 7
REQDOC_USECASES_ID = 8
REQDOC_GOALS_ID = 9
REQDOC_RESPONSIBILITIES_ID = 10
REQDOC_REQUIREMENTS_ID = 11
REQDOC_OBSTACLES_ID = 12
REQDOC_VULNERABILITIES_ID = 13
REQDOC_ATTACKERS_ID = 14
REQDOC_THREATS_ID = 15
REQDOC_RISKS_ID = 16
REQDOC_MISUSECASES_ID = 17
REQDOC_RESPONSES_ID = 18
REQDOC_COUNTERMEASURES_ID = 19
REQDOC_DEPENDENCIES_ID = 20
REQDOC_ARCHITECTURALPATTERNS_ID = 21
REQDOC_DATAFLOWS_ID = 22
REQDOC_LOCATIONS_ID = 23
REQDOC_TEMPLATEASSETS_ID = 24
REQDOC_TEMPLATEGOALS_ID = 25
REQDOC_TEMPLATEREQUIREMENTS_ID = 26
REQDOC_SECURITYPATTERNS_ID = 27

DOCOPT_HTML_ID = 0
DOCOPT_RTF_ID = 1
DOCOPT_PDF_ID = 2
DOCOPT_ODT_ID = 3
DOCOPT_DOCX_ID = 4

PROJECTSETTINGS_ID = 18200
PROJECTSETTINGS_NOTEBOOKSETTINGS_ID = 18210
PROJECTSETTINGS_TEXTPROJECTNAME_ID = 18220
PROJECTSETTINGS_TEXTBACKGROUND_ID = 18230
PROJECTSETTINGS_TEXTGOALS_ID = 18240
PROJECTSETTINGS_TEXTSCOPE_ID = 18250
PROJECTSETTINGS_IMAGERICHPICTURE_ID = 18251
PROJECTSETTINGS_LISTDICTIONARY_ID = 18260
PROJECTSETTINGS_LISTCONTRIBUTORS_ID = 18270
PROJECTSETTINGS_LISTREVISIONS_ID = 18280
PROJECTSETTINGS_BUTTONCOMMIT_ID = 18300
PROJECTSETTINGS_PANELSETTINGS_ID = 18310

DICTIONARYENTRY_ID = 18300
DICTIONARYENTRY_TEXTNAME_ID = 18310
DICTIONARYENTRY_TEXTDEFINITION_ID = 18320
DICTIONARYENTRY_BUTTONCOMMIT_ID = 18330

DICTIONARYLISTCTRL_MENUADD_ID = 18400
DICTIONARYLISTCTRL_MENUDELETE_ID = 18410

CONTRIBUTORLISTCTRL_MENUADD_ID = 18500
CONTRIBUTORLISTCTRL_MENUDELETE_ID = 18510

CONTRIBUTORENTRY_ID = 18600
CONTRIBUTORENTRY_TEXTFIRSTNAME_ID = 18610
CONTRIBUTORENTRY_TEXTSURNAME_ID = 18620
CONTRIBUTORENTRY_TEXTAFFILIATION_ID = 18330
CONTRIBUTORENTRY_COMBOROLE_ID = 18340
CONTRIBUTORENTRY_BUTTONCOMMIT_ID = 18350

REVISIONENTRY_ID = 18700
REVISIONENTRY_TEXTREMARKS_ID = 18710
REVISIONENTRY_BUTTONCOMMIT_ID = 18720

REQUIREMENTHISTORY_ID = 18800

DOMAINVIEW_ID = 19000

VALUETYPES_ID = 20500
VALUETYPES_COMBOENVIRONMENT_ID = 20510
VALUETYPES_VALUELIST_ID = 20520
VALUETYPES_BUTTONADD_ID = 20530
VALUETYPES_BUTTONDELETE_ID = 20540

VALUETYPE_ID = 20600
VALUETYPE_TEXTNAME_ID = 20610
VALUETYPE_TEXTDESCRIPTION_ID = 20620
VALUETYPE_TEXTSCORE_ID = 20630
VALUETYPE_TEXTRATIONALE_ID = 20640
VALUETYPE_BUTTONCOMMIT_ID = 20650

SINGLEENVIRONMENT_ID = 20700

RISKSCATTER_ID = 20800
RISKSCATTER_COMBOENVIRONMENT_ID = 20810

ENVNOTEBOOK_INHERITPROPERTIES_ID = 20910

CC_DIRECTORYIMPORT_ID = 21000

DIRECTORYDIALOG_ID = 21100
DIRECTORYDIALOG_COMBOTYPE_ID = 21110
DIRECTORYDIALOG_LISTENTRIES_ID = 21120
DIRECTORYDIALOG_BUTTONIMPORT_ID = 21130

CONCA_MENUADD_ID = 21200
CONCA_MENUDELETE_ID = 21210

CONCERNASSOCIATION_ID = 21300
CONCERNASSOCIATION_COMBOSOURCE_ID = 21310
CONCERNASSOCIATION_COMBOSOURCEMULTIPLICITY_ID = 21320
CONCERNASSOCIATION_TEXTLINK_ID = 21330
CONCERNASSOCIATION_COMBOTARGET_ID = 21340
CONCERNASSOCIATION_COMBOTARGETMULTIPLICITY_ID = 21350
CONCERNASSOCIATION_BUTTONCOMMIT_ID = 21360

NARCTRL_MENUGOAL_ID = 22000
NARCTRL_MENUOBSTACLE_ID = 22005
NARCTRL_MENUREQUIREMENT_ID = 22010

DEPENDENCIES_ID = 22100
DEPENDENCIES_DEPENDENCYLIST_ID = 22110
DEPENDENCIES_BUTTONADD_ID = 22120
DEPENDENCIES_BUTTONDELETE_ID = 22130

DEPENDENCY_ID =22200
DEPENDENCY_COMBOENVIRONMENT_ID = 22210
DEPENDENCY_COMBODEPENDER_ID = 22220
DEPENDENCY_COMBODEPENDEE_ID = 22230
DEPENDENCY_COMBODTYPE_ID = 22240
DEPENDENCY_COMBODEPENDENCY_ID = 22250
DEPENDENCY_TEXTRATIONALE_ID = 22260
DEPENDENCY_BUTTONCOMMIT_ID = 22260

TEMPLATEASSETS_ID = 22300
TEMPLATEASSETS_ASSETLIST_ID = 22310
TEMPLATEASSETS_BUTTONADD_ID = 22320
TEMPLATEASSETS_BUTTONDELETE_ID = 22330

TEMPLATEASSET_ID = 22400
TEMPLATEASSET_LISTPROPERTIES_ID = 22410
TEMPLATEASSET_BUTTONCOMMIT_ID = 22420

SECURITYPATTERNS_ID = 22500
SECURITYPATTERNS_PATTERNLIST_ID = 22510
SECURITYPATTERNS_BUTTONADD_ID = 22520
SECURITYPATTERNS_BUTTONDELETE_ID = 22530

SECURITYPATTERN_ID = 22600
SECURITYPATTERN_TEXTNAME_ID = 22610
SECURITYPATTERN_NOTEBOOKPATTERN_ID = 22620
SECURITYPATTERN_TEXTCONTEXT_ID = 22630
SECURITYPATTERN_TEXTPROBLEM_ID = 22640
SECURITYPATTERN_TEXTSOLUTION_ID = 22650
SECURITYPATTERN_LISTREQUIREMENTS_ID = 22660
SECURITYPATTERN_LISTPATTERNSTRUCTURE_ID = 22670
SECURITYPATTERN_BUTTONCOMMIT_ID = 22680

PATTERNSTRUCTURE_ID = 22700
PATTERNSTRUCTURE_COMBOHEADASSET_ID = 22710
PATTERNSTRUCTURE_COMBOHEADTYPE_ID = 22720
PATTERNSTRUCTURE_COMBOHEADNAV_ID = 22725
PATTERNSTRUCTURE_COMBOHEADMULTIPLICITY_ID = 22730
PATTERNSTRUCTURE_TEXTHEADROLE_ID = 22740
PATTERNSTRUCTURE_TEXTTAILROLE_ID = 22750
PATTERNSTRUCTURE_COMBOTAILMULTIPLICITY_ID = 22760
PATTERNSTRUCTURE_COMBOTAILNAV_ID = 22765
PATTERNSTRUCTURE_COMBOTAILTYPE_ID = 22770
PATTERNSTRUCTURE_COMBOTAILASSET_ID = 22780
PATTERNSTRUCTURE_BUTTONCOMMIT_ID = 22790

PATTERNREQUIREMENT_ID = 22800
PATTERNREQUIREMENT_NOTEBOOKREQUIREMENT_ID = 22810
PATTERNREQUIREMENT_TEXTNAME_ID = 22815
PATTERNREQUIREMENT_TEXTDESCRIPTION_ID = 22820
PATTERNREQUIREMENT_COMBOTYPE_ID = 22830
PATTERNREQUIREMENT_TEXTRATIONALE_ID = 22840
PATTERNREQUIREMENT_TEXTFITCRITERION_ID = 22850
PATTERNREQUIREMENT_COMBOASSET_ID = 22860
PATTERNREQUIREMENT_BUTTONCOMMIT_ID = 22870

SPENVIRONMENT_ID = 22900
SPENVIRONMENT_BUTTONCOMMIT_ID = 22910

EXPOSEDCOUNTERMEASURE_ID = 23000
EXPOSEDCOUNTERMEASURE_BUTTONCOMMIT_ID = 23010

EXTERNALDOCUMENTS_ID = 23100
EXTERNALDOCUMENTS_DOCLIST_ID = 23110
EXTERNALDOCUMENTS_BUTTONADD_ID = 23120
EXTERNALDOCUMENTS_BUTTONDELETE_ID = 23130

EXTERNALDOCUMENT_ID = 23200
EXTERNALDOCUMENT_TEXTNAME_ID = 23210
EXTERNALDOCUMENT_TEXTVERSION_ID = 23220
EXTERNALDOCUMENT_TEXTDATE_ID = 23230
EXTERNALDOCUMENT_TEXTAUTHORS_ID = 23240
EXTERNALDOCUMENT_TEXTDESCRIPTION_ID = 23250
EXTERNALDOCUMENT_BUTTONCOMMIT_ID = 23260

DOCUMENTREFERENCES_ID = 23300
DOCUMENTREFERENCES_COMBOEXTERNALDOCUMENT_ID = 23305
DOCUMENTREFERENCES_REFLIST_ID = 23310
DOCUMENTREFERENCES_BUTTONADD_ID = 23320
DOCUMENTREFERENCES_BUTTONDELETE_ID = 23330

DOCUMENTREFERENCE_ID = 23400
DOCUMENTREFERENCE_TEXTNAME_ID = 23410
DOCUMENTREFERENCE_COMBODOCNAME_ID = 23420
DOCUMENTREFERENCE_TEXTCONTRIBUTOR_ID = 23421
DOCUMENTREFERENCE_TEXTSECTNO_ID = 23430
DOCUMENTREFERENCE_TEXTSECTTITLE_ID = 23440
DOCUMENTREFERENCE_TEXTPAGENO_ID = 23450
DOCUMENTREFERENCE_TEXTEXCERPT_ID = 23460
DOCUMENTREFERENCE_BUTTONCOMMIT_ID = 23470

PERSONACHARACTERISTICS_ID = 23500
PERSONACHARACTERISTICS_CHARLIST_ID = 23510
PERSONACHARACTERISTICS_BUTTONADD_ID = 23520
PERSONACHARACTERISTICS_BUTTONDELETE_ID = 23530

PERSONACHARACTERISTIC_ID = 23600
PERSONACHARACTERISTIC_COMBOPERSONA_ID = 23610
PERSONACHARACTERISTIC_COMBOVARIABLE_ID = 23620
PERSONACHARACTERISTIC_TEXTCHARACTERISTIC_ID = 23630
PERSONACHARACTERISTIC_TEXTQUALIFIER_ID = 23640
PERSONACHARACTERISTIC_LISTGROUNDS_ID = 23650
PERSONACHARACTERISTIC_LISTWARRANT_ID = 23660
PERSONACHARACTERISTIC_LISTBACKING_ID = 23670
PERSONACHARACTERISTIC_LISTREBUTTAL_ID = 23680
PERSONACHARACTERISTIC_BUTTONCOMMIT_ID = 23690

BVNTC_LISTCHARACTERISTICS_ID = 23710
BVNTC_VISCHARACTERISTICS_ID = 23720
BVNTC_TEXTOPENCODING_ID = 23730
BVNTC_LISTALPHABET_ID = 23740
BVNTC_CMDUNLINKCODES_ID = 23750
BVNTC_CMDMEMO_ID = 23755
BVNTC_MENU_CODING = 23760

CONCEPTREFERENCES_ID = 23800
CONCEPTREFERENCES_REFLIST_ID = 23810
CONCEPTREFERENCES_BUTTONADD_ID = 23820
CONCEPTREFERENCES_BUTTONDELETE_ID = 23830

CONCEPTREFERENCE_ID = 23900
CONCEPTREFERENCE_TEXTNAME_ID = 23910
CONCEPTREFERENCE_COMBODIMNAME_ID = 23920
CONCEPTREFERENCE_COMBOOBJTNAME_ID = 23930
CONCEPTREFERENCE_TEXTDESCRIPTION_ID = 23940
CONCEPTREFERENCE_BUTTONCOMMIT_ID = 23950

CHARACTERISTICREFERENCE_ID = 24000
CHARACTERISTICREFERENCE_BUTTONCOMMIT_ID = 24010
CHARACTERISTICREFERENCE_COMBOREFERENCE_ID = 24020
CHARACTERISTICREFERENCE_COMBODOCUMENT_ID = 24030
CHARACTERISTICREFERENCE_COMBODIMENSION_ID = 24040
CHARACTERISTICREFERENCE_TEXTDESCRIPTION_ID = 24050
CHARACTERISTICREFERENCEPANEL_ID = 24060

DRLC_MENU_REFERENCEDCHARACTERISTICS_ID = 25000

DIRECTORYENTRY_ID = 25100
DIRECTORYENTRY_TEXTLABEL_ID = 25110
DIRECTORYENTRY_TEXTNAME_ID = 25120
DIRECTORYENTRY_TEXTTYPE_ID = 25130
DIRECTORYENTRY_TEXTDESCRIPTION_ID = 25140

PERDOCPANEL_ID = 25200
PERDOCPANEL_CHECKPROJECTPURPOSE_ID = 25210
PERDOCPANEL_CHECKPROJECTSCOPE_ID = 25220
PERDOCPANEL_CHECKENVIRONMENTS_ID = 25230
PERDOCPANEL_CHECKSTAKEHOLDERS_ID = 25240
PERDOCPANEL_CHECKTASKS_ID = 25250

USECASE_ID = 25300
USECASE_TEXTNAME_ID = 25310
USECASE_TAGS_ID = 25312
USECASE_TEXTAUTHOR_ID = 25315
USECASE_TEXTSHORTCODE_ID = 25320
USECASE_LISTACTORS_ID = 25330
USECASE_TEXTDESCRIPTION_ID = 25340
USECASE_LISTENVIRONMENTS_ID = 25350
USECASE_TEXTPRECONDITION_ID = 25360
USECASE_PANELENVIRONMENT_ID = 25370
USECASE_LISTENVIRONMENTS_ID = 25380
USECASE_GRIDFLOW_ID = 25390
USECASE_TEXTPOSTCONDITION_ID = 25391
USECASE_LISTEXCEPTIONS_ID = 25392
USECASE_BUTTONCOMMIT_ID = 25393
USECASE_NOTEBOOKENVIRONMENT_ID = 25394
USECASE_PANELFLOW_ID = 25395

EXCEPTION_ID = 25500
EXCEPTION_TEXTNAME_ID = 25510
EXCEPTION_RADIOREQUIREMENT_ID = 25520
EXCEPTION_RADIOGOAL_ID = 25530
EXCEPTION_COMBOGOALS_ID = 25540
EXCEPTION_COMBOCATEGORY_ID = 25550
EXCEPTION_TEXTDEFINITION_ID = 25560
EXCEPTION_BUTTONCOMMIT_ID = 25570

EXCEPTIONLIST_ID = 25600

USECASES_ID = 25700
USECASES_USECASELIST_ID = 25710
USECASES_MENUTRACE_ENVIRONMENT_ID = 25720
USECASES_BUTTONADD_ID = 25730
USECASES_BUTTONDELETE_ID = 25740

UCTCTRL_MENUGOAL_ID = 25800
UCTCTRL_MENUREQUIREMENT_ID = 25810

SINGLEREQUIREMENT_ID = 25900
SINGLEREQUIREMENT_NOTEBOOKREQUIREMENT_ID = 25910
SINGLEREQUIREMENT_COMBOTYPE_ID = 25920
SINGLEREQUIREMENT_RADIOASSET_ID = 25930
SINGLEREQUIREMENT_RADIOENVIRONMENT_ID = 25940
SINGLEREQUIREMENT_COMBOREFERRER_ID = 25950
SINGLEREQUIREMENT_COMBOPRIORITY_ID = 25960
SINGLEREQUIREMENT_TEXTDESCRIPTION_ID = 25970
SINGLEREQUIREMENT_TEXTRATIONALE_ID = 25980
SINGLEREQUIREMENT_TEXTFITCRITERION_ID = 25990
SINGLEREQUIREMENT_TEXTORIGINATOR_ID = 25991
SINGLEREQUIREMENT_COMBOCONTRIBUTIONTYPE_ID = 25992
SINGLEREQUIREMENT_BUTTONCOMMIT_ID = 25993

TASKCHARACTERISTIC_ID = 23700
TASKCHARACTERISTIC_COMBOTASK_ID = 23710
TASKCHARACTERISTIC_BUTTONCOMMIT_ID = 23720

TCNTC_LISTCHARACTERISTICS_ID = 23800
TCNTC_VISCHARACTERISTICS_ID = 23810

SEARCHMODEL_ID = 23900
SEARCHMODEL_PANEL_ID = 23910
SEARCHMODEL_TEXTSEARCHSTRING_ID = 23920
SEARCHMODEL_BUTTONFIND_ID = 23930
SEARCHMODEL_LISTRESULTS_ID = 23940
SEARCHMODEL_BUTTONCLOSE_ID = 23950

ENVIRONMENT_NOTEBOOKENVIRONMENT_ID = 24000
ENVIRONMENT_GRIDVALUETENSIONS_ID = 24010
ENVIRONMENT_TEXTTENSIONRATIONALE_ID = 24020

SEARCHOPTIONSPANEL_ID = 24100
SEARCHPANEL_CHECKTOGGLE_ID = 24105
SEARCHPANEL_CHECKPS_ID = 24110
SEARCHPANEL_CHECKENV_ID = 24120
SEARCHPANEL_CHECKROLE_ID = 24130
SEARCHPANEL_CHECKPC_ID = 24140
SEARCHPANEL_CHECKTC_ID = 24150
SEARCHPANEL_CHECKREF_ID = 24160
SEARCHPANEL_CHECKP_ID = 24170
SEARCHPANEL_CHECKTASK_ID = 24180
SEARCHPANEL_CHECKUC_ID = 24190
SEARCHPANEL_CHECKDP_ID = 24200
SEARCHPANEL_CHECKGOAL_ID = 24210
SEARCHPANEL_CHECKOBS_ID = 24220
SEARCHPANEL_CHECKREQ_ID = 24230
SEARCHPANEL_CHECKASSET_ID = 24240
SEARCHPANEL_CHECKVUL_ID = 24250
SEARCHPANEL_CHECKATTACKER_ID = 24260
SEARCHPANEL_CHECKTHR_ID = 24270
SEARCHPANEL_CHECKRISK_ID = 24280
SEARCHPANEL_CHECKRESP_ID = 24290
SEARCHPANEL_CHECKCM_ID = 24300
SEARCHPANEL_CHECKDIR_ID = 24295
SEARCHPANEL_CHECKCODE_ID = 24296
SEARCHPANEL_CHECKMEMO_ID = 24297
SEARCHPANEL_CHECKINTERNALDOCUMENT_ID = 24298
SEARCHPANEL_CHECKTAGS_ID = 24299

REFERENCESYNOPSIS_ID = 24400
REFERENCESYNOPSIS_TEXTREFNAME_ID = 24410
REFERENCESYNOPSIS_TEXTSYNOPSIS_ID = 24420
REFERENCESYNOPSIS_COMBODIMENSION_ID = 24430
REFERENCESYNOPSIS_COMBOACTORTYPE_ID = 24440
REFERENCESYNOPSIS_COMBOACTORNAME_ID = 24450
REFERENCESYNOPSIS_BUTTONCOMMIT_ID = 24460

REFERENCECONTRIBUTION_ID = 24500
REFERENCECONTRIBUTION_COMBOSOURCE_ID = 24510
REFERENCECONTRIBUTION_RADIOREFERENCE_ID = 24511
REFERENCECONTRIBUTION_RADIOCHARACTERISTIC_ID = 24512
REFERENCECONTRIBUTION_COMBODESTINATION_ID = 24520
REFERENCECONTRIBUTION_COMBOMEANSEND_ID = 24530
REFERENCECONTRIBUTION_COMBOCONTRIBUTION_ID = 24540
REFERENCECONTRIBUTION_BUTTONCOMMIT_ID = 24550

CLC_MENU_REFERENCESYNOPSIS_ID = 24600
CLC_MENU_REFERENCECONTRIBUTION_ID = 24610

USECASECONTRIBUTION_ID = 24700

STEPSYNOPSIS_ID = 24800
STEPSYNOPSIS_TEXTSYNOPSIS_ID = 24810
STEPSYNOPSIS_COMBOACTORTYPE_ID = 24820
STEPSYNOPSIS_COMBOACTORNAME_ID = 24830
STEPSYNOPSIS_BUTTONCOMMIT_ID = 24840

INTERFACELIST_MENUADD_ID = 24900
INTERFACELIST_MENUDELETE_ID = 24910

INTERFACELISTDIALOG_ID = 25000
INTERFACELISTDIALOG_COMBONAME_ID = 25010
INTERFACELISTDIALOG_COMBOTYPE_ID = 25020
INTERFACELISTDIALOG_COMBOACCESSRIGHT_ID = 25030
INTERFACELISTDIALOG_COMBOPRIVILEGE_ID = 25040

COMPONENTVIEWS_ID = 25100
COMPONENTVIEWS_LISTCOMPONENTVIEWS_ID = 25110
COMPONENTVIEWS_BUTTONADD_ID = 25120
COMPONENTVIEWS_BUTTONDELETE_ID = 25130

COMPONENTVIEW_ID =  25200
COMPONENTVIEW_TEXTNAME_ID = 25210
COMPONENTVIEW_TEXTSYNOPSIS_ID = 25220
COMPONENTVIEW_LISTCOMPONENTS_ID = 25240
COMPONENTVIEW_LISTCONNECTORS_ID = 25250
COMPONENTVIEW_NOTEBOOKCOMPONENTVIEW_ID = 25255
COMPONENTVIEW_BUTTONCOMMIT_ID = 25260
COMPONENTLIST_VIEWASSETS_ID = 25270
COMPONENTLIST_VIEWGOALS_ID = 25280

COMPONENT_ID = 25300
COMPONENT_TEXTNAME_ID = 25310
COMPONENT_TEXTDESCRIPTION_ID = 25320
COMPONENT_LISTINTERFACES_ID = 25330
COMPONENT_LISTSTRUCTURE_ID = 25340
COMPONENT_LISTREQUIREMENTS_ID = 25350
COMPONENT_LISTGOALS_ID = 25355
COMPONENT_BUTTONCOMMIT_ID = 25360

CONNECTOR_ID = 25400
CONNECTOR_TEXTNAME_ID = 25410
CONNECTOR_COMBOFROMNAME_ID = 25420
CONNECTOR_TEXTFROMROLE_ID = 25425
CONNECTOR_COMBOFROMINTERFACE_ID = 25430
CONNECTOR_COMBOTONAME_ID = 25440
CONNECTOR_COMBOTOINTERFACE_ID = 25450
CONNECTOR_TEXTTOROLE_ID = 25460
CONNECTOR_COMBOASSET_ID = 25470
CONNECTOR_COMBOPROTOCOL_ID = 25480
CONNECTOR_COMBOACCESSRIGHT_ID = 25490
CONNECTOR_BUTTONCOMMIT_ID = 25500

COMPONENTVIEWMITIGATION_ID = 25500
COMPONENTVIEWMITIGATION_LISTVULNERABILITIES_ID = 25510
COMPONENTVIEWMITIGATION_LISTTHREATS_ID = 25520
COMPONENTVIEWMITIGATION_BUTTONCOMMIT_ID = 25530

WEAKNESSANALYSIS_ID = 25600
WEAKNESSANALYSIS_NOTEBOOKWEAKNESS_ID = 25610
WEAKNESSANALYSIS_LISTTHREATS_ID = 25620
WEAKNESSANALYSIS_LISTVULNERABILITIES_ID = 25630
WEAKNESSANALYSIS_LISTPERSONAIMPACT_ID = 25640
WEAKNESSANALYSIS_LISTGOALOBSTACLE_ID = 25650
WEAKNESSANALYSIS_BUTTONCOMMIT_ID = 25660

WEAKNESSTREATMENT_ID = 25700
WEAKNESSTREATMENT_RADIOGOAL_ID = 25705
WEAKNESSTREATMENT_RADIOREQUIREMENT_ID = 25706
WEAKNESSTREATMENT_COMBOREQGOAL_ID = 25710
WEAKNESSTREATMENT_COMBOASSET_ID = 25720
WEAKNESSTREATMENT_COMBOEFFECTIVENESS_ID = 25730
WEAKNESSTREATMENT_TEXTRATIONALE_ID = 25740
WEAKNESSTREATMENT_BUTTONCOMMIT_ID = 25750

TEMPLATEREQUIREMENTS_ID = 25800
TEMPLATEREQUIREMENTS_REQUIREMENTLIST_ID = 25810
TEMPLATEREQUIREMENTS_BUTTONADD_ID = 25820
TEMPLATEREQUIREMENTS_BUTTONDELETE_ID = 25830

TEMPLATEREQUIREMENT_ID = 25900
TEMPLATEREQUIREMENT_NOTEBOOKREQUIREMENT_ID = 25910
TEMPLATEREQUIREMENT_TEXTNAME_ID = 25920
TEMPLATEREQUIREMENT_TEXTDESCRIPTION_ID = 25930
TEMPLATEREQUIREMENT_COMBOTYPE_ID = 25940
TEMPLATEREQUIREMENT_TEXTRATIONALE_ID = 25960
TEMPLATEREQUIREMENT_TEXTFITCRITERION_ID = 25970
TEMPLATEREQUIREMENT_COMBOASSET_ID = 25980
TEMPLATEREQUIREMENT_BUTTONCOMMIT_ID = 25990

PERSONAIMPACT_ID = 26000
PERSONAIMPACT_LISTTASKIMPACT_ID = 26010
PERSONAIMPACT_LISTUSECASES_ID = 26020
PERSONAIMPACT_LISTCOMPONENTS_ID = 26030

INTERNALDOCUMENTS_ID = 26100
INTERNALDOCUMENTS_DOCLIST_ID = 26110
INTERNALDOCUMENTS_BUTTONADD_ID = 26120
INTERNALDOCUMENTS_BUTTONDELETE_ID = 26130

INTERNALDOCUMENT_ID = 26200
INTERNALDOCUMENT_TEXTNAME_ID = 26210
INTERNALDOCUMENT_TEXTDESCRIPTION_ID = 26220
INTERNALDOCUMENT_TEXTCONTENT_ID = 26230
INTERNALDOCUMENT_BUTTONCOMMIT_ID = 26240

CODES_ID = 26300
CODES_DOCLIST_ID = 26310
CODES_BUTTONADD_ID = 26320
CODES_BUTTONDELETE_ID = 26330

CODE_ID = 26400
CODE_TEXTNAME_ID = 26410
CODE_COMBOTYPE_ID = 26420
CODE_TEXTDESCRIPTION_ID = 26430
CODE_TEXTINCLUSIONCRITERIA_ID = 26440
CODE_TEXTEXAMPLE_ID = 26450
CODE_BUTTONCOMMIT_ID = 26460

CODENETWORK_ID = 26500
CODENETWORK_COMBOPERSONA_ID = 26510
CODENETWORK_IMAGENETWORK_ID = 26520
CNV_MENU_ADD_ID = 26530
CNV_MENU_EDIT_ID = 26540

CODERELATIONSHIP_ID = 26600
CODERELATIONSHIP_COMBOFROMCODE_ID = 26610
CODERELATIONSHIP_COMBOTOCODE_ID = 26620
CODERELATIONSHIP_COMBORTTYPE_ID = 26630
CODERELATIONSHIP_BUTTONADD_ID = 26640

CODERELATIONSHIPEDITOR_ID = 26700
CODERELATIONSHIP_BUTTONCOMMIT_ID = 26710
CODERELATIONSHIP_LISTRELATIONSHIPS_ID = 26720
CODERELATIONSHIPLISTCTRL_MENUADD_ID = 26730
CODERELATIONSHIPLISTCTRL_MENUDELETE_ID = 26740
CODERELATIONSHIPLISTCTRL_MENUCHARACTERISTICS_ID = 26750

IMPLIEDPROCESS_ID = 26800
IMPLIEDPROCESS_COMBOPERSONA_ID = 26810
IMPLIEDPROCESS_IMAGENETWORK_ID =  26820
IMPLIEDPROCESS_LISTRELATIONSHIPS_ID = 26830
IMPLIEDPROCESS_PAGESPECIFICATION_ID = 26840
IMPLIEDPROCESS_TEXTSPECIFICATION_ID = 26850
IMPLIEDPROCESS_LISTCHANNELS_ID = 26851
IMPLIEDPROCESS_PAGERELATIONSHIP_ID = 26860
IMPLIEDPROCESS_NOTEBOOKSPECIFICATION_ID = 26870
IMPLIEDPROCESS_PAGESUMMARY_ID = 26880
IMPLIEDPROCESS_TEXTNAME_ID = 26881
IMPLIEDPROCESS_TEXTDESCRIPTION_ID =  26882
IMPLIEDPROCESS_BUTTONCOMMIT_ID = 26890

IMPLIEDPROCESSES_ID = 26900
IMPLIEDPROCESSES_IMPLIEDPROCESSLIST_ID = 26910
IMPLIEDPROCESSES_BUTTONADD_ID = 26920
IMPLIEDPROCESSES_BUTTONDELETE_ID = 26930

TEMPLATEGOALS_ID = 27000
TEMPLATEGOALS_GOALLIST_ID = 27010
TEMPLATEGOALS_BUTTONADD_ID = 27020
TEMPLATEGOALS_BUTTONDELETE_ID = 27030

TEMPLATEREQUIREMENT_ID = 27100
TEMPLATEREQUIREMENT_NOTEBOOKREQUIREMENT_ID = 27110
TEMPLATEREQUIREMENT_TEXTNAME_ID = 27120
TEMPLATEREQUIREMENT_TEXTDESCRIPTION_ID = 27130
TEMPLATEREQUIREMENT_COMBOTYPE_ID = 27140
TEMPLATEREQUIREMENT_TEXTRATIONALE_ID = 27150
TEMPLATEREQUIREMENT_TEXTFITCRITERION_ID = 27160
TEMPLATEREQUIREMENT_COMBOASSET_ID = 27170
TEMPLATEREQUIREMENT_BUTTONCOMMIT_ID = 27180

GOALOBSTACLE_ID = 27200
GOALOBSTACLE_TEXTGOAL_ID = 27210
GOALOBSTACLE_TEXTOBSTACLE_ID = 27220
GOALOBSTACLE_BUTTONADD_ID = 27230
GOALOBSTACLE_BUTTONIGNORE_ID = 27240
GOALOBSTACLE_BUTTONCOMMIT_ID = 27250

MEMO_ID = 27300
MEMO_TEXTNAME_ID = 27310
MEMO_TEXTDESCRIPTION_ID = 27320
MEMO_BUTTONCOMMIT_ID = 27330

CODING_ID = 27400
CODING_TEXTCATEGORY_ID = 27410

CHANNELLISTCTRL_MENUADD_ID = 27500
CHANNELLISTCTRL_MENUDELETE_ID = 27510

CHANNEL_ID = 27600
CHANNEL_TEXTCHANNEL_ID = 27610
CHANNEL_TEXTDATATYPE_ID = 27620
CHANNEL_BUTTONADD_ID = 27630

RMFRAME_MENU_EUSTACE_INTERNALDOCUMENTS = 27700
RMFRAME_MENU_EUSTACE_CODES = 27710
RMFRAME_MENU_EUSTACE_QUOTATIONS = 27720
RMFRAME_MENU_EUSTACE_CODENETWORK = 27730
RMFRAME_MENU_EUSTACE_IMPLIEDPROCESSES = 27740

QUOTATIONS_ID = 27800
QUOTATIONS_LISTQUOTATIONS_ID = 27810

QUOTATIONLISTCTRL_MENUDELETE_ID = 27900

QUOTATION_ID = 28000
QUOTATION_NOTEBOOKQUOTATION_ID = 28010
QUOTATION_TEXTCODE_ID = 28020
QUOTATION_TEXTARTIFACTTYPE_ID = 28030
QUOTATION_TEXTARTIFACTNAME_ID = 28040
QUOTATION_TEXTSOURCE_ID =28050
QUOTATION_TEXTLABEL_ID = 28060
QUOTATION_TEXTSYNOPSIS_ID =28070
QUOTATION_BUTTONCOMMIT_ID = 28080

IMPLIEDCHARACTERISTIC_ID = 28100
IMPLIEDCHARACTERISTIC_IMAGENETWORK_ID = 28110
IMPLIEDCHARACTERISTIC_TEXTCHARACTERISTIC_ID = 28120
IMPLIEDCHARACTERISTIC_TEXTQUALIFIER_ID = 28130
IMPLIEDCHARACTERISTIC_TEXTINTENTION_ID = 28135
IMPLIEDCHARACTERISTIC_COMBOINTENTIONTYPE_ID = 28136
IMPLIEDCHARACTERISTIC_LISTLHS_ID = 28140
IMPLIEDCHARACTERISTIC_LISTRHS_ID = 28150
IMPLIEDCHARACTERISTIC_COMBOTYPE_ID = 28160
IMPLIEDCHARACTERISTIC_BUTTONCOMMIT_ID = 28170

CHARACTERISTICREFERENCETYPE_ID = 28200
CHARACTERISTICREFERENCETYPE_COMBOVALUE_ID = 28210
CHARACTERISTICREFERENCETYPE_TEXTCHARINTENT_ID = 28220
CHARACTERISTICREFERENCETYPE_TEXTINTENTION_ID = 28230
CHARACTERISTICREFERENCETYPE_COMBOINTTYPE_ID = 28240
CHARACTERISTICREFERENCETYPE_COMBOMEANSEND_ID = 28250
CHARACTERISTICREFERENCETYPE_COMBOCONTRIBUTION_ID = 28260
CHARACTERISTICREFERENCETYPE_BUTTONCOMMIT_ID = 28270

ID_STEPGRID = 28300
STEPGRID_MENUDELETE_ID = 28310
STEPGRID_MENUEXCEPTION_ID = 28320
STEPGRID_MENUGOAL_ID = 28330
STEPGRID_MENUOBSTACLE_ID = 28340
STEPGRID_MENUREQUIREMENT_ID = 28350
STEPGRID_MENUSYNOPSIS_ID = 28360
STEPGRID_MENUTAGS_ID = 28370

TASKCHARACTERISTICS_ID = 28400
TASKCHARACTERISTICS_CHARLIST_ID = 28410
TASKCHARACTERISTICS_BUTTONADD_ID = 28420
TASKCHARACTERISTICS_BUTTONDELETE_ID = 28430

PERDOC_PROJECTPURPOSE_ID = 0
PERDOC_PROJECTSCOPE_ID = 1
PERDOC_ENVIRONMENTS_ID = 2
PERDOC_STAKEHOLDERS_ID = 3
PERDOC_TASKS_ID = 4

DPIA_NEED_ID = 0
DPIA_PROCESSING_ID = 1
DPIA_CONSULTATION_ID = 2
DPIA_NECESSITY_ID = 3
DPIA_RISKS_ID = 4
DPIA_MEASURES_ID = 5

C_PROPERTY = 0
I_PROPERTY = 1
AV_PROPERTY = 2
AC_PROPERTY = 3
AN_PROPERTY = 4
PAN_PROPERTY = 5
UNL_PROPERTY = 6
UNO_PROPERTY = 7
C_RATIONALE = 8
I_RATIONALE = 9
AV_RATIONALE = 10
AC_RATIONALE = 11
AN_RATIONALE = 12
PAN_RATIONALE = 13
UNL_RATIONALE = 14
UNO_RATIONALE = 15

HIGH_VALUE = 3
MEDIUM_VALUE = 2
LOW_VALUE = 1
NONE_VALUE = 0

LOW_ZOOM_RATIO = 0.4
MED_ZOOM_RATIO = 0.6
HIGH_ZOOM_RATIO = 0.7

LOWKAOS_ZOOM_RATIO = 1
MEDKAOS_ZOOM_RATIO = 1.5
HIGHKAOS_ZOOM_RATIO = 2


from transformers import CLIPTextModel, CLIPTokenizer, logging
from diffusers import AutoencoderKL, UNet2DConditionModel, PNDMScheduler, DDIMScheduler, StableDiffusionPipeline
from diffusers.utils.import_utils import is_xformers_available
from os.path import isfile

# suppress partial model loading warning
logging.set_verbosity_error()

import torch
import torch.nn as nn
import torch.nn.functional as F

from torch.cuda.amp import custom_bwd, custom_fwd
from dataclasses import dataclass

class SpecifyGradient(torch.autograd.Function):
    @staticmethod
    @custom_fwd
    def forward(ctx, input_tensor, gt_grad):
        ctx.save_for_backward(gt_grad)
        # we return a dummy value 1, which will be scaled by amp's scaler so we get the scale in backward.
        return torch.ones([1], device=input_tensor.device, dtype=input_tensor.dtype)

    @staticmethod
    @custom_bwd
    def backward(ctx, grad_scale):
        gt_grad, = ctx.saved_tensors
        gt_grad = gt_grad * grad_scale
        return gt_grad, None

def seed_everything(seed):
    torch.manual_seed(seed)
    torch.cuda.manual_seed(seed)
    #torch.backends.cudnn.deterministic = True
    #torch.backends.cudnn.benchmark = True

@dataclass
class UNet2DConditionOutput:
    sample: torch.HalfTensor # Not sure how to check what unet_traced.pt contains, and user wants. HalfTensor or FloatTensor

class StableDiffusion(nn.Module):
    def __init__(self, device, fp16, vram_O, sd_version='2.1', hf_key=None):
        super().__init__()

        self.device = device
        self.sd_version = sd_version

        print(f'[INFO] loading stable diffusion...')

        if hf_key is not None:
            print(f'[INFO] using hugging face custom model key: {hf_key}')
            model_key = hf_key
        elif self.sd_version == '2.1':
            model_key = "stabilityai/stable-diffusion-2-1-base"
        elif self.sd_version == '2.0':
            model_key = "stabilityai/stable-diffusion-2-base"
        elif self.sd_version == '1.5':
            model_key = "runwayml/stable-diffusion-v1-5"
        else:
            raise ValueError(f'Stable-diffusion version {self.sd_version} not supported.')

        precision_t = torch.float16 if fp16 else torch.float32

        # Create model
        pipe = StableDiffusionPipeline.from_pretrained(model_key, torch_dtype=precision_t)

        if isfile('./unet_traced.pt'):
            # use jitted unet
            unet_traced = torch.jit.load('./unet_traced.pt')
            class TracedUNet(torch.nn.Module):
                def __init__(self):
                    super().__init__()
                    self.in_channels = pipe.unet.in_channels
                    self.device = pipe.unet.device

                def forward(self, latent_model_input, t, encoder_hidden_states):
                    sample = unet_traced(latent_model_input, t, encoder_hidden_states)[0]
                    return UNet2DConditionOutput(sample=sample)
            pipe.unet = TracedUNet()

        if is_xformers_available():
            pipe.enable_xformers_memory_efficient_attention()

        if vram_O:
            pipe.enable_sequential_cpu_offload()
            pipe.enable_vae_slicing()
            pipe.unet.to(memory_format=torch.channels_last)
            pipe.enable_attention_slicing(1)
            # pipe.enable_model_cpu_offload()
        else:
            pipe.to(device)

        self.vae = pipe.vae
        self.tokenizer = pipe.tokenizer
        self.text_encoder = pipe.text_encoder
        self.unet = pipe.unet

        self.scheduler = DDIMScheduler.from_pretrained(model_key, subfolder="scheduler", torch_dtype=precision_t)

        self.num_train_timesteps = self.scheduler.config.num_train_timesteps
        self.min_step = int(self.num_train_timesteps * 0.02)
        self.max_step = int(self.num_train_timesteps * 0.50)
        self.alphas = self.scheduler.alphas_cumprod.to(self.device) # for convenience

        print(f'[INFO] loaded stable diffusion!')

    def get_text_embeds(self, prompt, negative_prompt, batch=1):
        # prompt, negative_prompt: [str]

        # Tokenize text and get embeddings
        text_input = self.tokenizer(prompt, padding='max_length', max_length=self.tokenizer.model_max_length, truncation=True, return_tensors='pt')

        with torch.no_grad():
            text_embeddings = self.text_encoder(text_input.input_ids.to(self.device))[0]

        B, S = text_embeddings.shape[:2]
        text_embeddings = text_embeddings.repeat(1, batch, 1).view(B * batch, S, -1)

        # Do the same for unconditional embeddings
        uncond_input = self.tokenizer(negative_prompt, padding='max_length', max_length=self.tokenizer.model_max_length, return_tensors='pt')

        with torch.no_grad():
            uncond_embeddings = self.text_encoder(uncond_input.input_ids.to(self.device))[0]

        B, S = uncond_embeddings.shape[:2]
        uncond_embeddings = uncond_embeddings.repeat(1, batch, 1).view(B * batch, S, -1)

        # Cat for final embeddings
        text_embeddings = torch.cat([uncond_embeddings, text_embeddings])
        return text_embeddings

    def train_step(self, text_embeddings, pred_rgb, guidance_scale=30, as_latent=False):
        B = pred_rgb.shape[0]

        if as_latent:
            # directly downsample input as latent
            latents = F.interpolate(pred_rgb, (64, 64), mode='bilinear', align_corners=False) * 2 - 1
        else:

            # interp to 512x512 to be fed into vae.
            pred_rgb_512 = F.interpolate(pred_rgb, (512, 512), mode='bilinear', align_corners=False)

            # encode image into latents with vae, requires grad!
            latents = self.encode_imgs(pred_rgb_512)

        # timestep ~ U(0.02, 0.98) to avoid very high/low noise level
        t = torch.randint(self.min_step, self.max_step + 1, [B], dtype=torch.long, device=self.device)

        # predict the noise residual with unet, NO grad!
        with torch.no_grad():
            # add noise
            noise = torch.randn_like(latents)
            latents_noisy = self.scheduler.add_noise(latents, noise, t)
            # pred noise
            latent_model_input = torch.cat([latents_noisy] * 2)
            tt = torch.cat([t] * 2)
            # Save input tensors for UNet
            #torch.save(latent_model_input, "train_latent_model_input.pt")
            #torch.save(t, "train_t.pt")
            #torch.save(text_embeddings, "train_text_embeddings.pt")
            # print(latent_model_input.shape, t.shape, text_embeddings.shape)
            noise_pred = self.unet(latent_model_input, tt, encoder_hidden_states=text_embeddings).sample

        # perform guidance (high scale from paper!)
        noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
        noise_pred = noise_pred_text + guidance_scale * (noise_pred_text - noise_pred_uncond)

        # w(t), sigma_t^2
        w = (1 - self.alphas[t])
        # w = self.alphas[t] ** 0.5 * (1 - self.alphas[t])

        grad = w.view(-1, 1, 1, 1) * (noise_pred - noise)

        # clip grad for stable training?
        # grad = grad.clamp(-10, 10)
        grad = torch.nan_to_num(grad)

        # since we omitted an item in grad, we need to use the custom function to specify the gradient
        loss = SpecifyGradient.apply(latents, grad)

        return loss

    def produce_latents(self, text_embeddings, height=512, width=512, num_inference_steps=50, guidance_scale=7.5, latents=None):

        if latents is None:
            latents = torch.randn((text_embeddings.shape[0] // 2, self.unet.in_channels, height // 8, width // 8), device=self.device)

        self.scheduler.set_timesteps(num_inference_steps)

        with torch.autocast('cuda'):
            for i, t in enumerate(self.scheduler.timesteps):
                # expand the latents if we are doing classifier-free guidance to avoid doing two forward passes.
                latent_model_input = torch.cat([latents] * 2)

                # Save input tensors for UNet
                #torch.save(latent_model_input, "produce_latents_latent_model_input.pt")
                #torch.save(t, "produce_latents_t.pt")
                #torch.save(text_embeddings, "produce_latents_text_embeddings.pt")
                # predict the noise residual
                with torch.no_grad():
                    noise_pred = self.unet(latent_model_input, t, encoder_hidden_states=text_embeddings)['sample']

                # perform guidance
                noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
                noise_pred = noise_pred_text + guidance_scale * (noise_pred_text - noise_pred_uncond)

                # compute the previous noisy sample x_t -> x_t-1
                latents = self.scheduler.step(noise_pred, t, latents)['prev_sample']

        return latents

    def decode_latents(self, latents):

        latents = 1 / self.vae.config.scaling_factor * latents

        with torch.no_grad():
            imgs = self.vae.decode(latents).sample

        imgs = (imgs / 2 + 0.5).clamp(0, 1)

        return imgs

    def encode_imgs(self, imgs):
        # imgs: [B, 3, H, W]

        imgs = 2 * imgs - 1

        posterior = self.vae.encode(imgs).latent_dist
        latents = posterior.sample() * self.vae.config.scaling_factor

        return latents

    def prompt_to_img(self, prompts, negative_prompts='', height=512, width=512, num_inference_steps=50, guidance_scale=7.5, latents=None):

        if isinstance(prompts, str):
            prompts = [prompts]

        if isinstance(negative_prompts, str):
            negative_prompts = [negative_prompts]

        # Prompts -> text embeds
        text_embeds = self.get_text_embeds(prompts, negative_prompts) # [2, 77, 768]

        # Text embeds -> img latents
        latents = self.produce_latents(text_embeds, height=height, width=width, latents=latents, num_inference_steps=num_inference_steps, guidance_scale=guidance_scale) # [1, 4, 64, 64]

        # Img latents -> imgs
        imgs = self.decode_latents(latents) # [1, 3, 512, 512]

        # Img to Numpy
        imgs = imgs.detach().cpu().permute(0, 2, 3, 1).numpy()
        imgs = (imgs * 255).round().astype('uint8')

        return imgs

if __name__ == '__main__':

    import argparse
    import matplotlib.pyplot as plt

    parser = argparse.ArgumentParser()
    parser.add_argument('prompt', type=str)
    parser.add_argument('--negative', default='', type=str)
    parser.add_argument('--sd_version', type=str, default='2.1', choices=['1.5', '2.0', '2.1'], help="stable diffusion version")
    parser.add_argument('--hf_key', type=str, default=None, help="hugging face Stable diffusion model key")
    parser.add_argument('--fp16', action='store_true', help="use float16 for training")
    parser.add_argument('--vram_O', action='store_true', help="optimization for low VRAM usage")
    parser.add_argument('-H', type=int, default=512)
    parser.add_argument('-W', type=int, default=512)
    parser.add_argument('--seed', type=int, default=0)
    parser.add_argument('--steps', type=int, default=50)
    opt = parser.parse_args()

    seed_everything(opt.seed)

    device = torch.device('cuda')

    sd = StableDiffusion(device, opt.fp16, opt.vram_O, opt.sd_version, opt.hf_key)

    imgs = sd.prompt_to_img(opt.prompt, opt.negative, opt.H, opt.W, opt.steps)

    # visualize image
    plt.imshow(imgs[0])
    plt.show()


# _*_ coding: utf-8 _*_
__author__ = 'daiyaquan'
__date__ = '2018/6/2 9:20'

class Solution:
    def removeNthFromEnd(self, head, n):
        """
        1. 双指针，一个是一开始启动的，一个是慢一点启动的，通过n来控制什么时候启动第二个needle
        """
        needle = head
        slow_needle = None
        virtual_head = ListNode(None)
        virtual_head.next = head

        while needle:

            needle = needle.next
            if n > 0:
                n -= 1

            if n == 0:
                if slow_needle is None:
                    slow_pre = virtual_head
                    slow_needle = head
                else:
                    slow_pre = slow_needle
                    slow_needle = slow_needle.next

        # 删除节点
        if n == 0:
            slow_pre.next = slow_needle.next

        return virtual_head.next


import pandas as pd
import numpy as np
import ruptures as rpt
from scipy.signal import find_peaks
from   scipy.stats import norm
from   scipy.special import logsumexp
import sdt.changepoint as sdt_cp
#import numba

'''===========TOOLS  - Split dataset; Peak Finder============='''

def split_dataset(dataset, segment_size):
    '''Computational cost for offline bayesian search method is ????(look this up, I think it's O(n^2)

    If you can expect that the probability for change point segments to be less than a certain log distance
    then splitting the log into many segments can greatly improve computation time

    This is currently only built with the sdt-python offline Bayesian method that concatenates a continuous
    probabilty curve for the input dataset.

    Inputs:
    Dataset (numpy array, this will handle multi-dimentonal data as well, in a horizonal stack)
    Segment size  ( legth of segments, last segment will be what is a remainder after n complete segments)

    '''

    segments = []
    current_segment = []
    segment_num = 0

    for idx, item in enumerate(dataset):
        current_segment.append(item)
        if len(current_segment) == segment_size:
            segment_num += 1
            segments.append([segment_num, idx - segment_size + 1, idx + 1])
            current_segment = []

    if current_segment:
        segment_num += 1
        segments.append([segment_num, len(dataset) - len(current_segment), len(dataset)])

    return segments

def find_prob_peaks(data, height=0.1, return_peak_heights=False):
    '''Wrapper for scipy find peaks function

    Taks in 1D numpy data array and outputs array of local maximums

    hight function sets minimum threshold, default is 0.01
    '''

    peaks, _peak_heights = find_peaks(data, height=height)

    if return_peak_heights == True:
        return peaks, _peak_heights
    else:
        return peaks

def bayes_offline_split(data, segment_length=1000, **kwargs):
    '''For computational efficiency, datasets are split into equal segments for ChangePoint detection

    Parameters:
    data: np.ndarray,
    sequence length: this is division length of the segments, any remainder of incomplete
                    segments will be in the tail (last).

    **** DOES NOT UNIQULY HANDLE CORNER CASE WHERE SEGMENT FALLS ON A CHANGEPOINT****
    Dunno what this means yet, if it's a problem at all, will have to be addressed later.

    '''

    #Keyword Args assingment
    _prior = kwargs.get('prior')
    _method = kwargs.get('method')
    _engine = kwargs.get('engine')
    _normalize = kwargs.get('normal')
    _p = kwargs.get('p')
    _k = kwargs.get('k')

    #Argument Defaults
    if _method == None:
        _method = "full_cov"

    if _prior == None:
        _prior = "const"

    if _p == None:
        _p = 0.1

    if _k == None:
        _k=1

    if _engine == None:
        _engine ="numba"
    print('method- ' +_method+ ', prior- ' +_prior + ', engine- '+ _engine)#'Output- '+ _full_output +'Threshhold- '+ _thresh)

    full_prob = []

    #Go straight to CP search segments lengths that are less than the dataset length
    if len(data) <= segment_length:
        print('Segment length is less than dataset length, no spliting necessary')
        full_prob=bayes_offline_sdt(data.T, method=_method, prior=_prior, engine=_engine, p=_p, k=_k)

    #if segment is smaller than dataset, go on to splitting it up
    else:
        split = split_dataset(data, segment_length)

        #establishing full probablility obj

        #loop through segments and add probability dist. to the full_prob obj
        print('Segmenting into '+ str(segment_length))
        for segment in split:
            #print('Segmenting into '+ str(segment_length))
            seg_prob = bayes_offline_sdt(data[segment[1]:segment[2]].T,
                                        method=_method, prior=_prior, engine=_engine, normal=_normalize, p=_p, k=_k)
            full_prob = np.concatenate((full_prob, seg_prob))
            print('completed segment ' + str(segment[0]) + ' from ' + str(segment[1]) + ': ' + str(segment[2])+ ' of ' + str(len(data)), end="\r")
    print(end='/n')
    return full_prob

def normalize_array(arr, low_clip, high_clip):
    '''created through CHATGPT-4
    text input:

    build a python function that normalizes a numpy
    array to values between zero and one as inputs takes in an
    array to normalize, and two clipping percentage parameters
    one for the high end and one for the low end'''

    # Calculate the lower and upper percentile values
    low_value = np.percentile(arr, low_clip)
    high_value = np.percentile(arr, 100 - high_clip)

    # Clip the array values based on the percentiles
    clipped_arr = np.clip(arr, low_value, high_value)

    # Normalize the clipped array to values between zero and one
    normalized_arr = (clipped_arr - low_value) / (high_value - low_value)

    return normalized_arr

''' ==========CHANGEPOINT SEARCH TOOLS ==========='''

def bayes_offline_sdt(data, **kwargs):
    '''Implementation of bayesian offline changepoint methods that is
    described in Fearnhead et al 2006, Chosen for its elegant handling of
    both univariate and multivariate data.

    Utilizing the protocols from sdt-python:
    https://schuetzgroup.github.io/sdt-python/

    Parameters:
    data: np.array - 'm x n' matrix of m datasets and n observations

    method: str - Choices - {"gauss" , "ifm", "full_cov"}
    prior: str - Choices - {"const", "geometric", "neg_binomial"}
        -Geometric prior `P(t) =  p (1 - p)^{t - 1}` requires value for 'p' where (0 < p < 1)  default is 0.1
        -neg_binomial prior ****THIS PRIOR CLASS IS NOT WORKING YET IN SDT-PYTHON, do not use it :( ****
         `P(t) =  {{t - k}\choose{k - 1}} p^k (1 - p)^{t - k}` require value for
        'p' where (0 < p < 1)  and 'k' (int) default is p=0.1, k=1

    engine: str - Choices - {'numba' or 'numpy' default is 'numba'}
    past: int - number of datapoints that probability seach will include in analysis

    full_output: boolean - change point list or array len(data) probabilities of a changepoint
                            returns 4 elements, prob, Q, P, Pcp

    returns probabilities of changepoints

    References:
    Fearnhead, Paul: “Exact and efficient Bayesian inference for multiple changepoint problems”,
    Statistics and computing 16.2 (2006), pp. 203–21

    Adams and McKay: “Bayesian Online Changepoint Detection”, arXiv:0710.3742

    Killick et al.: “Optimal Detection of Changepoints With a Linear Computational Cost”,
    Journal of the American Statistical Association, Informa UK Limited, 2012, 107, 1590–1598
    '''

    #KWARGS getter
    _method = kwargs.get('method')
    _prior = kwargs.get('prior')
    _engine = kwargs.get('engine')
    _full_output = kwargs.get('full_output')
    _thresh = kwargs.get('threshold')
    _past = kwargs.get('past')
    _normalize = kwargs.get('normal')
    _p = kwargs.get('p')
    _k = kwargs.get('k')
    _high_clip = kwargs.get('high_clip')
    _low_clip = kwargs.get('low_clip')

    #Default arguments
    if _method == None:
        _method = "full_cov"
    if _engine == None:
        _engine ="numba"
    if _past == None:
        _past = 20
    if _high_clip == None:
        _high_clip = 0
    if _low_clip == None:
        _low_clip = 0
    if _normalize == True:
        data = normalize_array(data, _low_clip, _high_clip)

    #Prior parameters and defaults
    if _prior == None:
        _prior = "const"
        _prior_params = {}

    if _p == None:
        _p = 0.1

    if _k == None:
        _k=1

    if _prior == 'const':
        _prior_params = {}

    if _prior == "geometric":
        _prior_params = {'p': _p}

    if _prior == "neg_binomial":
        _prior_params = {'k': _k, 'p': _p}

    #if _full_output = True:
    #    _full_output = False
    #print('method- ' +_method+ ', prior- ' +_prior + ', engine- '+ _engine)#'Output- '+ _full_output +'Threshhold- '+ _thresh)

    #Offline Bayes Class init
    detOffBay = sdt_cp.BayesOffline(_prior, _method, engine=_engine, prior_params=_prior_params)

    #Full output
    if _full_output==True:
        #detOffBay = sdt_cp.BayesOffline(_prior, _method, engine=_engine)
        prob, q, p, pcp = detOffBay.find_changepoints(data.T, full_output=True)
        return prob, q, p, pcp

    #Threshold case output
    elif _thresh!=None:
        return detOffBay.find_changepoints(data.T, prob_threshold=_thresh)

    #Everything else output
    else:
        #detOffBay = sdt_cp.BayesOffline(_prior, _method, engine=_engine)
        return detOffBay.find_changepoints(data.T, truncate=-20)

''' Depreciating  this function because sdt-python is much much faster '''
# def bayes_offline_BCP(data, truncate=-20):
#     '''Offline changepoint analysis for signal processing and finding changepoints.
#     implemended with 'bayesian changepoint detection' package (see references below)

#     Requires a continuous 1D dataset as numpy array:

#     Also:

#     Tuning variables should include:

#     truncate term:  Speed up calculations by truncating a sum if
#      the summands provide negligible contributions. This parameter
#      is the exponent of the threshold. Set to -inf to turn off. Defaults to -20

#     references:
#     https://github.com/hildensia/bayesian_changepoint_detection

#     '''
#     #data = GR_rollAvg_[:2100]
#     prior_function = partial(const_prior, p=1/(len(data) + 100))
#     _trunc = truncate

#     Q, P, Pcp = offline_changepoint_detection(data, prior_function ,offline_ll.StudentT(),truncate=_trunc)

#     return Q, P, Pcp

# depreciating because sdt-python is much faster
# def bayes_online_BCP(data, **kwargs):
#     '''
#     Online, changepoint analysis for signal processing and finding changepoints.
#     implemended with 'bayesian changepoint detection' package (see references below)

#     Requires a continuous 1D dataset as numpy array:

#     Also:

#     Tuning variables should include:

#     hazard = value that corresponds to the maximum likely continuous sequence.

#     alpha, beta = to determine student T distribution prior.

#     mu = expected mean of dataset

#     kappa = ??

#     references:
#     https://github.com/hildensia/bayesian_changepoint_detection
#     Adams and Mackay 2007 "Bayesian Online Changepoint Detection"

#     '''

#     _mu = kwargs.get('mu')
#     _hazard = kwargs.get('hazard')
#     _alpha = kwargs.get('alpha')
#     _beta = kwargs.get('beta')
#     _kappa = kwargs.get('kappa')

#     hazard_function = partial(constant_hazard, _hazard)

#     R, maxes = online_changepoint_detection(data, hazard_function, online_ll.StudentT(alpha=_alpha, beta=_beta , kappa=_kappa, mu=_mu))

#     return R, maxes

def pelt_bkps(data, pen=120, min_size=250):

    '''PELT search method for offline changepoint search. Ruptures.

    will find an arbitrary number of changepoints

    takes in a continuous sequence of data and
    through the minimization of a cost function or 'model'
    identifies changepoints:

    Function returns array of dataset relative changepoints my_bkps

    min_size refers to the minimum continuous data length that will be
    allowed between change points; pen is the threshold for the search
    method, in that higher numbers find fewer changepoints.

    model options:
        "l2" (least squares)
        "ar" (auto regressive)
        "cosine" (Cosine similarity)
        refer to ruptures documentation for others

    references:
    Killick et al.: “Optimal Detection of Changepoints With a Linear Computational Cost”,
    Journal of the American Statistical Association, Informa UK Limited, 2012, 107, 1590–1598
    '''

    _pen = pen
    _min_size = min_size

    model = "l2"
    algo = rpt.Pelt(model=model, min_size=_min_size).fit(data)
    my_bkps = algo.predict(pen=_pen)

    return my_bkps

'''=======================VISUALIZATION =============================='''

def CP_GRAPH(data, pen=120, min_size=250):

    '''wrapper for changepoint search and Visualization of changepoints using ruptures PELT method'''

    _min_size = min_size
    _pen = pen
    data_work = data
    #data_work = fill_out_data_ends_complete(data)

    CPoints = pelt_bkps(data_work, pen=pen, min_size=min_size)
    print(datalabel,CPoints)
    rpt.show.display(data_work, CPoints, figsize=(10, 3))

    return CPoints

'''===============Online Bayesian as implemented by G. Gunderson======================='''

class change_point_tools(object):
    if __name__ == '__main__':
        T      = len(data)   # Number of observations.
        hazard = 1/100  # Constant prior on changepoint probability.
        mean0  = 50      # The prior mean on the mean parameter.
        var0   = 10      # The prior variance for mean parameter.
        varx   = 7      # The known variance of the data.

#       data, cps      = generate_data(varx, mean0, var0, T, hazard) # generated data
        #data, cps      = well_data_bkps(data)
        #model          = GaussianUnknownMean(mean0, var0, varx)
        #R, pmean, pvar = bocd(data, model, hazard)

        #plot_posterior(T, data, cps, R, pmean, pvar)

    #plot_posterior(T, data, R, pmean, pvar)

        """============================================================================
    Author: Gregory Gundersen
    Python implementation of Bayesian online changepoint detection for a normal
    model with unknown mean parameter. For algorithm details, see
        Adams & MacKay 2007
        "Bayesian Online Changepoint Detection"
        https://arxiv.org/abs/0710.3742
    For Bayesian inference details about the Gaussian, see:
        Murphy 2007
        "Conjugate Bayesian analysis of the Gaussian distribution"
        https://www.cs.ubc.ca/~murphyk/Papers/bayesGauss.pdf
    This code is associated with the following blog posts:
        http://gregorygundersen.com/blog/2019/08/13/bocd/
        http://gregorygundersen.com/blog/2020/10/20/implementing-bocd/
    ============================================================================"""

    # -----------------------------------------------------------------------------

    def bocd(data, model, hazard):
        """Return run length posterior using Algorithm 1 in Adams & MacKay 2007.
        """
        # 1. Initialize lower triangular matrix representing the posterior as
        #    function of time. Model parameters are initialized in the model class.
        #
        #    When we exponentiate R at the end, exp(-inf) --> 0, which is nice for
        #    visualization.
        #
        T           = len(data)
        log_R       = -np.inf * np.ones((T+1, T+1))
        log_R[0, 0] = 0              # log 0 == 1
        pmean       = np.empty(T)    # Model's predictive mean.
        pvar        = np.empty(T)    # Model's predictive variance.
        log_message = np.array([0])  # log 0 == 1
        log_H       = np.log(hazard)
        log_1mH     = np.log(1 - hazard)

        for t in range(1, T+1):
            # 2. Observe new datum.
            x = data[t-1]

            # Make model predictions.
            pmean[t-1] = np.sum(np.exp(log_R[t-1, :t]) * model.mean_params[:t])
            pvar[t-1]  = np.sum(np.exp(log_R[t-1, :t]) * model.var_params[:t])

            # 3. Evaluate predictive probabilities.
            log_pis = model.log_pred_prob(t, x)

            # 4. Calculate growth probabilities.
            log_growth_probs = log_pis + log_message + log_1mH

            # 5. Calculate changepoint probabilities.
            log_cp_prob = logsumexp(log_pis + log_message + log_H)

            # 6. Calculate evidence
            new_log_joint = np.append(log_cp_prob, log_growth_probs)

            # 7. Determine run length distribution.
            log_R[t, :t+1]  = new_log_joint
            log_R[t, :t+1] -= logsumexp(new_log_joint)

            # 8. Update sufficient statistics.
            model.update_params(t, x)

            # Pass message.
            log_message = new_log_joint

        R = np.exp(log_R)
        return R, pmean, pvar

    # -----------------------------------------------------------------------------

    class GaussianUnknownMean:

        def __init__(self, mean0, var0, varx):
            """Initialize model.

            meanx is unknown; varx is known
            p(meanx) = N(mean0, var0)
            p(x) = N(meanx, varx)
            """
            self.mean0 = mean0
            self.var0  = var0
            self.varx  = varx
            self.mean_params = np.array([mean0])
            self.prec_params = np.array([1/var0])

        def log_pred_prob(self, t, x):
            """Compute predictive probabilities \pi, i.e. the posterior predictive
            for each run length hypothesis.
            """
            # Posterior predictive: see eq. 40 in (Murphy 2007).
            post_means = self.mean_params[:t]
            post_stds  = np.sqrt(self.var_params[:t])
            return norm(post_means, post_stds).logpdf(x)

        def update_params(self, t, x):
            """Upon observing a new datum x at time t, update all run length
            hypotheses.
            """
            # See eq. 19 in (Murphy 2007).
            new_prec_params  = self.prec_params + (1/self.varx)
            self.prec_params = np.append([1/self.var0], new_prec_params)
            # See eq. 24 in (Murphy 2007).
            new_mean_params  = (self.mean_params * self.prec_params[:-1] + \
                                (x / self.varx)) / new_prec_params
            self.mean_params = np.append([self.mean0], new_mean_params)

        @property
        def var_params(self):
            """Helper function for computing the posterior variance.
            """
            return 1./self.prec_params + self.varx

    # -----------------------------------------------------------------------------

    def generate_data(varx, mean0, var0, T, cp_prob):
        """Generate partitioned data of T observations according to constant
        changepoint probability `cp_prob` with hyperpriors `mean0` and `prec0`.
        """
        data  = []
        cps   = []
        meanx = mean0
        for t in range(0, T):
            if np.random.random() < cp_prob:
                meanx = np.random.normal(mean0, var0)
                cps.append(t)
            data.append(np.random.normal(meanx, varx))
        return data, cps

    # -----------------------------------------------------------------------------

    def plot_posterior(T, data, cps, R, pmean, pvar):
        fig, axes = plt.subplots(2, 1, figsize=(20,10))

        ax1, ax2 = axes

        ax1.scatter(range(0, T), data, alpha=0.2)
        ax1.plot(range(0, T), data)
        ax1.set_xlim([0, T])
        ax1.margins(0)

        # Plot predictions.
        ax1.plot(range(0, T), pmean, c='k')
        _2std = 2 * np.sqrt(pvar)
        ax1.plot(range(0, T), pmean - _2std, c='k', ls='--')
        ax1.plot(range(0, T), pmean + _2std, c='k', ls='--')

        ax2.imshow(np.rot90(R), aspect='auto', cmap='gray_r',
                norm=LogNorm(vmin=0.0001, vmax=1))
        ax2.set_xlim([0, T])
        ax2.margins(0)

        for cp in cps:
            ax1.axvline(cp, c='red', ls='dotted', alpha=0.5)
            #ax2.axvline(cp, c='red', ls='dotted', alpha=0.5)

        plt.tight_layout()
        plt.show()


from re import X
import sys

def diffusion(arr):
    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]
    add = [[0] * c for _ in range(r)]
    for i in range(r):
        for j in range(c):
            if arr[i][j] == -1 or arr[i][j] == 0:
                continue
            else:
                tmp = arr[i][j] // 5
                for idx in range(4):
                    nx = dx[idx] + i
                    ny = dy[idx] + j
                    if nx >= 0 and ny >= 0 and nx < r and ny < c and arr[nx][ny] != -1:
                        add[nx][ny] += tmp
                        add[i][j] -= tmp
    for i in range(r):
        for j in range(c):
            arr[i][j] += add[i][j]

def rotate(arr, pos):
    dx = [-1, 0, 1, 0]
    dy = [0, 1, 0, -1]
    idx = 0
    x = pos - 1
    y = 0
    while True:
        nx = x + dx[idx]
        ny = y + dy[idx]
        if nx < 0 or ny < 0 or nx > pos or ny >= c:
            idx += 1
            continue
        elif nx == pos and ny == 0:
            arr[x][y] = 0
            break
        arr[x][y] = arr[nx][ny]
        x = nx
        y = ny
    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]
    idx = 0
    x = pos + 2
    y = 0
    while True:
        nx = x + dx[idx]
        ny = y + dy[idx]
        if nx < pos + 1 or ny < 0 or nx >= r or ny >= c:
            idx += 1
            continue
        elif nx == pos + 1 and ny == 0:
            arr[x][y] = 0
            break
        arr[x][y] = arr[nx][ny]
        x = nx
        y = ny

r, c, t = map(int, sys.stdin.readline().split(" "))
arr = []
for _ in range(r):
    arr.append(list(map(int, sys.stdin.readline().split(" "))))
for i in range(r):
    if arr[i][0] == -1:
        pos = i
        break
for _ in range(t):
    diffusion(arr)
    rotate(arr, pos)
ret = 0
for a in arr:
    for val in a:
        if val != -1:
            ret += val
print(ret)


import numpy as np

from matplotlib.testing.decorators import image_comparison
import matplotlib.pyplot as plt
from matplotlib.patheffects import (Normal, Stroke, withStroke,
                                    withSimplePatchShadow)

@image_comparison(baseline_images=['patheffect1'], remove_text=True)
def test_patheffect1():
    ax1 = plt.subplot(111)
    ax1.imshow([[1, 2], [2, 3]])
    txt = ax1.annotate("test", (1., 1.), (0., 0),
                       arrowprops=dict(arrowstyle="->",
                                       connectionstyle="angle3", lw=2),
                       size=20, ha="center",
                       path_effects=[withStroke(linewidth=3,
                                     foreground="w")])
    txt.arrow_patch.set_path_effects([Stroke(linewidth=5,
                                             foreground="w"),
                                      Normal()])

    ax1.grid(True, linestyle="-")

    pe = [withStroke(linewidth=3, foreground="w")]
    for l in ax1.get_xgridlines() + ax1.get_ygridlines():
        l.set_path_effects(pe)

@image_comparison(baseline_images=['patheffect2'], remove_text=True)
def test_patheffect2():

    ax2 = plt.subplot(111)
    arr = np.arange(25).reshape((5, 5))
    ax2.imshow(arr)
    cntr = ax2.contour(arr, colors="k")

    plt.setp(cntr.collections,
             path_effects=[withStroke(linewidth=3, foreground="w")])

    clbls = ax2.clabel(cntr, fmt="%2.0f", use_clabeltext=True)
    plt.setp(clbls,
             path_effects=[withStroke(linewidth=3, foreground="w")])

@image_comparison(baseline_images=['patheffect3'])
def test_patheffect3():

    ax3 = plt.subplot(111)
    p1, = ax3.plot([0, 1], [0, 1])
    ax3.set_title(r'testing$^{123}$',
        path_effects=[withStroke(linewidth=1, foreground="r")])
    leg = ax3.legend([p1], [r'Line 1$^2$'], fancybox=True, loc=2)
    leg.legendPatch.set_path_effects([withSimplePatchShadow()])

if __name__ == '__main__':
    import nose
    nose.runmodule(argv=['-s', '--with-doctest'], exit=False)


"""
Create mongoDB Atlas client
"""
from typing import Union
from pymongo.mongo_client import MongoClient

class DatabaseConnectionError(Exception):
    """
    Exception to be raised if the connection fails
    :param: message - str
    """

    def __init__(self, message) -> None:
        self.message = message
        super().__init__(self.message)

class MongoDBClient:
    """
    Initialize connection with mongodb database.
    :param:  conn_string: str - database param to connection.
    :return: None.
    :rtype: none.
    """

    def __init__(self, conn_string: str) -> None:
        self.__conn_string: str = conn_string
        self.__client: Union[MongoClient, None] = self.__create_conn()
        if self.__client is None:
            raise DatabaseConnectionError("Failed to connect to the database.")

    @property
    def client(self):
        """Getter method for accessing the MongoClient instance.
        Returns:
            The current value of the client attribute.
        """
        return self.__client

    def __create_conn(self) -> Union[MongoClient, None]:
        """
        Return a MongoClient instance to initialize the database connection.
        :return: MongoClient instance or None.
        :rtype: MongoClient or None
        """
        client: MongoClient = MongoClient(self.__conn_string)
        try:
            client.admin.command('ping')
            print("Pinged your deployment. You successfully connected to MongoDB!")
            return client
        except Exception as error:
            print(error)
            return None


def arm(n):
    temp = 0
    l = len(str(n))
    for i in str(n):
        temp = temp + int(i) ** l
        if temp == n:
            return "armstrong"
    else:
        return "not arm strong"

print(arm(153))


from random import randint
contador = 0
computador = 0
num = -1
computador = randint(0, 10)# Faz o computador pega um numero
print("Sou seu computador...")
print("Acabei de pensar em um número entre 0 e 10.")
print("Será que você consegue adivinhar qual foi?")
while num != computador:
    num = int(input("Qual e o seu palpite?"))
    if num > computador:
        print("Menos... Tente mais uma vez ")
        contador +=1
    elif num < computador :
        print("Mais... Tente mais uma vez ")
        contador +=1
print("Você acertou, Parabens!!! Você tento {} vezes para acerta".format(contador))


### YOUR CODE HERE
# import tensorflow as tf
import torch
import torch.nn as nn
import os, time
import numpy as np
from Network import MyNetwork
from ImageUtils import parse_record
from tqdm import tqdm

"""This script defines the training, validation and testing process.
"""
DEVICE = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
#DEVICE = torch.device('cpu')
torch.manual_seed(3)
if torch.cuda.is_available():
    torch.cuda.manual_seed(3)

class MyModel(nn.Module):

    def __init__(self, config):
        super(MyModel, self).__init__()
        self.config = config
        self.network = MyNetwork(
            self.config['block_size'],
            self.config['classes'],
            self.config['first_num_filters']
        ).to(DEVICE)

        #self.lr = self.config.lr
        self.loss = nn.CrossEntropyLoss()
        self.optimizer = torch.optim.SGD(self.network.parameters(),
                                         lr=0.01,
                                         momentum=0.9,
                                         weight_decay = self.config['weight_decay'])

    # def model_setup(self):
    #     pass
    # I definitely changd the argument catalog here, for ease of my implementation
    def train(self, x_train, y_train, train_config, x_valid=None, y_valid=None):

        for g in self.optimizer.param_groups:
            g['lr'] = train_config['learning_rate']
        print('learning rate is {}'.format(g['lr']))
        num_samples = x_train.shape[0]
        num_batches = num_samples // train_config['batch_size']
        rem = 1 if num_samples % train_config['batch_size'] > 0 else 0
        print('### Training... ###')
        val_accuracies = {}
        for epoch in range(1, train_config['max_epoch']+1):
            self.network.train()
            start_time = time.time()

            shuffle_index = np.random.permutation(num_samples)
            curr_x_train = x_train[shuffle_index]
            curr_y_train = y_train[shuffle_index]
            running_loss = 0
            if epoch % 50 == 0:
                for g in self.optimizer.param_groups:
                    g['lr'] = g['lr']/10

            for i in range(num_batches + rem):

                start_batch = i*train_config['batch_size']
                end_batch = (i+1)*train_config['batch_size']

                x_batch = curr_x_train[start_batch:end_batch]
                y_batch = curr_y_train[start_batch:end_batch]

                x_batch = np.array(list(map(lambda x : parse_record(x, True), x_batch)))

                x_batch = torch.tensor(x_batch).float().to(DEVICE)
                y_batch = torch.tensor(y_batch).long().to(DEVICE)

                self.optimizer.zero_grad()
                outputs = self.network(x_batch)

                loss = self.loss(outputs, y_batch)
                running_loss += loss.item()
                loss.backward()
                self.optimizer.step()

                #print('Batch {:d}/{:d} Loss {:.6f}'.format(i, num_batches, loss))
                print('Batch {:d}/{:d} Loss {:.6f}'.format(i, num_batches, loss), end='\r', flush=True)

            duration = time.time() - start_time
            # if x_valid is not None:
            #     val_error = evaluate(self, x_valid, y_valid)
            print('Epoch {:d} Loss {:.6f} Duration {:.3f} seconds.'.format(epoch, running_loss/num_batches, duration))

            if epoch % train_config['save_interval'] == 0:
                self.save(epoch)
                val_accuracies[epoch] = [running_loss/num_batches]

                if x_valid is not None:
                    val_acc = self.evaluate(x_valid, y_valid)
                    val_accuracies[epoch].append(val_acc)
                    print("validation accuracy after epoch {} is {}".format(epoch, val_acc))

        return val_accuracies

    def evaluate(self, x, y):
        self.network.eval()
        print('### Evaluate on evaluation set ###')
        accuracy_dict = {}

        batch_size = 64
        num_batches = x.shape[0] // batch_size
        rem = 1 if x.shape[0] % batch_size > 0 else 0
        preds = []

        for i in tqdm(range(num_batches+rem)):
            #print(end_batch)
            start_batch = i*batch_size
            end_batch = (i+1)*batch_size

            x_batch = x[start_batch:end_batch]
            y_batch = y[start_batch:end_batch]

            x_batch = np.array(list(map(lambda x_i : parse_record(x_i, False), x_batch)))
            #prediction = self.predict_prob(x_batch)
            x_batch = torch.tensor(x_batch).float().cuda()
            prediction = self.network(x_batch)
            prediction = torch.argmax(prediction, dim=1)
            preds.extend(prediction)

        y = torch.tensor(y)
        preds = torch.tensor(preds)
        acc = torch.sum(preds==y)/y.shape[0]
        print('Test accuracy: {:.4f}'.format( round(acc.item(),4)))

        return round(acc.item(),4)

    def predict_prob(self, x):
        ### right this assumes there is cuda present in the platform be sure to mention about
        ### expecting the data to be of shape 3 x 32 x 32

        x = torch.tensor(x).float().to(DEVICE)
        prediction = self.network(x)
        #prediction = torch.argmax(prediction, dim=1)
        prediction = nn.functional.softmax(prediction, dim=1)
        return prediction

    def save(self, epoch):
        checkpoint_path = os.path.join(self.config['save_dir'], 'model-%d.ckpt'%(epoch))
        os.makedirs(self.config['save_dir'], exist_ok=True)
        torch.save(self.network.state_dict(), checkpoint_path)
        print("Checkpoint has been created.")

    def load(self, checkpoint_name):
        ckpt = torch.load(checkpoint_name, map_location="cpu")
        self.network.load_state_dict(ckpt, strict=True)
        print("Restored model parameters from {}".format(checkpoint_name))

### END CODE HERE


import copy

import autoscaled_group
import common
import default

# Properties in use by this component
HEALTH_PATH = default.HEALTH_PATH
PORT = default.PORT
REPLICAS = default.REPLICAS
SERVICE = default.SERVICE

# Generated in the REPLICAS properties
GENERATED_PROP = default.GENERATED_PROP
GEN_NAME = 'generatedName'

def GenerateBackendService(context):
  """Generates one backendService resource."""
  prop = context.properties
  port = prop[default.PORT]
  health_path = prop[default.HEALTH_PATH]
  default_srv = prop[default.SERVICE]
  outputs = prop.setdefault(GENERATED_PROP, dict())
  be_name = common.AutoName(context.env['name'], default.BACKEND_SERVICE)
  hc_name = common.AutoName(context.env['name'], default.HEALTHCHECK)

  # pyformat: disable
  resource = [
      {
          'name': hc_name,
          'type': default.HEALTHCHECK,
          'properties': {
              'port': port,
              'requestPath': health_path,
          }
      }, {
          'name': be_name,
          'type': default.BACKEND_SERVICE,
          'properties': {
              'port': port,
              'portName': default_srv,
              'backends': GenerateBackends(context),
              'healthChecks': [common.Ref(hc_name)],
              'generatedProperties': outputs
          }
      }
  ]
  # pyformat: enable
  return resource

def GenerateBackends(context):
  """Generates dictionary of IGMs connected to a backeend service."""
  name = context.env['name']
  prop = context.properties
  replicas = prop[REPLICAS]
  backends = []
  for zone_dict in replicas:
    short_abbrv = common.ShortenZoneName(zone_dict[default.ZONE])
    ig_name = common.AutoName(name, default.IGM, short_abbrv)
    zone_dict[GEN_NAME] = ig_name
    backend = {'name': ig_name, 'group': common.RefGroup(ig_name)}
    backends.append(backend)
  prop[GENERATED_PROP][REPLICAS] = copy.deepcopy(replicas)
  return backends

def GenerateResourceList(context):
  """Returns list of resources generated by this module."""
  resources = autoscaled_group.GenerateNAutoscaledGroup(context)
  resources += GenerateBackendService(context)
  return resources

@common.FormatErrorsDec
def GenerateConfig(context):
  """Generates YAML resource configuration."""
  return common.MakeResource(GenerateResourceList(context))


#from aocutil import read_lines
from functools import reduce
from itertools import combinations
import re
import numpy as np
import math

def read_lines(path, fun=lambda x: x):
    with open(path,'r') as inp:
        lines = inp.readlines()
        return [fun(l.strip()) for l in lines]

class Planet:
    def __init__(self, position, velocity):
        self.position = position
        self.velocity = velocity

    def __repr__(self):
        return "pos=<x={}, y={}, z={}> vel=<x={}, y={}, z={}>".format(*self.position, *self.velocity)

    def energy(self):
        return np.sum(np.abs(self.position)) * np.sum(np.abs(self.velocity))

planets = [Planet(np.fromiter(re.findall(r'-?\d+', line), int), np.zeros(3, int)) for line in read_lines("input12.txt")]

get_hash = lambda i: tuple(reduce(lambda a, b: a + [b.position[i], b.velocity[i]], planets, []))
seen = [{}, {}, {}]
result = [0, 0, 0]
steps = 0
while not all(result):
    for j in range(3):
        hsh = get_hash(j)
        if hsh in seen[j] and not result[j]:
            result[j] = steps
        else:
            seen[j][hsh] = steps

    for p1, p2 in combinations(planets, 2):
        gravity = np.sign(p2.position - p1.position)
        p1.velocity += gravity
        p2.velocity -= gravity

    for p in planets:
        p.position += p.velocity

    steps += 1
lcm = lambda *args: reduce(lambda a, b: a * b // math.gcd(a, b), *args)
print(lcm(result))

#print(reduce(lambda a, b: a + b.energy(), planets, 0))


from random import randint

playAgain = 'yes'

while playAgain == 'yes':

    comp = str(randint(0,9)) + str(randint(0,9)) + str(randint(0,9)) + str(randint(0,9))

    print('Welcome to Bulls and Cows!')

    user = input('Enter your 4-digit guess: (i.e. 1234) ')

    bulls = 0

    while bulls < 4:

        bulls = 0
        cows = 0

        while len(user) != 4:
            user = input('You must enter a 4-digit number: ')

        if id(comp[0]) == id(user[0]):
            bulls = bulls + 1
        elif id(comp[0]) == id(user[1]):
            cows = cows + 1
        elif id(comp[0]) == id(user[2]):
            cows = cows + 1
        elif id(comp[0]) == id(user[3]):
            cows = cows + 1
        else:
            cows = cows + 0

        if id(comp[1]) == id(user[1]):
            bulls = bulls + 1
        elif id(comp[1]) == id(user[0]):
            cows = cows + 1
        elif id(comp[1]) == id(user[2]):
            cows = cows + 1
        elif id(comp[1]) == id(user[3]):
            cows = cows + 1
        else:
            cows = cows + 0

        if id(comp[2]) == id(user[2]):
            bulls = bulls + 1
        elif id(comp[2]) == id(user[1]):
            cows = cows + 1
        elif id(comp[2]) == id(user[0]):
            cows = cows + 1
        elif id(comp[2]) == id(user[3]):
            cows = cows + 1
        else:
            cows = cows + 0

        if id(comp[3]) == id(user[3]):
            bulls = bulls + 1
        elif id(comp[3]) == id(user[1]):
            cows = cows + 1
        elif id(comp[3]) == id(user[2]):
            cows = cows + 1
        elif id(comp[3]) == id(user[0]):
            cows = cows + 1
        else:
            cows = cows + 0

        print('Bulls: ' + str(bulls) + ' Cows: ' + str(cows))

        if bulls != 4:
            user = input('Enter another guess: ')

    print('You win!')
    playAgain = input('Play again? (yes/no) ')
    while playAgain != 'yes' and playAgain !='no':
        playAgain = input('Please enter yes or no: ')

print('Goodbye :)')


def add(x,y):
    result = x + y
    print("Add called...",result)

def sub(x,y):
    result = x - y
    print("Sub called...",result)

def mul(x,y):
    result = x * y
    print("Mul called...",result)

def div(x,y):
    result = x / y
    print("Div called...",result)

while True:

    print("""
    1. Add
    2. Sub
    3. Mul
    4. Div
    """)

    user_choice = input("Enter your choice : ")
    num_1 = float(input("Enter first number : "))
    num_2 = float(input("Enter second number : "))
    operations = {
        "1" : add,
        "2" : sub,
        "3" : mul,
        "4" : div
    }
    opr = operations.get(user_choice)
    # print(opr)
    opr(num_1, num_2)