str_no_string = 0
str_empty_string = 1
str_yes = 2
str_no = 3
str_credits_0 = 4
str_credits_1 = 5
str_credits_2 = 6
str_credits_3 = 7
str_credits_4 = 8
str_credits_5 = 9
str_credits_6 = 10
str_credits_7 = 11
str_credits_8 = 12
str_credits_9 = 13
str_credits_10 = 14
str_credits_11 = 15
str_credits_12 = 16
str_profile_banner_selection_text = 17
str_use_default_banner = 18
str_game_type_1 = 19
str_game_type_2 = 20
str_game_type_3 = 21
str_game_type_4 = 22
str_game_type_5 = 23
str_game_types_end = 24
str_fac_1_default_name = 25
str_fac_2_default_name = 26
str_fac_3_default_name = 27
str_fac_4_default_name = 28
str_fac_5_default_name = 29
str_fac_6_default_name = 30
str_fac_7_default_name = 31
str_fac_8_default_name = 32
str_leave_edit_mode = 33
str_distance_reg1_sq_distance_reg2 = 34
str_choose_faction_banner = 35
str_keep_current_banner = 36
str_next = 37
str_previous = 38
str_spectate = 39
str_join_game = 40
str_choose_an_option = 41
str_choose_an_option_targeting_s1 = 42
str_change_options = 43
str_change_controls = 44
str_show_rules = 45
str_show_info = 46
str_admin_panel = 47
str_admin_tools = 48
str_admin_items = 49
str_kick_player = 50
str_ban_player_temp = 51
str_ban_player_perm = 52
str_mute_player = 53
str_mute_players = 54
str_kill_player = 55
str_fade_player_out = 56
str_freeze_player = 57
str_teleport_to_player = 58
str_teleport_behind_player = 59
str_teleport_player = 60
str_teleport_forwards = 61
str_equip_admin_armor = 62
str_become_invisible = 63
str_refill_health = 64
str_become_godlike = 65
str_spawn_admin_horse = 66
str_remove_admin_horses = 67
str_remove_stray_horses = 68
str_teleport_to_ships = 69
str_reset_sunken_ships = 70
str_join_faction = 71
str_lock_current_faction = 72
str_unlock_current_faction = 73
str_log_current_position = 74
str_log_distance_to_position = 75
str_your_current_position_is = 76
str_your_distance_to_position_is = 77
str_quit = 78
str_choose_a_player_to_s0 = 79
str_kick = 80
str_ban_temp = 81
str_ban_perm = 82
str_mute = 83
str_kill = 84
str_fade_out = 85
str_freeze = 86
str_teleport_to = 87
str_teleport_behind = 88
str_teleport = 89
str_propose_as_lord = 90
str_send_message_to = 91
str_give_take_door_key = 92
str_give_take_money_chest_key = 93
str_give_take_item_chest_key = 94
str_give_take_marshal = 95
str_allow_disallow_announcing = 96
str_outlaw = 97
str_request_poll = 98
str_choose_a_poll_type = 99
str_s0__reg0_ = 100
str_choose_poll_scene = 101
str_choose_poll_kick = 102
str_choose_poll_ban = 103
str_choose_poll_faction_lord = 104
str_choose_a_scene = 105
str_faction_admin = 106
str_change_faction_banner = 107
str_change_faction_name = 108
str_kick_player_from_faction = 109
str_outlaw_player = 110
str_manage_door_keys = 111
str_manage_money_chest_keys = 112
str_manage_item_chest_keys = 113
str_manage_announcers = 114
str_manage_marshals = 115
str_choose_a_faction = 116
str_declare_faction_hostile = 117
str_offer_faction_peace = 118
str_you_have_door_keys = 119
str_you_have_money_keys = 120
str_you_have_item_keys = 121
str_you_have_announcers = 122
str_you_are_a_marshal = 123
str_log_admin_target_player = 124
str_log_admin_target_self = 125
str_log_admin_target_faction = 126
str_log_admin_kick = 127
str_log_admin_ban_temp = 128
str_log_admin_ban_perm = 129
str_log_admin_mute = 130
str_log_admin_mute_all = 131
str_log_admin_kill = 132
str_log_admin_fade_out = 133
str_log_admin_freeze = 134
str_log_admin_teleport_to = 135
str_log_admin_teleport_behind = 136
str_log_admin_teleport = 137
str_log_admin_teleport_forwards = 138
str_log_admin_refill_health = 139
str_log_admin_become_godlike = 140
str_log_admin_get_armor = 141
str_log_admin_get_invisible = 142
str_log_admin_get_horse = 143
str_log_admin_remove_horses = 144
str_log_admin_remove_stray_horses = 145
str_log_admin_teleport_to_ships = 146
str_log_admin_reset_ships = 147
str_log_admin_join_faction = 148
str_log_admin_lock_faction = 149
str_log_admin_own_position = 150
str_log_admin_own_distance = 151
str_log_admin_cheat_money = 152
str_log_admin_cheat_item = 153
str_log_admin_restocked_s4 = 154
str_poll_change_scene = 155
str_poll_kick_player = 156
str_poll_ban_player = 157
str_poll_faction_lord = 158
str_poll_log = 159
str_poll_existing = 160
str_poll_invalid = 161
str_poll_result_no = 162
str_poll_result_yes = 163
str_poll_result_admin_no = 164
str_poll_result_admin_yes = 165
str_poll_requester_keys = 166
str_poll_time_left = 167
str_departed_player = 168
str_set_s0 = 169
str_s0_reg1 = 170
str_invalid_respawn_period = 171
str_invalid_max_players = 172
str_invalid_scene = 173
str_command_not_implemented = 174
str_bot_count = 175
str_round_max_seconds = 176
str_respawn_period = 177
str_num_bots_voteable = 178
str_scenes_voteable = 179
str_factions_voteable = 180
str_player_respawn_as_bot = 181
str_kick_voteable = 182
str_ban_voteable = 183
str_valid_vote_ratio = 184
str_auto_team_balance_limit = 185
str_starting_gold = 186
str_combat_gold_bonus = 187
str_round_gold_bonus = 188
str_player_banners_allowed = 189
str_force_default_armor = 190
str_team_points_gained_for_flags = 191
str_points_gained_for_capturing_flags = 192
str_game_time_limit = 193
str_team_point_limit = 194
str_defender_spawn_count = 195
str_disallow_ranged_weapons = 196
str_use_class_limits = 197
str_class_limit_player_count = 198
str_squad_size = 199
str_scale_squad = 200
str_build_points_team1 = 201
str_build_points_team2 = 202
str_allow_multiple_firearms = 203
str_enable_bonuses = 204
str_bonus_strength = 205
str_bonus_range = 206
str_fall_off_horse = 207
str_horse_dying = 208
str_auto_kick = 209
str_max_teamkills_before_kick = 210
str_auto_horse = 211
str_auto_swap = 212
str_limit_grenadier = 213
str_limit_skirmisher = 214
str_limit_rifle = 215
str_limit_cavalry = 216
str_limit_lancer = 217
str_limit_hussar = 218
str_limit_dragoon = 219
str_limit_cuirassier = 220
str_limit_heavycav = 221
str_limit_artillery = 222
str_limit_rocket = 223
str_limit_sapper = 224
str_limit_musician = 225
str_limit_sergeant = 226
str_limit_officer = 227
str_limit_general = 228
str_max_players = 229
str_friendly_fire = 230
str_melee_friendly_fire = 231
str_friendly_fire_damage_self_ratio = 232
str_friendly_fire_damage_friend_ratio = 233
str_ghost_mode = 234
str_control_block_direction = 235
str_combat_speed = 236
str_add_to_game_servers_list = 237
str_anti_cheat = 238
str_combat_speed_0 = 239
str_combat_speed_1 = 240
str_combat_speed_2 = 241
str_combat_speed_3 = 242
str_combat_speed_4 = 243
str_automatic = 244
str_by_mouse_movement = 245
str_free = 246
str_stick_to_any_player = 247
str_stick_to_team_members = 248
str_stick_to_team_members_view = 249
str_game_rules = 250
str_s0_reg0 = 251
str_s0_s1 = 252
str_s2_s3 = 253
str_s0__s1 = 254
str_basic_name_labels = 255
str_scene_name = 256
str_server_name = 257
str_game_password = 258
str_welcome_message = 259
str_game_type = 260
str_scene = 261
str_start_scene = 262
str_edit_scene = 263
str_zero = 264
str_remaining_time_reg0_s0reg1_s1reg2 = 265
str_respawning_in_reg0_seconds = 266
str_press_select_spawn_point = 267
str_press_select_spawn_area = 268
str_press_select_confirm_spawn_area = 269
str_restart_as_peasant_commoner = 270
str_number_of_factions_reg0 = 271
str_victory_condition_none = 272
str_victory_condition_castles = 273
str_respawn_with_partial_health = 274
str_respawn_with_full_health = 275
str_herd_animal_limit_reg0 = 276
str_always_fine = 277
str_always_raining = 278
str_dynamic = 279
str_player_name = 280
str_class = 281
str_kills = 282
str_deaths = 283
str_ping = 284
str_score = 285
str_score_reg0 = 286
str_all_players = 287
str_reg0_players = 288
str_reg0_player = 289
str_reg0_players_of_reg1 = 290
str_reg0_player_of_reg1 = 291
str_reg0 = 292
str_s0 = 293
str_s1 = 294
str_enable_s0 = 295
str_disable_s0 = 296
str_un = 297
str_drop_items = 298
str_display_faction_in_name_labels = 299
str_display_chat_overlay = 300
str_display_faction_chat_on_overlay = 301
str_activate_clickable_animation_menu = 302
str_mute_global_chat = 303
str_mute_music = 304
str_walk_on = 305
str_open_close_helmet = 306
str_toggle_head = 307
str_toggle_hand = 308
str_attach_cart_pack = 309
str_detach_cart_pack = 310
str_reveal_money_pouch_to_target = 311
str_reveal_money_pouch_to_area = 312
str_commit_suicide = 313
str_action_menu_end = 314
str_s0_are_you_sure = 315
str_unmute_music = 316
str_hide_name_labels = 317
str_display_name_labels = 318
str_display_basic_name_labels = 319
str_hide_chat_overlay = 320
str_display_local_chat_on_overlay = 321
str_deactivate_clickable_animation_menu = 322
str_unmute_global_chat = 323
str_walk_off = 324
str_profile_display_name_labels = 325
str_profile_hide_faction_in_name_labels = 326
str_profile_display_basic_name_labels = 327
str_profile_display_chat_overlay = 328
str_profile_overlay_shows_faction_chat = 329
str_profile_mute_global_chat = 330
str_profile_mute_music = 331
str_profile_non_clickable_animation_menu = 332
str_profile_disable_automatic_shadow_recalculation = 333
str_profile_disable_rain_snow_particles = 334
str_open_close_helmet_error = 335
str_suicide_in_reg1 = 336
str_log_s1_committed_suicide = 337
str_overlay_shows_faction_chat = 338
str_disable_automatic_shadow_recalculation = 339
str_disable_rain_snow_particles = 340
str_reg0__s0 = 341
str_menu_guestures = 342
str_menu_guestures_2 = 343
str_menu_stationary = 344
str_menu_neutral = 345
str_menu_hostile = 346
str_menu_robbery = 347
str_menu_commands = 348
str_menu_music_1 = 349
str_menu_music_2 = 350
str_anim_cheer = 351
str_anim_clap = 352
str_anim_raise_sword = 353
str_anim_hands_on_hips = 354
str_anim_hand_on_chest = 355
str_anim_arms_crossed = 356
str_anim_stand_still = 357
str_anim_surrender = 358
str_anim_nod_head = 359
str_anim_peeing = 360
str_anim_wave_hand = 361
str_anim_this_way = 362
str_anim_go_away = 363
str_anim_sit = 364
str_anim_sleeping = 365
str_anim_kneel = 366
str_anim_pray = 367
str_anim_beg = 368
str_anim_track = 369
str_anim_bow = 370
str_anim_lean_on_sword = 371
str_anim_pike_stance = 372
str_anim_away_vile_beggar = 373
str_anim_my_lord = 374
str_anim_almost_harvesting_season = 375
str_anim_whats_this_then = 376
str_anim_out_for_a_stroll_are_we = 377
str_anim_we_ride_to_war = 378
str_anim_less_talking_more_raiding = 379
str_anim_you_there_stop = 380
str_anim_war_cry = 381
str_anim_tear_you_limb_from_limb = 382
str_anim_better_not_be_a_manhunter = 383
str_anim_drink_from_your_skull = 384
str_anim_gods_will_decide_your_fate = 385
str_anim_nice_head_on_shoulders = 386
str_anim_hunt_you_down = 387
str_anim_dead_men_tell_no_tales = 388
str_anim_stand_and_deliver = 389
str_anim_your_money_or_your_life = 390
str_anim_have_our_pay_or_fun = 391
str_anim_word_about_purse_belongings = 392
str_anim_easy_way_or_hard_way = 393
str_anim_everything_has_a_price = 394
str_anim_slit_your_throat = 395
str_anim_horn_charge = 396
str_anim_horn_regroup = 397
str_anim_horn_retreat = 398
str_anim_lute_1 = 399
str_anim_lute_2 = 400
str_anim_lute_3 = 401
str_anim_lute_4 = 402
str_anim_lyre_1 = 403
str_anim_lyre_2 = 404
str_anim_lyre_3 = 405
str_anim_lyre_4 = 406
str_anim_flute_1 = 407
str_anim_flute_2 = 408
str_anim_flute_3 = 409
str_anim_flute_4 = 410
str_anim_vielle_1 = 411
str_anim_vielle_2 = 412
str_anim_vielle_3 = 413
str_anim_vielle_4 = 414
str_log_animation = 415
str_anim_giving_birth = 416
str_done = 417
str_use = 418
str_buy = 419
str_buy_sell = 420
str_buy_sell_craft = 421
str_take = 422
str_take_put_craft = 423
str_dont_have_enough_money = 424
str_cant_equip_item = 425
str_collect_reg1_gold = 426
str_rest = 427
str_rest_horse = 428
str_winch_lower = 429
str_winch_raise = 430
str_winch_drop = 431
str_destructible = 432
str_cut_down = 433
str_mine = 434
str_harvest = 435
str_prune = 436
str_burn = 437
str_take_a_seat = 438
str_destroy_s1 = 439
str_destroy_all_items_cart = 440
str_process_wood = 441
str_process_metal = 442
str_process_hammer_metal = 443
str_process_grind = 444
str_process_cook = 445
str_process_press = 446
str_process_brew = 447
str_process_tavern = 448
str_process_preserve = 449
str_process_spin = 450
str_process_weave = 451
str_process_cut = 452
str_process_leather = 453
str_stockpile = 454
str_stockpile_nearly_full = 455
str_stockpile_full = 456
str_export = 457
str_export_for_s1 = 458
str_import = 459
str_build = 460
str_access = 461
str_attach = 462
str_not_close_enough = 463
str_s0__s1_ = 464
str_drop_money_bag = 465
str_drop_all_money_bag = 466
str_deposit_money_chest = 467
str_withdraw_money_chest = 468
str_admin_cheat_money = 469
str_bank_withdraw = 470
str_bank_withdraw_5k = 471
str_bank_deposit = 472
str_bank_deposit_all = 473
str_no_bank_nearby = 474
str_too_close_to_bank_for_money_pouch = 475
str_no_money_chest_nearby = 476
str_cant_open_money_chest = 477
str_not_enough_money_in_chest = 478
str_chest_appears_lockpicked = 479
str_gold_reg2 = 480
str_buy_banner_faction = 481
str_stock_count_reg0 = 482
str_crafting_refund_reg0_reward_reg1 = 483
str_crafting_reward_reg1 = 484
str_selling_price_reg0 = 485
str_womens_clothes = 486
str_item_id = 487
str_spawn_s1 = 488
str_troop_not_available = 489
str_troop_train = 490
str_troop_assume_role = 491
str_troop_become = 492
str_troop_become_for = 493
str_troop_cost = 494
str_troop_strength_agility = 495
str_troop_weapon_proficiencies = 496
str_requires_strength_reg1 = 497
str_requires_power_draw_reg1 = 498
str_requires_power_throw_reg1 = 499
str_requires_shield_reg1 = 500
str_requires_riding_reg1 = 501
str_damage_reg1_speed_reg2 = 502
str_accuracy_reg1_reload_reg2 = 503
str_joined_the_s1 = 504
str_s0_joined_the_s1 = 505
str_must_leave_s1_first = 506
str_not_a_member_of_s1 = 507
str_inactive_faction_change = 508
str_s0_has_dismounted_a_s1 = 509
str_s0_has_mounted_a_s1 = 510
str_s1_captured_s2 = 511
str_your_faction_not_hostile_to_s1 = 512
str_your_faction_not_captured_required_points = 513
str_door_locked_by_s1 = 514
str_door_bolted = 515
str_chest_locked_by_s1 = 516
str_s0_killed_faction_member = 517
str_s0_killed_friendly_faction_member = 518
str_s0_has_been_outlawed = 519
str_you_have_been_outlawed = 520
str_your_outlaw_rating_now_reg1 = 521
str_scene_error_this_faction_is_not_active = 522
str_you_are_not_lord_of_s1 = 523
str_you_are_now_lord_of_s1 = 524
str_s10_now_lord_of_s1 = 525
str_s10_now_known_as_s1 = 526
str_banner_used_by_s1 = 527
str_s1_doesnt_need_merc = 528
str_s1_reign_supreme = 529
str_s1_now_hostile_towards_s10 = 530
str_s1_and_s10_made_peace = 531
str_lord_of_s1_withdraws_offer_of_peace = 532
str_lord_of_s1_offers_peace = 533
str_not_riding_necessary_horse = 534
str_already_attached_cart = 535
str_resource_required = 536
str_not_at_mast_or_rudder = 537
str_craft_not_skilled = 538
str_craft_wrong_resources = 539
str_no_horse = 540
str_too_wounded_to_rest = 541
str_too_hungry_to_rest = 542
str_horse_too_wounded_to_sell = 543
str_dismount_to_sell = 544
str_item_too_long_for_container = 545
str_cant_put_money_bag_in_container = 546
str_cant_put_ammo_in_container = 547
str_cant_put_non_ammo_in_container = 548
str_too_far_away_loot = 549
str_herd_animal_limit_reached = 550
str_s1_reveals_money_pouch_containing_about_reg1 = 551
str_you_reveal_money_pouch_to_s1 = 552
str_you_reveal_money_pouch_to_near_by_players = 553
str_s1_revealed_money_pouch_containing_reg1_to_s2 = 554
str_s1_revealed_money_pouch_containing_reg1_to_near_by_players_s0 = 555
str_s1_revealed_money_pouch_containing_reg1_to_near_by_players_none = 556
str_your_target_too_far_away = 557
str_no_target_selected = 558
str_chat_format = 559
str_send_message_to_players_nearby = 560
str_send_message_to_the_s11 = 561
str_change_name_of_your_faction = 562
str_send_admin_message = 563
str_send_admin_message_to_s1 = 564
str_admin_chat_format = 565
str_admin_chat_player_format = 566
str_admin_chat_to_player_format = 567
str_admin_announcement_format = 568
str_local_chat_log_format = 569
str_faction_chat_log_format = 570
str_s1_has_left_the_game_with_id_reg0 = 571
str_error_unable_to_find_link_scene_prop = 572
str_error_unlinked_scene_prop = 573
str_error_edit_mode_not_enabled = 574
str_no_more_unlinked_scene_props = 575
str_error_scene_prop_0_pw = 576
str_error_load_out_id_reg0_not_defined = 577
str_game_type_1_info = 578
str_game_type_2_info = 579
str_game_type_3_info = 580
str_game_type_4_info = 581
str_game_type_5_info = 582
str_pw_welcome = 583
str_pw_editor_welcome = 584
str_pw_editor_info = 585
str_pw_editor_values_info = 586
str_pw_editor_castle_names = 587
str_castle_names_numbers_format = 588
str_book_of_clothing = 589
str_book_of_weapons = 590
str_book_of_armor = 591
str_book_of_healing = 592
str_name_server_error_code_reg0 = 593
str_name_server_input_error_parameter_s0 = 594
str_name_server_invalid_response = 595
str_name_server_log_s10 = 596
str_kicked_using_other_players_name = 597
str_kicked_using_other_clan_tag = 598
str_kicked_using_invalid_name = 599
str_kicked_not_registered = 600
str_http_s1_password_s2_id_reg1_uid_reg2_name_s3 = 601
str_http_s0_admin = 602
str_name_server = 603
str_name_server_password = 604
str_scene_name_1 = 605
str_scene_name_2 = 606
str_scene_name_3 = 607
str_scene_name_4 = 608
str_scene_name_5 = 609
str_scene_name_6 = 610
str_scene_name_7 = 611
str_scene_name_8 = 612
str_scene_name_9 = 613
str_scene_name_10 = 614
str_scene_name_11 = 615
str_scene_name_12 = 616
str_scene_name_13 = 617
str_scene_name_14 = 618
str_scene_name_15 = 619
str_scene_name_16 = 620
str_scene_name_17 = 621
str_scene_name_18 = 622
str_scene_name_19 = 623
str_scene_name_20 = 624
str_scene_name_21 = 625
str_scene_name_22 = 626
str_scene_name_23 = 627
str_scene_name_24 = 628
str_scene_name_25 = 629
str_scene_name_26 = 630
str_scene_name_27 = 631
str_scene_name_28 = 632
str_scene_name_29 = 633
str_scene_name_30 = 634
str_scene_names_end = 635
str_castle_name_0 = 636
str_castle_name_1 = 637
str_castle_name_2 = 638
str_castle_name_3 = 639
str_castle_name_4 = 640
str_castle_name_5 = 641
str_castle_name_6 = 642
str_castle_name_7 = 643
str_castle_name_8 = 644
str_castle_name_9 = 645
str_castle_name_10 = 646
str_castle_name_11 = 647
str_castle_name_12 = 648
str_castle_name_13 = 649
str_castle_name_14 = 650
str_castle_name_15 = 651
str_castle_name_16 = 652
str_castle_name_17 = 653
str_castle_name_18 = 654
str_castle_name_19 = 655
str_castle_name_20 = 656
str_castle_name_21 = 657
str_castle_name_22 = 658
str_castle_name_23 = 659
str_castle_name_24 = 660
str_castle_name_25 = 661
str_castle_name_26 = 662
str_castle_name_27 = 663
str_castle_name_28 = 664
str_castle_name_29 = 665
str_castle_name_30 = 666
str_castle_name_31 = 667
str_castle_name_32 = 668
str_castle_name_33 = 669
str_castle_name_34 = 670
str_castle_name_35 = 671
str_castle_name_36 = 672
str_castle_name_37 = 673
str_castle_name_38 = 674
str_castle_name_39 = 675
str_castle_name_40 = 676
str_castle_name_41 = 677
str_castle_name_42 = 678
str_castle_name_43 = 679
str_castle_name_44 = 680
str_castle_name_45 = 681
str_castle_name_46 = 682
str_castle_name_47 = 683
str_castle_name_48 = 684
str_castle_name_49 = 685
str_castle_name_50 = 686
str_castle_name_51 = 687
str_castle_name_52 = 688
str_castle_name_53 = 689
str_castle_name_54 = 690
str_castle_name_55 = 691
str_castle_name_56 = 692
str_castle_name_57 = 693
str_castle_name_58 = 694
str_castle_name_59 = 695
str_castle_name_60 = 696
str_castle_name_61 = 697
str_castle_name_62 = 698
str_castle_name_63 = 699
str_castle_name_64 = 700
str_castle_name_65 = 701
str_castle_name_66 = 702
str_castle_name_69 = 703
str_castle_name_70 = 704
str_castle_name_71 = 705
str_castle_name_72 = 706
str_castle_name_73 = 707
str_castle_name_74 = 708
str_castle_name_75 = 709
str_castle_name_76 = 710
str_castle_name_77 = 711
str_castle_name_78 = 712
str_castle_name_79 = 713
str_castle_name_80 = 714
str_castle_name_81 = 715
str_castle_name_82 = 716
str_castle_name_83 = 717
str_castle_name_84 = 718
str_castle_name_85 = 719
str_castle_name_86 = 720
str_castle_name_87 = 721
str_castle_name_88 = 722
str_castle_name_89 = 723
str_castle_name_90 = 724
str_castle_name_91 = 725
str_castle_name_92 = 726
str_castle_name_93 = 727
str_castle_name_94 = 728
str_castle_name_95 = 729
str_castle_name_96 = 730
str_castle_name_97 = 731
str_castle_name_98 = 732
str_castle_name_99 = 733
str_castle_name_100 = 734
str_castle_name_101 = 735
str_castle_name_102 = 736
str_castle_name_103 = 737
str_castle_name_104 = 738
str_castle_name_105 = 739
str_castle_name_106 = 740
str_castle_name_107 = 741
str_castle_name_108 = 742
str_castle_name_109 = 743
str_castle_name_110 = 744
str_castle_name_111 = 745
str_castle_name_112 = 746
str_castle_name_113 = 747
str_castle_name_114 = 748
str_castle_name_115 = 749
str_castle_name_116 = 750
str_castle_name_117 = 751
str_castle_name_118 = 752
str_castle_name_119 = 753
str_castle_name_120 = 754
str_castle_name_121 = 755
str_castle_name_122 = 756
str_castle_name_123 = 757
str_castle_name_124 = 758
str_castle_name_125 = 759
str_castle_name_126 = 760
str_castle_name_127 = 761
str_castle_names_end = 762
str_attach_to_himself_log = 763
str_attach_to_horse_log = 764
str_detach_from_himself_log = 765
str_detach_from_horse_log = 766
str_log_use_money_bag = 767
str_log_spawn_money_bag = 768
str_log_money_chest_withdraw = 769
str_log_money_chest_deposit = 770
str_log_hit_door = 771
str_log_repair_door = 772
str_log_hit_chest = 773
str_log_repair_chest = 774
str_log_hit_ship = 775
str_log_drop_item = 776
str_log_pick_up_item = 777
str_log_put_item_in_inventory = 778
str_log_put_item_in_finventory = 779
str_log_take_item_from_inventory = 780
str_log_take_item_from_finventory = 781
str_log_hit_player = 782
str_log_hit_phorse = 783
str_log_hit_animal = 784
str_log_bump = 785
str_log_heal_player = 786
str_log_heal_phorse = 787
str_log_heal_animal = 788
str_log_loot_corpse = 789
str_log_s11_dropped_loot = 790
str_log_use_cart = 791
str_log_capture = 792
str_log_capture_secondary = 793
str_shield_hit_log = 794
str_log_equipment = 795
str_s1_kicked_s2_from_s3 = 796
str_s1_outlawed_s2_from_s3 = 797
str_s2_kicked_you_from_the_faction = 798
str_s2_outlawed_you_from_the_faction = 799


# Copyright 2014
# The Cloudscaling Group, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
logging.getLogger('boto').setLevel(logging.INFO)
logging.getLogger('paramiko').setLevel(logging.WARNING)
LOG = logging.getLogger(__name__)

def detect_new_volume(proc_partitions, proc_partitions_new):
    devices = get_devices(proc_partitions)
    devices_new = get_devices(proc_partitions_new)
    devices_new -= devices
    return devices_new.pop()

def get_devices(proc_partitions):
    devices = set()
    for line in proc_partitions:
        items = [item for item in line.split(' ') if len(item) > 0]
        if len(items) > 0:
            devices.add(items[3])

    return devices


import json
from django.http import HttpResponse
from django.views.generic import View

from django.shortcuts import render, get_object_or_404, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.utils.decorators import method_decorator

from ..settings import SCRUFFY_BLOG_SETTINGS
from ..models import Post, PostElement
from ..forms import PostForm, PostElementForm, PostImageForm

class PostDetail(View):
    """ Edit a blog post. """

    base_template = 'admin/base_site.html'
    editor_template = 'scruffy_blog/writing/post_detail.html'
    cancel_url = "admin:scruffy_blog_post_changelist" # By name

    # You may swap these out for proxy models, but do so carefully.
    post_model = Post
    element_model = PostElement

    def __init__(self, *args, **kwargs):
        super(PostDetail, self).__init__(*args, **kwargs)
        self.base_template = kwargs.get('base_template') or self.base_template

    @property
    def blog(self):
        """
        Return a blog if you want to lock the post to it.
        Return `None` and the user will select the blog.
        By default, this does nothing, but you can override it.
        """
        return None

    @property
    def scruffy_cropper_url(self):
        return None

    @method_decorator(login_required)
    @method_decorator(permission_required('blog.change_post'))
    def dispatch(self, *args, **kwargs):
        return super(PostDetail, self).dispatch(*args, **kwargs)

    def get_forms(self):
        self.form = PostForm(self.request.POST or None,
            files=self.request.FILES or None,
            instance=self.post,
            prefix="post-core",
            redirect_url=self.request.path,
            cropper_url=self.scruffy_cropper_url,
            blog=self.blog
            )
        self.embed_form = PostElementForm(post=self.post, ui=True)
        return self.form, self.embed_form

    def get_post(self):
        """ Get the post. """
        obj_id = self.kwargs.get('obj_id')
        if obj_id:
            self.post = get_object_or_404(Post, id=obj_id)
        else:
            self.post = Post()
        return self.post

    def post(self, request, **kwargs):
        self.get_post()
        form, embed_form = self.get_forms()
        if form.is_valid():
            obj = form.save()
            element_forms = self.convert_json_to_elements(request.POST.get('export'), obj, files=request.FILES)

            element_ids = []
            elements = []

            # Save (and keep track of) all the forms.
            for e_form in element_forms:
                if not e_form.is_valid():
                    return HttpResponse(unicode(e_form.errors))
                e_obj = e_form.save()
                elements.append(e_obj)
                element_ids.append(e_obj.id)

            # Wipe out all the unkept embeds
            PostElement.objects.filter(post_id=obj.id).exclude(id__in=element_ids).delete()
            messages.add_message(request, messages.SUCCESS, 'Saved! Keep writing!')
            obj.save()

            if str(obj.id) in request.path:
                return redirect(request.path)
            else:
                # This is a hack, since I really don't know where the edit page lives.
                return redirect("{}../{}".format(request.path, str(obj.id)))
        return self.render()

    def get(self, request, *args, **kwargs):
        self.get_post()
        self.get_forms()
        return self.render()

    def render(self):
        return render(self.request, self.editor_template, {
            'base_template': self.base_template,
            'post': self.post,
            'form': self.form,
            'embed_form': self.embed_form,
            "cancel_url": self.cancel_url,
        })

    def convert_json_to_elements(self, export, post_obj, files={}):
        """
        Turns the json into elements for a post.
        Returns a tuple of text_elements and embed_elements
        """
        elements = []
        if not export:
            return elements
        data = json.loads( export )

        for key, params in data.items():
            instance = PostElement()
            if params.get('obj_id'):
                try:  # Text nodes will always be new. Oh well.
                    instance = PostElement.objects.get(id=params.get('obj_id'), post=post_obj)
                except PostElement.DoesNotExist:
                    pass

            order = int(key.split('_')[-1])
            form_data = {
                'obj_type'      : params.get('obj_type') or 'text',
                'content'       : params.get('content') or '',
                'src'           : params.get('src') or '',
                'post'          : post_obj.id,
                'order'         : order,
                'image'         : params.get('image'),
            }
            bound_form = PostElementForm(form_data, instance=instance, post=post_obj)
            elements.append(bound_form)

        return elements

@login_required
def upload_photo(request, obj_id=None, img_id=None):
    """The awful async iframe uploader."""

    form = PostImageForm(request.POST or None, files=request.FILES or None)
    resp = None

    if request.POST:
        if not obj_id:
            resp = {'errors':'Please save your post before adding images.'}
            resp = json.dumps(resp)
        if obj_id and form.is_valid():
            obj = form.save(commit=False)
            obj.post_id = obj_id
            obj.save()
            resp = {'filename': obj.image.url,
                'thumb': obj.__unicode__(),
                'id': obj.id,
            }
            resp = json.dumps(resp)

    return render(request, 'scruffy_blog/writing/upload_photo.html', {
            'form': form,
            'resp': resp,
            'stylesheet': SCRUFFY_BLOG_SETTINGS['upload_photo_stylesheet'],
        })


from typing import Dict

from .queryset import QuerySet
from json import load
from os.path import exists

class HBOSConfig(object):

    # noinspection PyBroadException
    def __init__(self, configFile):
        config = None
        self._new_install = False
        self._querysets: Dict[str, QuerySet] = dict()
        if exists(configFile):
            try:
                with open(configFile, "r") as f:
                    config = load(f)
                    f.close()
            except:
                config = None
                self._new_install=True
        if config is None:
            self._new_install = True
            return

        for k in config["querysets"]:
            self._querysets[k] = QuerySet(config["querysets"][k])

    @property
    def querysets(self) -> Dict[str, QuerySet]:
        return self._querysets

    @querysets.setter
    def set_querysets(self, value: Dict[str, QuerySet]):
        self._querysets = value

    @property
    def is_new(self) -> bool:
        return self._new_install

    @is_new.setter
    def set_is_new(self, value: bool):
        self._new_install = value


import json
import os
import sys

import requests

AUTH_URL = "https://accounts.spotify.com/api/token"
TOKEN_RELATIVE_PATH = "spotify/access_data/token.json"
CREDENTIALS_RELATIVE_PATH = "spotify/access_data/credentials.json"

client_id = None
client_secret = None
token = None

def credentialsProvided():
    if os.path.exists(CREDENTIALS_RELATIVE_PATH):
        return True
    return False

def loadCredentials():
    if not credentialsProvided():
        sys.exit()
    with open(CREDENTIALS_RELATIVE_PATH) as f:
        json_credentials = json.load(f)
    global client_id
    global client_secret
    client_id = json_credentials["client_id"]
    client_secret = json_credentials["client_secret"]

def tokenFileSaved():
    if os.path.exists(TOKEN_RELATIVE_PATH):
        return True
    return False

def loadToken():
    global token
    if token is not None:
        return
    if tokenFileSaved():
        with open(TOKEN_RELATIVE_PATH) as f:
            token = json.load(f)["token"]
    else:
        getNewToken()

def requestAuthorization():
    if client_id is None and client_secret is None:
        loadCredentials()
    auth_response = requests.post(AUTH_URL, {
        "grant_type": "client_credentials",
        "client_id": client_id,
        "client_secret": client_secret,
    })
    return auth_response

def getNewToken():
    response = requestAuthorization()
    response_json = response.json()
    global token
    token = response_json["access_token"]
    saveTokenTnJsonFile()
    return token

def saveTokenTnJsonFile():
    if token is not None:
        with open(TOKEN_RELATIVE_PATH, "w") as f:
            json.dump({"token": token}, f)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#Script is a simple, object oriented, GUI calculator for DIY projects

##It has 3 functions:

    #Cicrumference:

        #Supply length of raw planks and dimenstions of room to calculate how
        #many planks required to surround the room. Once calculation is complete
        #You may select "Next room", this will keep any offcuts left from this
        #calculation and attempt to use them in future "rooms", or "New calc"
        #which will discard any offcuts left from this calculation and start fresh.

    #Area:

        #Supply length and width of raw planks and dimenstions of room to
        #calculate how many planks required to cover the area of the room.
        #Once calculation is complete You may select "Next room", this will
        #keep any offcuts left from this calculation and attempt to use them
        #in future "rooms", or "New calc" which will discard any offcuts
        #left from this calculation and start fresh.

    #Custom:

        #Supply length and width of raw planks and length and width of any boards
        #you need to construct your project. This will find various combinations
        #of cuts from each plank and select the combinatoin with least wastage
        #from each. It will then tell you the minimum number of fresh planks
        #you need to complete your project

import tkinter
from tkinter import StringVar, ttk

##Class representing lengths of fresh wood to be used
class Plank:

    def __init__(self, length, width, woodstore):
        #Save woodstore so we can refer to it easily
        self.woodstore = woodstore

        #Define attributes of this length
        self.length = length
        self.width = width

    def cut_board(self, length, width, offcut):
        #Attempt to cut board of given size from this plank
        try:
            #Raise an exception if passed sizes are longet than this plank
            if length > self.length or width > self.width:
                raise ValueError

            #Cut board off this plank
            self.length = self.length - length

            #add cut board to list
            self.woodstore.boards.append(Board(length, width, self.woodstore))

            if offcut == False:
                #Add remainder of this plank to offcuts list
                if self.length > 0:
                    self.woodstore.offcuts.append(self)

                #If width of board is less than width of this length add to offcut list
                if self.width - width > 0:
                    self.woodstore.offcuts.append(Plank(length, self.width - width, self.woodstore))

        except ValueError:
            #If we have tried to cut a longer length than available inform user
            ##Shouldnt be able to trigger this
            Error_Message("You tried to cut off more than was available!!")

##Class representing boards cut for purpose
class Board:

    def __init__(self, length, width, woodstore):
        self.woodstore = woodstore
        self.length = length
        self.width = width

#Class to represent physical storage of cut pieces
class WoodStore:

    def __init__(self):
        #Define properties and initialize store
        self.planks = None
        self.boards = None
        self.offcuts = None
        self.empty_store()

        #Reset store to starting values
    def empty_store(self):
        #Counter to keep track of how many planks we use
        self.planks = 0

        #Lists to hold cut-to-size boards and offcuts
        self.boards = []
        self.offcuts = []

    def get_plank(self, length, width):
        #Increase count of planks used and give out plank for use
        self.planks = self.planks + 1
        return Plank(length, width, self)

#Class containing 2 option "confirmation" popup message
class Confirmation_Message:

    def __init__(self, parent, text):
        #Define confirmation popup window
        self.popup = tkinter.Toplevel()
        self.popup.geometry("450x150")
        self.popup.title("Continue?")
        self.popup.resizable(0, 0)

        #Define frame to hold text
        self.popup_frame = tkinter.Frame(
                self.popup, padx=30, pady=15)

        self.popup_frame.grid(
                row=1, column=1)

        #Define frame to hold buttons
        self.popup_button_frame = tkinter.Frame(
                self.popup, padx=30, pady=10)

        self.popup_button_frame.grid(
                row=2, column=1)

        #Define spacer for between buttons
        self.popup_spacer = tkinter.Frame(
                self.popup_button_frame, width=180)

        self.popup_spacer.grid(
                row=2, column=2)

        #Define warning message
        self.popup_label = tkinter.Label(
                self.popup_frame, text=text)

        self.popup_label.grid(
                row=1, column=1, columnspan=3)

        #Define buttons
        self.popup_cancel = tkinter.Button(
                self.popup_button_frame, text="Next room")

        self.popup_cancel.grid(
                row=2, column=1)

        self.popup_ok = tkinter.Button(
                self.popup_button_frame, text="New calc")

        self.popup_ok.grid(
                row=2, column=3)

    #Destructor to completely delete popup
    def close(self):
        self.popup.destroy()

class Error_Message:

    def ok(self):
            self.warning.destroy()

    def __init__(self, text):

        #Define error popup
        self.warning = tkinter.Toplevel()
        self.warning.geometry("275x100")
        self.warning.resizable(0, 0)
        self.warning.title("Error")

        #Define frame to hold widgets
        self.warning_frame = tkinter.Frame(
                self.warning, padx=20, pady=10,)

        self.warning_frame.pack()

        #Only insert spacer if there is only one line of text in the warning message
        if len(text.split("\n")) < 2 :
            #Define spacer for between text and button
            self.warning_spacer = tkinter.Frame(
                    self.warning_frame, height=10,)

            self.warning_spacer.grid(
                    row=2, column=2)

        #Define warning message
        self.warning_label = tkinter.Label(
                self.warning_frame, text=text, wraplength=200)

        self.warning_label.grid(
                row=1, column=1, columnspan=3)

        #Define ok button
        self.warning_ok = tkinter.Button(
                self.warning_frame, text="Ok", command=self.ok)

        self.warning_ok.grid(
                row=3, column=2)

class Area_View:

    def __init__(self, root, welcome):
        self.root = root
        self.welcome = welcome
        self.woodstore = self.welcome.woodstore

        #Make sure woodstore is empty
        self.woodstore.empty_store()

        self.frame = tkinter.Frame(self.root)
        self.frame.pack(fill="both", expand=True)

        self.top_spacer = tkinter.Frame(self.frame, width=60, height=30)
        self.top_spacer.grid(row=0, column=0)

        self.title_label = tkinter.Label(self.frame, text="Calculate area")
        self.title_label.grid(row=1, column=1, pady=10, columnspan=2)

        self.heading_label = tkinter.Label(self.frame,\
                                           text="Please enter details below")
        self.heading_label.grid(row=2, column=1, columnspan=2, pady=10)

        self.width_label = tkinter.Label(self.frame, text="Width of room: ")
        self.width_label.grid(row=3, column=1, pady=10)

        self.width_entry = tkinter.Entry(self.frame)
        self.width_entry.grid(row=3, column=2, pady=10)

        self.width_unit_label = tkinter.Label(self.frame, text="mm")
        self.width_unit_label.grid(row=3, column=3, pady=10)

        self.length_label = tkinter.Label(self.frame, text="Length of room: ")
        self.length_label.grid(row=4, column=1, pady=10)

        self.length_entry = tkinter.Entry(self.frame)
        self.length_entry.grid(row=4, column=2, pady=10)

        self.length_unit_label = tkinter.Label(self.frame, text="mm")
        self.length_unit_label.grid(row=4, column=3, pady=10)

        self.plank_width_label = tkinter.Label(self.frame, text="Width of planks: ")
        self.plank_width_label.grid(row=5, column=1, pady=10)

        self.plank_width_entry = tkinter.Entry(self.frame)
        self.plank_width_entry.grid(row=5, column=2, pady=10)

        self.plankw_unit_label = tkinter.Label(self.frame, text="mm")
        self.plankw_unit_label.grid(row=5, column=3, pady=10)

        self.plank_length_label = tkinter.Label(self.frame, text="Length of planks: ")
        self.plank_length_label.grid(row=6, column=1, pady=10)

        self.plank_length_entry = tkinter.Entry(self.frame)
        self.plank_length_entry.grid(row=6, column=2, pady=10)

        self.plankl_unit_label = tkinter.Label(self.frame, text="mm")
        self.plankl_unit_label.grid(row=6, column=3, pady=10)

        self.direction_label = tkinter.Label(self.frame, text="Which direction are you laying boards?")
        self.direction_label.grid(row=7, column=1, columnspan=2, pady=10)

        self.direction_options = ["Lengthwise", "Widthwise"]
        self.direction = StringVar()

        self.direction_menu = ttk.Combobox(
                self.frame, textvariable=self.direction,\
                values=self.direction_options, width=15)
        self.direction_menu.grid(row=8, column=2, pady=10)
        self.direction_menu.set("Lengthwise")

        self.back_button = tkinter.Button(self.frame, text="Back", command=self.welcome.back, width=12, height=3)
        self.back_button.grid(row=9, column=1, pady=20)

        self.calculate_button = tkinter.Button(self.frame, text="Calculate", command=self.calculate, width=12, height=3)
        self.calculate_button.grid(row=9, column=2, columnspan=2, pady=20, sticky="e")

    def add_room(self):
        #Close popup and leave woodstore intact to continue calculating
        self.info.close()

    def new_calc(self):
        #Empty woodstore for next calculation
        self.woodstore.empty_store()
        self.info.close()

    def calculate(self):
        self.error = False
        #check user has supplied all relevant information
        try:
            self.room_length = int(self.length_entry.get())
            self.room_width = int(self.width_entry.get())
            self.plank_length = int(self.plank_length_entry.get())
            self.plank_width = int(self.plank_width_entry.get())

        #If any details have been given in incorrect format alert user and halt processing
        except:
            Error_Message("Please check your input!")
            self.error = True

        #If no errors gathering information we can proceed
        if self.error == False:

            #Send data to function to fill given area, accounting for direction of boards

            #If boards to be layed lengthwise in room
            if self.direction.get() == "Lengthwise":
                self.fill_area(self.room_length, self.room_width)

            #If boards to be layed widthwise in room
            else:
                self.fill_area(self.room_width, self.room_length)

            #Display result to user
            self.info = Confirmation_Message(self, "You need {} planks!".format(self.woodstore.planks))
            #Configure "next room" button
            self.info.popup_cancel.config(command=self.add_room)
            #Configure "new calculation button
            self.info.popup_ok.config(command = self.new_calc)

    def fill_area(self, length, width):

        while width > 0:
            #Set length for next strip of boards
            this_strip = length

            while this_strip > 0:
                #If there is enough room to cut a full width board
                if width >= self.plank_width:

                    #If enough space for a full plank take one from store and reduce length of this strip accordingly
                    if this_strip > self.plank_length:
                        self.woodstore.get_plank(self.plank_length, self.plank_width)
                        this_strip = this_strip - self.plank_length

                    else:
                        #Check offcuts to see if we can use one of them
                        for i in self.woodstore.offcuts:
                            if i.length > this_strip and this_strip > 0 and self.plank_width == i.width:
                                i.cut_board(this_strip, self.plank_width, True)

                                #if we have used all of this offcut remove it from the list
                                if i.length == 0:
                                    self.woodstore.offcuts.remove(i)
                                this_strip = 0

                        #If we didnt have an offcut to use cut from a new plank
                        if this_strip > 0 and this_strip <= self.plank_length:
                            #get fresh plank from woodstore
                            this_plank = self.woodstore.get_plank(self.plank_length, self.plank_width)

                            #Cut plank to needed size and keep offcut for use
                            this_plank.cut_board(this_strip, self.plank_width, False)

                            this_strip = 0

                        #reduce width to cover by width of boards cut
                        width = width - self.plank_width

                #If there is not enough width left for a full plank
                else:
                    #If theres enough space for a full plank cut one to width
                    if this_strip > self.plank_length:
                        this_plank = self.woodstore.get_plank(self.plank_length, self.plank_width)
                        this_plank.cut_board(self.plank_length, width, False)
                        this_strip = this_strip - self.plank_length

                        #If we have completed the last strip reduce width to 0
                        if this_strip == 0:
                            width = 0

                    else:
                        #Check offcuts to see if we can use one of them
                        for i in self.woodstore.offcuts:
                            if i.length >= this_strip and this_strip > 0 and i.width >= width:
                                i.cut_board(this_strip, width, True)

                                #if we have used all of this offcut remove it from the list
                                if i.length == 0:
                                    self.woodstore.offcuts.remove(i)
                                this_strip = 0
                                width = 0

                        #If we didnt have an offcut to use cut from a new plank
                        if this_strip > 0 and this_strip <= self.plank_length:
                            #get fresh plank from woodstore
                            this_plank = self.woodstore.get_plank(self.plank_length, self.plank_width)

                            #Cut plank to needed size and keep offcut for use
                            this_plank.cut_board(this_strip, width, False)

                            this_strip = 0
                            width = 0

class Circumference_View:

    def __init__(self, root, welcome):
        self.root = root
        self.welcome = welcome
        self.woodstore = self.welcome.woodstore

        #Make sure woodstore is empty
        self.woodstore.empty_store()

        self.frame = tkinter.Frame(self.root)
        self.frame.pack(fill="both", expand=True)

        self.top_spacer = tkinter.Frame(self.frame, width=50, height=30)
        self.top_spacer.grid(row=0, column=0, pady=10)

        self.title_label = tkinter.Label(self.frame, text="Calculate circumference")
        self.title_label.grid(row=1, column=1, pady=10, columnspan=2)

        self.heading_label = tkinter.Label(self.frame,\
                                           text="Please enter details below")
        self.heading_label.grid(row=2, column=1, columnspan=2, pady=10)

        self.width_label = tkinter.Label(self.frame, text="Width of room: ")
        self.width_label.grid(row=3, column=1, pady=10)

        self.width_entry = tkinter.Entry(self.frame)
        self.width_entry.grid(row=3, column=2, pady=10)

        self.width_unit_label = tkinter.Label(self.frame, text="mm")
        self.width_unit_label.grid(row=3, column=3, pady=10)

        self.length_label = tkinter.Label(self.frame, text="Length of room: ")
        self.length_label.grid(row=4, column=1, pady=10)

        self.length_entry = tkinter.Entry(self.frame)
        self.length_entry.grid(row=4, column=2, pady=10)

        self.length_unit_label = tkinter.Label(self.frame, text="mm")
        self.length_unit_label.grid(row=4, column=3, pady=10)

        self.plank_length_label = tkinter.Label(self.frame, text="Length of planks: ")
        self.plank_length_label.grid(row=5, column=1, pady=10)

        self.plank_length_entry = tkinter.Entry(self.frame)
        self.plank_length_entry.grid(row=5, column=2, pady=10)

        self.plank_unit_label = tkinter.Label(self.frame, text="mm")
        self.plank_unit_label.grid(row=5, column=3, pady=10)

        self.back_button = tkinter.Button(self.frame, text="Back", command=self.welcome.back, width=12, height=3)
        self.back_button.grid(row=6, column=1, pady=20)

        self.calculate_button = tkinter.Button(self.frame, text="Calculate", command = self.calculate, width=12, height=3)
        self.calculate_button.grid(row=6, column=2, columnspan=2, pady=20, sticky="e")

    def calculate(self):

        self.error = False
        #check user has supplied all relevant information
        try:
            self.room_length = int(self.length_entry.get())
            self.room_width = int(self.width_entry.get())
            self.plank_length = int(self.plank_length_entry.get())

        #If any details have been given in incorrect format alert user and halt processing
        except:
            Error_Message("Please enter whole numbers only!")
            self.error = True

        #If no errors gathering information we can proceed
        if self.error == False:
            #Cut boards for 2 longer sides
            for i in range(2):
                wall = self.room_length
                self.cut_for_wall(wall)

            #Cut booards for 2 shorter sides
            for i in range(2):
                wall = self.room_width
                self.cut_for_wall(wall)

            self.info = Confirmation_Message(self, "You need {} planks!".format(self.woodstore.planks))
            #Configure "next room" button
            self.info.popup_cancel.config(command=self.add_room)
            #Configure "new calculation button
            self.info.popup_ok.config(command = self.new_calc)

    def add_room(self):
        #Close popup and leave woodstore intact to continue calculating
        self.info.close()

    def new_calc(self):
        #Empty woodstore for next calculation
        self.woodstore.empty_store()
        self.info.close()

    def cut_for_wall(self, wall):
        while wall > 0:
            #If wall length is longer than plank length take whole plank and reduce length of wall
            #to calculate accordingly
            if wall > self.plank_length:
                self.woodstore.get_plank(self.plank_length, 0)
                wall = wall - self.plank_length

            #if plank is long enough to cover remaining section of wall
            else:
                #Check offcuts to see if we can use one of them
                for i in self.woodstore.offcuts:
                    if i.length > wall and wall > 0:
                        i.cut_board(wall, 0, True)

                        #if we have used all of this offcut remove it from the list)
                        if i.length == 0:
                            self.woodstore.offcuts.remove(i)
                        wall = 0

                #If we didnt have an offcut to use cut from a new plank
                if wall > 0:
                    #get fresh plank from woodstore
                    this_plank = self.woodstore.get_plank(self.plank_length, 0)

                    #Cut plank to needed size and keep offcut for use
                    this_plank.cut_board(wall, 0, False)

                    wall = 0

class Custom_View:

    def __init__(self, root, welcome):
        self.root = root
        self.welcome = welcome
        self.woodstore = self.welcome.woodstore

        #Make sure woodstore is empty
        self.woodstore.empty_store()

        #Counter to keep track of next available row of widgets
        self.row_counter = 2
        #dictionary to store generated widgets in using row number as key
        self.widgets = {}
        #List to hold initial row of board input widgets
        row0 = []

        self.container = tkinter.Frame(self.root)

        self.canvas = tkinter.Canvas(
                self.container, width=435, height=600)

        #Define scrollbar
        self.scrollbary = tkinter.Scrollbar(
                self.container, orient="vertical",\
                command=self.canvas.yview)

        #Create the top frame to hold widgets
        self.frame = tkinter.Frame(self.canvas)

        #Define scrollable region of canvas
        self.frame.bind(
                "<Configure>", lambda e:
                    self.canvas.configure(
                            scrollregion=self.canvas.bbox(
                                    "all")))
        self.canvas.create_window(
                (0, 0), window=self.frame, anchor="nw")

        #Configure the commands for interacting with scrollbars
        self.canvas.configure(
                yscrollcommand=self.scrollbary.set)

        #attach container to parent
        self.container.pack()

        #Define positioning of scrollbars
        self.scrollbary.grid(
                row=1, column=2, sticky="ns")

        #pack canvas into container and span full area of container
        self.canvas.grid(
                row=1, column=1, sticky="nsew")

        self.top_spacer = tkinter.Frame(self.frame, width=60, height=30)
        self.top_spacer.grid(row=0, column=0)

        self.title_label = tkinter.Label(self.frame, text="Custom project")
        self.title_label.grid(row=1, column=1, pady=10, columnspan=2)

        self.heading_label = tkinter.Label(self.frame,\
                                           text="Please enter sizes of raw plank of timber")
        self.heading_label.grid(row=2, column=1, columnspan=2, pady=10)

        self.plank_length_label = tkinter.Label(self.frame, text="Length of planks: ")
        self.plank_length_label.grid(row=3, column=1, pady=10)

        self.plank_length_entry = tkinter.Entry(self.frame)
        self.plank_length_entry.grid(row=3, column=2, pady=10)

        self.plankl_unit_label = tkinter.Label(self.frame, text="mm")
        self.plankl_unit_label.grid(row=3, column=3, pady=10)

        self.plank_width_label = tkinter.Label(self.frame, text="Width of planks: ")
        self.plank_width_label.grid(row=4, column=1, pady=10)

        self.plank_width_entry = tkinter.Entry(self.frame)
        self.plank_width_entry.grid(row=4, column=2, pady=10)

        self.plankw_unit_label = tkinter.Label(self.frame, text="mm")
        self.plankw_unit_label.grid(row=4, column=3, pady=10)

        self.table_heading = tkinter.Label(self.frame, text="Please enter boards you need for your project")
        self.table_heading.grid(row=5, column=1, columnspan=3, pady=10)

        #Frame to hold table of dynamic entries
        self.board_frame = tkinter.Frame(self.frame)
        self.board_frame.grid(row=6, column=1, columnspan=3, sticky="nsew")

        self.length_heading = tkinter.Label(self.board_frame, text="L")
        self.length_heading.grid(row=0, column=1, pady=10)

        self.length_entry = tkinter.Entry(self.board_frame, width=7)
        self.length_entry.grid(row=1, column=1, pady=10, padx=5)
        row0.append(self.length_entry)

        self.x_label = tkinter.Label(self.board_frame, text="X")
        self.x_label.grid(row=1, column=2, pady=10, padx=5)
        row0.append(self.x_label)

        self.width_heading = tkinter.Label(self.board_frame, text="W")
        self.width_heading.grid(row=0, column=3, pady=10)

        self.width_entry = tkinter.Entry(self.board_frame, width=7)
        self.width_entry.grid(row=1, column=3, pady=10, padx=5)
        row0.append(self.width_entry)

        self.unit_label = tkinter.Label(self.board_frame, text="mm")
        self.unit_label.grid(row=1, column=4, pady=10, padx=5)
        row0.append(self.unit_label)

        #Add initially generated row of board input widgets to dictionary
        self.widgets[0] = row0

        #########Here will be generated rows for adding more boards

        self.row_button = tkinter.Button(self.frame, text="+", command=self.add_row, height=3, width=5)
        self.row_button.grid(row=7, column=1, pady=10, sticky="e")

        self.back_button = tkinter.Button(self.frame, text="Back", command=self.welcome.back, width=12, height=3)
        self.back_button.grid(row=8, column=1, pady=10)

        self.calculate_button = tkinter.Button(self.frame, text="Calculate", command=self.calculate, width=12, height=3)
        self.calculate_button.grid(row=8, column=2, columnspan=2, pady=10, sticky="e")

    #Add another row of widgets to display
    def add_row(self):

        #Define list to hold widgets
        this_row = []

        #Define widgets for this row, add each to list
        length_entry = tkinter.Entry(self.board_frame, width=7)
        length_entry.grid(row=self.row_counter, column=1, pady=10)
        this_row.append(length_entry)

        x_label = tkinter.Label(self.board_frame, text="X")
        x_label.grid(row=self.row_counter, column=2, pady=10)
        this_row.append(x_label)

        width_entry = tkinter.Entry(self.board_frame, width=7)
        width_entry.grid(row=self.row_counter, column=3, pady=10)
        this_row.append(width_entry)

        unit_label = tkinter.Label(self.board_frame, text="mm")
        unit_label.grid(row=self.row_counter, column=4, pady=10)
        this_row.append(unit_label)

        remove_button = tkinter.Button(self.board_frame, text="-", command=lambda x=self.row_counter:self.del_row(x))
        remove_button.grid(row=self.row_counter, column=5, pady=10)
        this_row.append(remove_button)

        #Store list of widgets in dictionary using row number as key
        self.widgets[self.row_counter] = this_row

        #Increase row counter for next row
        self.row_counter = self.row_counter + 1

    def add_room(self):
        #Close popup and leave woodstore intact to continue calculating
        self.info.close()

    def new_calc(self):
        #Empty woodstore for next calculation
        self.woodstore.empty_store()
        self.info.close()

    def del_row(self, i):
        #Loop over list of widgets stored under passed row number
        #And destroy all
        for j in self.widgets[i]:
            j.destroy()
        #Remove entry from dictionary to avoid errors when reading in data
        del self.widgets[i]

    def calculate(self):

        #Function to sort list of boards
        def sort_func(x):
            return x.length

        #Bool flag to toggle if any errors reading in data
        self.error = False

        #Declare list to hold boards we need to cut
        self.boards = []

        try:

            ###Read in data from widgets, halt processing if any errors encountered

            #pull info on size of raw lengths
            self.raw_length = int(self.plank_length_entry.get())
            self.raw_width = int(self.plank_width_entry.get())

            #create board objects from supplied dimensions, hold in list
            for value in self.widgets.values():

                #Check the sizes of board required are within sizes of raw plank
                if int(value[0].get()) <= self.raw_length and int(value[2].get()) <= self.raw_width:
                    self.boards.append(Board(int(value[0].get()), int(value[2].get()), self.woodstore))

                #If above failed check if the supplied lehgth and width for this board wave been reversed
                elif int(value[2].get()) <= self.raw_length and int(value[0].get()) <= self.raw_width:
                    self.boards.append(Board(int(value[2].get()), int(value[0].get()), self.woodstore))

                else:
                    #If we couldnt get this board to fit within supplied dimensions for raw plank
                    #Inform user and halt processing
                    Error_Message("One of your boards is too big to cut from these planks!")
                    self.error = True

        except:
            Error_Message("Please enter whole numbers only!")
            self.error = True

        ###Provided there were no errors encountered building data, sort list of boards to cut by length

        #If we ran into any problems gathering data halt processing
        if self.error == False:
            #sort list of boards by length, largest to smallest
            self.boards.sort(reverse=True, key=sort_func)

            ##While list contains something##
            while len(self.boards) > 0:

                ###Start with longest board that needs cut, cut this from fresh plank and remove from list of
                ###boards to be cut

                #Check offcuts to see if any will fit this board
                found = False
                for i in self.woodstore.offcuts:
                    if i.length >= self.boards[0].length:
                        i.cut_board(self.boards[0].length, self.boards[0].width, True)
                        found = True
                        this_length = i

                #If there wasnt an offcut that fit this board just take a new plank from stores
                if found == False:
                    #take length from woodstore, cut longest board in list
                    this_length = self.woodstore.get_plank(self.raw_length, self.raw_width)
                    this_length.cut_board(self.boards[0].length, self.boards[0].width, False)

                #Delete board we just cut from list of required boards
                del self.boards[0]

                ###Loop over remaining boards and see if any can be cut from remainder of this plank, save any that fit
                ###into list and save list and reference to starting board in dictionaries (stored as 2 dictionaries with
                ###starting board reference as key to avoid issues if more than one combination gives the same wastage)

                ###Repeat this process until we have lists of every combination of boards we can cut from
                ###the remainder of this plank

                #Dictionary to hold results from passes over boards
                attempts = {}
                results = {}

                for i in range(len(self.boards)):
                    #Save remaining length in this plank
                    remaining_length = this_length.length

                    #List to hold boards for this pass
                    this_pass = []

                    #look at next longest board and see if there's enough left for it
                    if self.boards[i].length <= remaining_length:
                        remaining_length = remaining_length - self.boards[i].length
                        #Save index reference for board
                        this_pass.append(self.boards[i])

                        #Loop over remaining boards and see if any more will fit
                        for j in range(len(self.boards) - i):
                            if self.boards[j+i].length <= remaining_length:
                                remaining_length = remaining_length - self.boards[j+i].length
                                #Save index reference for board
                                this_pass.append(self.boards[j+i])

                        #Save list of results in dictionary using starting board index as key
                        attempts[i] = this_pass
                        results[i] = remaining_length

                ###Examine combinations we found and see which one leaves us the least left over material
                ###Then cut these boards and remove them from list of boards to be cut

                wastage = 999999
                permutation = None
                #Make sure we found something before trying to process
                if attempts != {}:
                    #Check results to find least wastage
                    for key, value in results.items():
                        if value < wastage:
                            wastage = value
                            permutation = key #key is the key of the combination of boards we want to cut from plank

                    #Loop over boards in chosen permutation and cut them from plank
                    for i in range(len(attempts[permutation])):
                        #Delete board from list of boards to be cut
                        try:
                            self.boards.remove(attempts[permutation][i])
                            this_length.cut_board(attempts[permutation][i].length, attempts[permutation][i].width, False)

                        #In case we try to delete a board that isnt in the list anymore
                        #Shouldnt happen
                        except:

                            pass

            self.info = Error_Message( "You need {} planks!".format(self.woodstore.planks))

class Welcome_view:

    def __init__(self, root):

        self.root = root

        #Initialize woodstore so we can store our wood
        self.woodstore = WoodStore()

        #Create display
        self.create_view()

    def create_view(self):

        self.frame = tkinter.Frame(self.root)
        self.frame.pack(fill="both", expand=True)

        self.top_spacer = tkinter.Frame(self.frame, width=80, height=50)
        self.top_spacer.grid(row=0, column=0)

        self.heading_label = tkinter.Label(self.frame, text="What are you trying to calculate today?")
        self.heading_label.grid(row=1, column=1, pady=20)

        self.area_button = tkinter.Button(self.frame, text="Area", command=self.area, width=12, height=3)
        self.area_button.grid(row=2, column=1, pady=20)

        self.circumference_button = tkinter.Button(self.frame, text="Circumference", command=self.circumference, width=12, height=3)
        self.circumference_button.grid(row=3, column=1, pady=20)

        self.custom_button = tkinter.Button(self.frame, text="Custom", command=self.custom, width=12, height=3)
        self.custom_button.grid(row=4, column=1, pady=20)

    def destroy_view(self):
        for widget in self.root.winfo_children():
            widget.destroy()

    def area(self):
        self.destroy_view()
        Area_View(self.root, self)

    def circumference(self):
        self.destroy_view()
        Circumference_View(self.root, self)

    def custom(self):
        self.destroy_view()
        Custom_View(self.root, self)

    def back(self):
        #Destroy current view and re-create welcome screen
        self.destroy_view()
        self.create_view()

#Define root window
root = tkinter.Tk()

root.title("Board calculator V1.0")
root.geometry("450x600")

view = Welcome_view(root)

if __name__ == "__main__":
    root.mainloop()


import logging

import discord
from discord.ext import commands
from motor.motor_asyncio import AsyncIOMotorClient

logger = logging.getLogger("DDog")

class DDog(commands.AutoShardedBot):
    def __init__(self, *args, **kwargs):
        if kwargs.get("mongourl"):
            logger.info("URL para MongoDB detectada, intentando conexion")
            self.db = AsyncIOMotorClient(kwargs.get("mongourl"))
        else:
            self.db = None

        if "mongourl" in kwargs:
            kwargs.pop("mongourl")

        super().__init__(*args, **kwargs)

        self.remove_command("help")

        self.add_command(self.stop)
        self.add_command(self._help)

    async def on_command(self, ctx):
        logger.info("Commando por {0.name} - {0.id}: {1.content}".format(ctx.author, ctx.message))

    async def on_ready(self):
        logger.info("Listo para trabajar con el prefijo '{0}'".format(self.command_prefix))

        game = discord.Game("{0}help".format(self.command_prefix))
        await self.change_presence(activity=game)

    @commands.command(alias=["detener", "cerrar"])
    @commands.is_owner()
    async def stop(self, ctx):
        """Detiene al Bot (en el caso de Heroku, lo reinicia)"""
        await ctx.send("Adios!")
        await self.logout()

    @commands.command(name="help")
    async def _help(self, ctx, *, uinput=None):
        """Muestra este mensaje de ayuda"""
        coms = []

        for com in self.commands:
            try:
                await com.can_run(ctx)
            except commands.CommandError:
                pass
            else:
                coms.append(com)

        coms = sorted(coms, key=lambda command: command.name)

        index = 0

        if uinput:
            if uinput.isnumeric():
                uinput = int(uinput)

        ifst = 5 * index
        ilst = 5 * index + 5

        if ifst >= len(coms):
            await ctx.send("La pagina de ayuda no es valida.")
            return
        if ilst > len(coms):
            ilst = len(coms)

        coms = coms[ifst:ilst]

        embed = discord.Embed(title="Comandos de {0}".format(ctx.me.name), colour=0x7FD935)
        for command in coms:
            embed.add_field(name=self.command_prefix + command.name,
                            value=command.help.splitlines()[0], inline=False)

        await ctx.send(embed=embed)


import serial
import json
import os
import random
##from twilio.rest import Client
import time
import requests
import pygame

ser = serial.Serial('COM24', 115200)

print ("connected to: " + ser.portstr)

while True:
    line = ser.readline()
    print("read a line")
    line = line.decode('utf8')
    ##line = line [2:13]
    ##line = line.replace(" ", "")
    line=line.rstrip()
    ##print(line)

    if line.count("#") != 2:
        print (line.count("##"))
        continue
    if line.count("?") != 2:
        continue
    line = line [2:30]
    line = line.replace("?", "")
    ##print(line)

    words = line.split(',')
    if "0.00" in words or len(words) != 5:
        continue

    for word in words:
        print(word)


from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponseRedirect
from .forms import ContatosForm
from .models import Contatos

def contatos(request):
    lista = Contatos.objects.order_by('nome')
    return render(request, 'contatos.html', {'lista' : lista})

def menu(request):
    return render(request, 'menu.html')

def criar(request):
    if request.method == 'POST':
        form = ContatosForm(request.POST)
        if form.is_valid():

            agenda = form.save(commit = False)

            agenda.save()
            return redirect('recente')
    else:
        form = ContatosForm()

    return render(request, 'criar.html', {'form' : form})

def detalhe(request, pk):
    agenda = get_object_or_404(Contatos, pk=pk)
    return render(request, 'detalhes.html', {'agenda' : agenda})

def editar(request, pk):
    contato = get_object_or_404(Contatos, pk=pk)
    if request.method == 'POST':
        form = ContatosForm(request.POST, instance=contato)
        if form.is_valid():
            contato.save()
            return redirect('detalhe', pk=contato.pk)
    else:
        form = ContatosForm(instance=contato)
    return render(request, 'editar.html', {'form' : form})

def deletar(request, pk):
    contato = get_object_or_404(Contatos, pk=pk)
    contato.delete()
    return redirect('contatos')

def recente(request):
    recente = Contatos.objects.latest('id')
    return render(request, 'recente.html', {'recente' : recente})