Ikariam Imperator

Overview tables for Ikariam 0.5.0+ desktop versions in the style of Ikariam Empire Board or Ikariam ExMachina. Rule your empire with ease!

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name           Ikariam Imperator
// @namespace      aubergineanodyne
// @description    Overview tables for Ikariam 0.5.0+ desktop versions in the style of Ikariam Empire Board or Ikariam ExMachina.  Rule your empire with ease!
// @author         AubergineAnodyne (Turkish translation edit by tuncayerguden)
//
// @grant          GM_getValue
// @grant          GM_setValue
// @grant          GM_addStyle
// @grant          GM_xmlhttpRequest
// @include        http://s*.*.ikariam.*/*
// @include        http://s*.ikariam.gameforge.com/*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
// @require        https://greasyfork.org/scripts/3622-ikariam-developer-tools-v0-5-0/code/Ikariam Developer Tools V050+.user.js
//
// @version        0.29
//
// @history        0.29 Added new ikariam domain url. (ikariam.gameforge.com)
// @history        0.28 Added Turkish translation (by tuncayerguden).
// @history        0.27 Fixed pillage of crystal not showing up.
// @history        0.26 Fixed colonization init-for-pirating implementation.
// @history        0.26 Fixed display of garrison table headers in Chrome.
// @history        0.25 Added espionage overview (FarmList reimplementation).
// @history        0.25 Removed "upgrade hover box" that shows only time for buildings that have already reached their max level.
// @history        0.25 Added option to initialize colonization missions for pirate raiding.
// @history        0.24 Added option to prevent destruction of non-mobile colonies (any town with a palace or governors residence).
// @history        0.24 Added option to show owner name next to city name on city view.
// @history        0.24 Added prompt to have script completely demolish building when downgrading by one level.
// @history        0.24 Added Hungarian translation (by Toroco).
// @history        0.24 Updated for Ikariam changes in 5.3.2.
// @history        0.23 Added support for Pirate Fortress (v0.5.3 new building).
// @history        0.23 Added Spanish translation (by Rada974).
// @history        0.23 Added French translation (by HéliOGraph).
// @history        0.22 Added debug setting to reset all data to default.
// @history        0.22 Fixed column separators on military overview table (misaligned by 1).
// @history        0.22 Fixed labels on links to barracks and shipyard in military overview table.
// @history        0.22 Changed building tooltip to show costs for next level when upgrading.
// @history        0.21 Updated German translation (from Cherry).
// @history        0.21 Fixed a bug preventing mine links from working.
// @history        0.20 Updated Polish translation (from pitmm).
// @history        0.20 Added Bosnian translation (from Scavenger).
// @history        0.20 Added debug panel.
// @history        0.19 Made a couple tweaks to alert functionality for Chrome.
// @history        0.18 Added desktop alert functionality for building upgrades and transport/deploy army,navy/pillage missions.
// @history        0.17 Added quick loading buttons for transports and donations (basically the x500 payloads script).
// @history        0.17 Updated German translation.
// @history        0.17 Added Polish translation (by pitmm).
// @history        0.17 Fixed a bug that incoming trade/pillage mission resources did not show up in overview.
// @history        0.16 Switched to new version of dependent scripts.
// @history        0.15 Fixed translation of settings not being applied.
// @history        0.15 Updated German translation.
// @history        0.14 Reworked impelentation of auto daily bonus form submit for Chrome.
// @history        0.13 Fix for Chrome (hopefully).
// @history        0.12 Added support for localization (and German translation from Cherry).
// @history        0.12 Added option to automatically submit daily bonus form.
// @history        0.12 Added features to hide various minor parts of the interface (chat, friends list, facebook button, ads).
// @history        0.12 Show loading pillage missions in incoming transport.
// @history        0.11 Small tweak to work with TamperMonkey in Google Chrome.
// @history        0.10 Initial version.
// ==/UserScript==

$.extend(String.prototype, {
  format: function() {
    var pattern = /%s/g
    
    return function format() {
      var args = arguments;
      var itemIndex = 0;
      var str = this.replace(pattern, function replacer(match, key) {
        return args[itemIndex++];
      });
      return str;
    }
  }(),
  format2: function() {
      var pattern = /%{([a-zA-Z_0-9]+)}/g
      
      return function format2(args) {
        var str = this.replace(pattern, function replacer(match, key) {
          return args[key];
        });
        return str;
      }
  }(),
});

var Imperator = function Imperator() {
  var localizations = {
    en: {
      misc: {
        resource_overview: 'Resource Overview',
        buildings_overview: 'Buildings Overview',
        military_overview: 'Military Overview',
        espionage_overview: 'Espionage Overview',
      
        upkeep: "Upkeep",
        growth: "Growth",
        trade_good: "Trade Good",
        city_name: "City",
        action_points: "Action Points",
        actions: "Actions",
        research: "Research",
        building_spots: "Building Spots",

        constructing: "Constructing",
        summary: "Summary:",
        
        population: "Population",
        population_growth: "Growth",
        
        resources: 'Resources',
        buildings: 'Buildings',
        military: 'Military',
        espionage: 'Espionage',
        
        resource_overview: 'Resources Overview',
        buildings_overview: 'Buildings Overview',
        military_overview: 'Military Overview',
        
        resource_cost: 'Cost',
        next_level_cost: 'Next Level Cost',
        missing: 'Missing',
        
        full: 'Full',
        time_to_full: 'To Full',
        time_to_empty: 'To Empty',
        
        maximum_capacity: 'Capacity',
        safe_capacity: 'Safe',
        employed: 'Employed',
        
        satisfaction: 'Satisfaction',
        tavern_wine_serving_level: 'Tavern Level',
        cultural_goods: 'Cultural Goods',
        
        units: 'Units',
        training: 'Training',
        deploying: 'Deploying',
        plundering: 'Plundering',
        
        in_transit: 'Transporting',
        none: 'None',
      },
      tweaks: {
        transport_minus_500: '-',
        transport_plus_500: '+500',
        transport_plus_1000: '+1k',
        transport_plus_5000: '+5k',
        
        transport_minus_500_text: 'Remove 500 goods',
        transport_plus_500_text: 'Add 500 goods',
        transport_plus_1000_text: 'Add 1000 goods',
        transport_plus_5000_text: 'Add 5000 goods',
        
        donate_plus_1000: '+1k',
        donate_plus_10000: '+10k',
        donate_plus_100000: '+100k',
        
        donate_plus_1000_text: 'Add 1000 wood to donation',
        donate_plus_10000_text: 'Add 10000 wood to donation',
        donate_plus_100000_text: 'Add 100000 wood to donation',
        
        completely_demolish_building_prompt: 'Do you want to completely demolish this building?',
        destroy_non_mobile_colony_prompt: 
            'Demolition of non-mobile colony blocked by "Ikariam Imperator"!  If you really ' +
            'want to demolish this town, first turn off the protection option in ' +
            '"Ikariam Imperator" options.',
      },
      actions: {
        deploy_army: 'Deploy Army',
        deploy_navy: 'Deploy Navy',
        transport_goods: 'Transport Goods',
        to_town_hall: 'To Town Hall',
        to_city_view: 'View City',
        to_island_view: 'View Island',
        to_barracks: 'To Barracks',
        to_shipyard: 'To Shipyard',
        spy_mission: 'Spy Mission',
        blockade: 'Blockade',
        pillage: 'Pillage',
        occupy: 'Occupy',
        send_spy: 'Send Spy',
        view_high_score: 'View Score',
        view_alliance_page: 'View Alliance Page',
      },
      resources: {
        wood: 'Wood',
        wine: 'Wine',
        marble: 'Marble',
        glass: 'Crystal',
        sulfur: 'Sulfur',
      },
      buildings: {
        townHall: 'Town Hall',
        palace: 'Palace',
        palaceColony: 'Governor\'s Residence',
        tavern: 'Tavern',
        museum: 'Museum',
        academy: 'Academy',
        workshop: 'Workshop',
        temple: 'Temple',
        embassy: 'Embassy',
        warehouse: 'Warehouse',
        dump: 'Dump',
        port: 'Trading Port',
        branchOffice: 'Trading Post',
        wall: 'Wall',
        safehouse: 'Hideout',
        barracks: 'Barracks',
        shipyard: 'Shipyard',
        pirateFortress: 'Pirate Fortress',
        forester: 'Forester',
        carpentering: 'Carpenter',
        winegrower: 'Winegrower',
        vineyard: 'Wine Press',
        stonemason: 'Stonemason',
        architect: 'Architect',
        glassblowing: 'Glassblower',
        optician: 'Optician',
        alchemist: 'Alchemist\'s Tower',
        fireworker: 'Firework Test Area',
      },
      units: {
        phalanx: 'Hoplite',
        steamgiant: 'Steam Giant',
        spearman: 'Spearman',
        swordsman: 'Swordsman',
        slinger: 'Slinger',
        archer: 'Archer',
        marksman: 'Sulphur Carabineer',
        ram: 'Ram',
        catapult: 'Catapult',
        mortar: 'Mortar',
        gyrocopter: 'Gyrocopter',
        bombardier: 'Balloon-Bombadier',
        cook: 'Cook',
        medic: 'Doctor',
        
        ship_ram: 'Ram Ship', 
        ship_flamethrower: 'Fire Ship',
        ship_steamboat: 'Steam Ram', 
        ship_ballista: 'Ballista Ship', 
        ship_catapult: 'Catapult Ship', 
        ship_mortar: 'Mortar Ship', 
        ship_submarine: 'Diving Boat',
        ship_paddlespeedship: 'Paddle Speedboat',
        ship_ballooncarrier: 'Balloon Carrier',
        ship_tender: 'Tender',
        ship_rocketship: 'Rocker Ship',
      },
      alerts: {
        building_upgrade_complete: 'Building upgrade complete',
        building_upgrade_complete_text: '%{building} in %{city} upgraded to level %{level}',
        
        mission_update: 'Mission update',
        
        loading: '%{type} has finished loading in %{city}',
        en_route: '%{type} has arrived in %{city}',
        returning: '%{type} has returned to %{city}',
        
        deployarmy: 'Army deployment',
        deploynavy: 'Navy deployment',
        plunder: 'Pillage',
        transport: 'Transport',
      },
      espionage: {
        player: 'Player',
        townhall_level: 'Town Hall Level',
        wall_level: 'Wall Level',
        travel_time: 'Travel Time',
        resources_lootable: 'Lootable',
        resources_looted: 'Looted',
        combats: 'Combats',
        military_score: 'Military Score',
        location: 'Location',
        view_island: 'View Island',
        occupied_by: 'Occupied by',
        blockaded_by: 'Blockaded by',
        time_since: 'Time Since',
        remove_target: 'Remove Target',
      },
      settings: {
        general: 'General',
        language: 'Language',
      
        overviews: 'Overviews',
        
        tweaks: 'Tweaks',
        auto_accept_daily_bonus: 'Automatically submit daily bonus form',
        hide_ads: 'Hide ads',
        hide_facebook: 'Hide facebook button',
        hide_friends_bar: 'Hide friends bar',
        hide_chat: 'Hide chat',
        transport_buttons: 'Add transport buttons: -500, +500, +1k, +5k',
        donation_buttons: 'Add donation buttons: +1k, +10k, +100k',
        show_city_owners: 'Show city owner next to city name (island view)',
        prevent_accidental_colony_destruction: 'Prevent destruction of non-mobile colonies',
        initialize_colonization_missions_for_pirate_raiding: 
            'Initialize colonization missions with wood and marble to build level 1 pirate fortress and use max draft speed',
        
        alerts: 'Alerts',
        do_test: 'Test',
        test_desktop_alert: 'Test desktop notification',
        test_desktop_alert_title: 'Test notification',
        test_desktop_alert_text: 'Successful notification!  Click to dismiss.',
        desktop_alerts_not_supported: 
             'Desktop alerts not supported by your browser.  You can try the HTML Desktop' + 
             'Notification extension for Firefox ' + 
             '(https://addons.mozilla.org/en-us/firefox/addon/html-notifications/) ' + 
             'or switching to Chrome (www.google.com/chrome/).',
             
        building_completion_alert_desktop: 'Desktop notification: building upgrade complete',
        transport_loaded_alert_desktop: 'Desktop notification: transport mission loaded',
        transport_arrived_alert_desktop: 'Desktop notification: transport mission arrived',
        transport_returned_alert_desktop: 'Desktop notification: transport mission returned',
        deploy_army_loaded_alert_desktop: 'Desktop notification: deploy army loaded',
        deploy_army_arrived_alert_desktop: 'Desktop notification: deploy army arrived',
        deploy_army_returned_alert_desktop: 'Desktop notification: deploy army returned',
        deploy_navy_arrived_alert_desktop: 'Desktop notification: deploy navy arrived',
        deploy_navy_returned_alert_desktop: 'Desktop notification: deploy navy returned',
        pillage_loaded_alert_desktop: 'Desktop notification: pillage loaded',
        pillage_arrived_alert_desktop: 'Desktop notification: pillage arrived',
        pillage_returned_alert_desktop: 'Desktop notification: pillage returned',
        
        debug: 'Debug',
      },
    },
    ba: {
      misc: {
        resource_overview: 'Pregled resursa',
        buildings_overview: 'Pregled zgrada',
        military_overview: 'Pregled vojske',
      
        upkeep: "Zadovoljstvo",
        growth: "Rast",
        trade_good: "Trade Good",
        city_name: "Grad",
        action_points: "Akcijski bodovi",
        actions: "Akcije",
        research: "Istraživanje",
        building_spots: "Gradilište",

        constructing: "Izgradnja",
        summary: "Ukupno:",
        
        population: "Populacija",
        population_growth: "Rast",
        
        resources: 'Resursi',
        buildings: 'Zgrade',
        military: 'Trupe',
        
        resource_overviewTab: 'Resursi',
        buildings_overviewTab: 'Zgrade',
        military_overviewTab: 'Trupe',
        
        resource_cost: 'Cijena',
        missing: 'Nedostaje',
        
        full: 'Puno',
        time_to_full: 'do popune',
        time_to_empty: 'do pražnjenja',
        
        maximum_capacity: 'Kapaciet',
        safe_capacity: 'Sigurno',
        employed: 'Radnici',
        
        satisfaction: 'Zadovoljstvo',
        tavern_wine_serving_level: 'Nivo Taverne',
        cultural_goods: 'Kulturna dobra',
        
        units: 'Jedinice',
        training: 'Regrutirano',
        deploying: 'Stacioniranje',
        plundering: 'Pljačka',
        
        in_transit: 'Transport',
      },
      tweaks: {
        transport_minus_500: '-',
        transport_plus_500: '+500',
        transport_plus_1000: '+1k',
        transport_plus_5000: '+5k',
        
        transport_minus_500_text: 'Ukloni 500 dobra',
        transport_plus_500_text: 'Dodaj 500 dobra',
        transport_plus_1000_text: 'Dodaj 1000 dobra',
        transport_plus_5000_text: 'Dodaj 5000 dobra',
        
        donate_plus_1000: '+1k',
        donate_plus_10000: '+10k',
        donate_plus_100000: '+100k',
        
        donate_plus_1000_text: 'Dodaj 1000 drva za donaciju',
        donate_plus_10000_text: 'Dodaj 10000 drva za donaciju',
        donate_plus_100000_text: 'Dodaj 100000 drva za donaciju',
        
      },
      actions: {
        deploy_army: 'Stacioniraj trupe',
        deploy_navy: 'Stacioniraj flotu',
        transport_goods: 'Prevezi dobra',
        to_town_hall: 'U Vječnicu',
        to_city_view: 'Prikaži grad',
      },
      resources: {
        wood: 'Drva',
        wine: 'Vino',
        marble: 'Mramor',
        glass: 'Kristal',
        sulfur: 'Sumpor',
      },
      buildings: {
        townHall: 'Gradska vječnica',
        palace: 'Palača',
        palaceColony: 'Guvernerova palača',
        tavern: 'Taverna',
        museum: 'Muzej',
        academy: 'Akademija',
        workshop: 'Radionica',
        temple: 'Hram',
        embassy: 'Veleposlanstvo',
        warehouse: 'Skladište',
        dump: 'Depo',
        port: 'Trgovačka luka',
        branchOffice: 'Market',
        wall: 'Zid',
        safehouse: 'Sklonište',
        barracks: 'Barake',


        shipyard: 'Brodogradilište',
        forester: 'Lugarova kuća',
        carpentering: 'Stolarija',
        winegrower: 'Vinarija',
        vineyard: 'Vinska preša',
        stonemason: 'Klesar',
        architect: 'Arhitektov ured',
        glassblowing: 'Staklarnica',
        optician: 'Optičar',
        alchemist: 'Alkemičarev toranj',
        fireworker: 'Radionica vatrometa',
      },
      units: {
        phalanx: 'Kopljanik',
        steamgiant: 'Željezni Div',
        spearman: 'Bacač koplja',
        swordsman: 'Mačevalac',
        slinger: 'Praćkar',
        archer: 'Strijelac',
        marksman: 'Sumforni Mušketar',
        ram: 'Ovan',
        catapult: 'Katapult',
        mortar: 'Minobacač',
        gyrocopter: 'Girokopter',
        bombardier: 'Balloon Bombarder',
        cook: 'Kuhar',
        medic: 'Doktor',
        
        ship_ram: 'Brod Ovan', 
        ship_flamethrower: 'Vatreni Brod',
        ship_steamboat: 'Parni Ovan', 
        ship_ballista: 'Brod Kopljar', 
        ship_catapult: 'Brod Katapult', 
        ship_mortar: 'Brod Minobacač', 
        ship_submarine: 'Podmornica',
        ship_paddlespeedship: 'Parni gliser',
        ship_ballooncarrier: 'Nosač balona',
        ship_tender: 'Tender',
        ship_rocketship: 'Raketni brod',
      },
      alerts: {
        building_upgrade_complete: 'Nadogradnja zgrade završena',
        building_upgrade_complete_text: '%{building} u %{city} nadograđena na nivo %{level}',
        
        mission_update: 'Izvještaj misije',
        
        loading: 'utovar %{type} završio u gradu %{city}',
        en_route: '%{type} je stigao u grad %{city}',
        returning: '%{type} se vratio u grad %{city}',
        
        deployarmy: 'Trupe stacionirane',
        deploynavy: 'Flota stacionirana',
        plunder: 'Pljačka',
        transport: 'Transport',
      },
      settings: {
        general: 'Općenito',
        language: 'Jezik',
      
        overviews: 'Pregledi',
        
        tweaks: 'Podešavanja',
        auto_accept_daily_bonus: 'Automatski dodijeli dnevni bonus',
        hide_ads: 'Sakrij oglase',
        hide_facebook: 'Sakrij Facebook gumb',
        hide_friends_bar: 'Sakrij popis prijatelja',
        hide_chat: 'Sakrij chat',
        transport_buttons: 'Dodaj gumbe za transport: -500, +500, +1k, +5k',
        donation_buttons: 'Dodaj gumbe za donacije: +1k, +10k, +100k',
        
        alerts: 'Obavijesti',
        do_test: 'Test',
        test_desktop_alert: 'Test za obavijesti radne površine',
        test_desktop_alert_title: 'Testna obavijest',
        test_desktop_alert_text: 'Uspješno ste obaviješteni!  Kliknite za zatvaranje.',
        desktop_alerts_not_supported: 
             'Vaš preglednik ne podržava obavijesti radne površine.  Možete pokušati sa HTML obavijestima' + 
             'radnog stola za Firefox ' + 
             '(https://addons.mozilla.org/en-us/firefox/addon/html-notifications/) ' + 
             'ili se prebacite na Chrome (www.google.com/chrome/).',
             
        building_completion_alert_desktop: 'Obavijest: nadogradnja zgrade završena',
        transport_loaded_alert_desktop: 'Obavijest: Utovar dobara završio',
        transport_arrived_alert_desktop: 'Obavijest: Transport dobara stigao',
        transport_returned_alert_desktop: 'Obavijest: Brodovi su se vratili iz transporta dobara',
        deploy_army_loaded_alert_desktop: 'Obavijest: Trupe za stacioniranje su se ukrcale',
        deploy_army_arrived_alert_desktop: 'Obavijest: Trupe stacionirane',
        deploy_army_returned_alert_desktop: 'Obavijest: Trupe su se vratile',
        deploy_navy_arrived_alert_desktop: 'Obavijest: Flota stigla na odredište',
        deploy_navy_returned_alert_desktop: 'Obavijest: Flota se vratila',
        pillage_loaded_alert_desktop: 'Obavijest: Jedinice za pljačku ukrcane',
        pillage_arrived_alert_desktop: 'Obavijest: Pljačka stigla na odredište',
        pillage_returned_alert_desktop: 'Obavijest: Brodovi su se vratili iz pljačke',
      },
    },
    de: {
      misc: {
        upkeep: "Unterhalt",
        growth: "Wachstum",
        trade_good: "Handelsgüter",
        city_name: "Stadt",
        action_points: "Aktionspunkte",
        actions: "Aktionen",
        research: "Forschung",
        building_spots: "freie Bauplätze",

        constructing: "im Bau befindlich",
        summary: "Summe:",

        population: "Bevölkerung",
        population_growth: "Wachstum",

        resources: 'Ressourcen',
        buildings: 'Gebäude',
        military: 'Militär',

        resource_overview: 'Ressourcenübersicht',
        buildings_overview: 'Gebäudeübersicht',
        military_overview: 'Militärübersicht',

        resource_cost: 'Kosten',
        next_level_cost: 'Kosten nächstes Level',
        missing: 'fehlt',

        full: 'voll',
        time_to_full: 'bis voll',
        time_to_empty: 'bis leer',

        maximum_capacity: 'Kapazität',
        safe_capacity: 'Sicher',
        employed: 'Forscher',

        satisfaction: 'Zufriedenheit',
        tavern_wine_serving_level: 'Tavernen Level',
        cultural_goods: 'Kulturgüter',

        units: 'Einheiten',
        training: 'Ausbildung',
        deploying: 'im Einsatz',
        plundering: 'Plünderung',

        in_transit: 'Transport',
      },
      tweaks: {
        transport_minus_500: '-',
        transport_plus_500: '+500',
        transport_plus_1000: '+1k',
        transport_plus_5000: '+5k',

        transport_minus_500_text: 'Entferne 500 Waren',
        transport_plus_500_text: 'Addiere 500 Waren',
        transport_plus_1000_text: 'Addiere 1000 Waren',
        transport_plus_5000_text: 'Addiere 5000 Waren',

        donate_plus_1000: '+1k',
        donate_plus_10000: '+10k',
        donate_plus_100000: '+100k',

        donate_plus_1000_text: 'Addiere 1000 Holz zur Spende',
        donate_plus_10000_text: 'Addiere 10000 Holz zur Spende',
        donate_plus_100000_text: 'Addiere 100000 Holz zur Spende',

      },
      actions: {
        deploy_army: 'Armee hier her verlegen',
        deploy_navy: 'Kriegsschiffe hier her verlegen',
        transport_goods: 'Waren hier her transportieren',
        to_town_hall: 'gehe ins Rathaus',
        to_city_view: 'zeige Stadtansicht',
        to_barracks: 'gehe zur Kaserne',
        to_shipyard: 'gehe zur Werft',
      },
      resources: {
        wood: 'Holz',
        wine: 'Wein',
        marble: 'Mamor',
        glass: 'Kristall',
        sulfur: 'Schwefel',
      },
      buildings: {
        townHall: 'Rathaus',
        palace: 'Palast',
        palaceColony: 'Stadthaltersitz',
        tavern: 'Taverne',
        museum: 'Museum',
        academy: 'Akademie',
        workshop: 'Erfinderwerkstatt',
        temple: 'Tempel',
        embassy: 'Botschaft',
        warehouse: 'Lagerhaus',
        dump: 'Halde',
        port: 'Handelshafen',
        branchOffice: 'Kontor',
        wall: 'Mauer',
        safehouse: 'Versteck',
        barracks: 'Kaserne',
        shipyard: 'Kriegswerft',
        forester: 'Forsthaus',
        carpentering: 'Zimmerei',
        winegrower: 'Winzerei',
        vineyard: 'Taverne',
        stonemason: 'Steinmetz',
        architect: 'Architekt',
        glassblowing: 'Glasbläser',
        optician: 'Optiker',
        alchemist: 'Alchimistenturm',
        fireworker: 'Feuerwerksplatz',  
      },
      units: {
        phalanx: 'Hoplit',
        steamgiant: 'Dampfgigant',
        spearman: 'Speerträger',
        swordsman: 'Schwertkämpfer',
        slinger: 'Steinschleuderer',
        archer: 'Bogenschütze',
        marksman: 'Schwefelbüchsenschütze',
        ram: 'Rammbock',
        catapult: 'Katapult',
        mortar: 'Mörser',
        gyrocopter: 'Gyrocopter',
        bombardier: 'Balloon-Bombadier',
        cook: 'Koch',
        medic: 'Doktor',

        ship_ram: 'Rammschiff', 
        ship_flamethrower: 'Feuerschiff',
        ship_steamboat: 'Dampframme', 
        ship_ballista: 'Ballistaschiff', 
        ship_catapult: 'Katapultschiff', 
        ship_mortar: 'Mörserschiff', 
        ship_submarine: 'Tauchboot',
        ship_paddlespeedship: 'Schaufelschnellboot',
        ship_ballooncarrier: 'Ballonträger',
        ship_tender: 'Tender',
        ship_rocketship: 'Raketenschiff',
      },
      alerts: {
        building_upgrade_complete: 'Gebäudeausbau abgeschlossen',
        building_upgrade_complete_text: '%{building} in %{city} ausgebaut auf Stufe %{level}',

        mission_update: 'Mission update',

        loading: '%{type} ist fertig mit beladen in %{city}',
        en_route: '%{type} ist angekommen in %{city}',
        returning: '%{type} ist zurück gekommen nach %{city}',

        deployarmy: 'Armeeaufträge',
        deploynavy: 'Flottenaufträge',
        plunder: 'Plündern',
        transport: 'Transport',

      },
      settings: {
        general: 'Allgemein',
        language: 'Sprache',
      
        overviews: 'Übersichten',
        
        tweaks: 'Sonstiges',
        auto_accept_daily_bonus: 'Automatisches senden des täglichen Login-Bonus',
        hide_ads: 'Werbung ausblenden',
        hide_facebook: 'Facbookbutton ausblenden',
        hide_friends_bar: 'Freundesliste ausblenden',
        hide_chat: 'Chat ausblenden',
        transport_buttons: 'Aanzeige Transport Buttons: -500, +500, +1k, +5k',
        donation_buttons: 'Anzeige Spende Buttons: +1k, +10k, +100k',

        alerts: 'Alarm',
        do_test: 'Test',
        test_desktop_alert: 'Test Desktop Benachrichtigung',
        test_desktop_alert_title: 'Test Benachrichtigung',
        test_desktop_alert_text: 'Test erfogreich!  Klicke hier zum beenden.',
        desktop_alerts_not_supported:
             'Desktop Alarm wird von deinem Browser nicht unterstützt. Versuche HTML Desktop' +
             'Benachrichtigungserweiterung für Firefox ' +
             '(https://addons.mozilla.org/de/firefox/addon/html-notifications/) ' +
             'oder wechsle zu Chrome (www.google.com/chrome/).',

       building_completion_alert_desktop: 'Benachrichtigung: Gebäudeausbau abgeschlossen',
       transport_loaded_alert_desktop: 'Benachrichtigung: Transport Mission beladen',
       transport_arrived_alert_desktop: 'Benachrichtigung: Transport Mission angekommen',
       transport_returned_alert_desktop: 'Benachrichtigung: Transport Mission zurück gekommen',
       deploy_army_loaded_alert_desktop: 'Benachrichtigung: eingesetzte Armee beladen',
       deploy_army_arrived_alert_desktop: 'Benachrichtigung: eingesetzte Armee angekommen',
       deploy_army_returned_alert_desktop: 'Benachrichtigung: eingesetzte Armee zurück gekommen',
       deploy_navy_arrived_alert_desktop: 'Benachrichtigung: eingesetzte Flotte angekommen',
       deploy_navy_returned_alert_desktop: 'Benachrichtigung: eingesetzte Flotte zurück gekommen',
       pillage_loaded_alert_desktop: 'Benachrichtigung: Plündergut beladen',
       pillage_arrived_alert_desktop: 'Benachrichtigung: Plündergut angekommen',
       pillage_returned_alert_desktop: 'Benachrichtigung: Plündergut zurück gekommen',

       debug: 'Debug',
      },
    },
    es: {
      misc: {
        resource_overview: 'Tabla de recursos',
        buildings_overview: 'Tabla de edificios',
        military_overview: 'Tabla Militar',

        upkeep: "Mantenimiento",
        growth: "Crecimiento",
        trade_good: "Bien de Lujo",
        city_name: "Ciudad",
        action_points: "Puntos de accion",
        actions: "Accion",
        research: "Investigacion",
        building_spots: "Lugares disponibles",
        constructing: "Construyendo",
        summary: "Resumen:",

        population: "Poblacion",
        population_growth: "Crecimiento",

        resources: 'Recursos',
        buildings: 'Edificios',
        military: 'Militar',

        resource_overview: 'Resumen de recursos',
        buildings_overview: 'Resumen de edificios',
        military_overview: 'Resumen Militar',

        resource_cost: 'Costos',
        next_level_cost: 'Costos Proximo nivel',
        missing: 'Faltante',

        full: 'Lleno',
        time_to_full: 'Tiempo para llenar',
        time_to_empty: 'Tiempo para vaciar',

        maximum_capacity: 'Capacidad',
        safe_capacity: 'Seguro',
        employed: 'Empleado',

        satisfaction: 'Satisfaccion',
        tavern_wine_serving_level: 'Vino servido',
        cultural_goods: 'Bienes Culturales',

        units: 'Unidades',
        training: 'Entrenando',
        deploying: 'Desplegando',
        plundering: 'Saqueando',

        in_transit: 'En transito',
      },
      tweaks: {
        transport_minus_500: '-500',
        transport_plus_500: '+500',
        transport_plus_1000: '+1k',
        transport_plus_5000: '+5k',
        transport_minus_500_text: 'reduce 500',
        transport_plus_500_text: 'Aumenta 500',
        transport_plus_1000_text: 'Aumenta 1000',
        transport_plus_5000_text: 'Aumenta 5000',
        donate_plus_1000: '+1k',
        donate_plus_10000: '+10k',
        donate_plus_100000: '+100k',
        donate_plus_1000_text: 'Aumenta 1000',
        donate_plus_10000_text: 'Aumenta 10000',
        donate_plus_100000_text: 'Aumenta 100000',
        },
        actions: {
        deploy_army: 'Desplegar Tropas',
        deploy_navy: 'Despplegar Flotas',
        transport_goods: 'Transportar Bienes',
        to_town_hall: 'ir a la intendencia',
        to_city_view: 'ver ciudad',
        to_barracks: 'ir al cuartel',
        to_shipyard: 'ir al astillero',
      },
      resources: {
        wood: 'Madera',
        wine: 'Vino',
        marble: 'Marmol',
        glass: 'Cristal',
        sulfur: 'Azufre',
      },
      buildings: {
        townHall: 'Intendencia',
        palace: 'Palacio',
        palaceColony: 'Residencia del Gobernador',
        tavern: 'Taberna',
        museum: 'Museo',
        academy: 'Academia',
        workshop: 'Taller de mejoras',
        temple: 'Templo',
        embassy: 'Embajada',
        warehouse: 'Deposito',
        dump: 'Vertedero',
        port: 'Puerto',
        branchOffice: 'Tienda',
        wall: 'Muralla',
        safehouse: 'Escondite',
        barracks: 'Cuartel',
        shipyard: 'Astillero',
        forester: 'Cabaña del guardabosques',
        carpentering: 'Carpinteria',
        winegrower: 'Vinicultor',
        vineyard: 'Prensa de Vino',
        stonemason: 'Cantero',
        architect: 'Oficina del arquitecto',
        glassblowing: 'Soplador de Vidrio',
        optician: 'Optica',
        alchemist: 'Alquimista',
        fireworker: 'Zona de pruebas pirotecnicas',
      },
      units: {
        phalanx: 'Hoplita',
        steamgiant: 'Gigante a vapor',
        spearman: 'Lancero',
        swordsman: 'Espadachin',
        slinger: 'Hondero',
        archer: 'Arquero',
        marksman: 'Fusilero',
        ram: 'Ariete',
        catapult: 'Catapulta',
        mortar: 'Mortero',
        gyrocopter: 'Gyrocoptero',
        bombardier: 'Bombardero',
        cook: 'Cocinero',
        medic: 'Medico',
        ship_ram: 'Barco Espolon',
        ship_flamethrower: 'Barco Lanzallamas',
        ship_steamboat: 'Barco Espolon a vapor',
        ship_ballista: 'Barco Ballesta',
        ship_catapult: 'Barco Catapulta',
        ship_mortar: 'Barco mortero',
        ship_submarine: 'Submarino',
        ship_paddlespeedship: 'Lancha de palas',
        ship_ballooncarrier: 'Porta-Globos',
        ship_tender: 'Barco de mantenimiento',
        ship_rocketship: 'Barco lanza-misiles',
      },
      alerts: {
        building_upgrade_complete: 'Expansion de edificio completa',
        building_upgrade_complete_text: '%{building} nivel %{level} completado(a) en%{city}',
        mission_update: 'Actualizar Mision',
        loading: 'Carga %{type} completa en %{city}',
        en_route: '%{type} en camino a %{city}',
        returning: '%{type} retornando desde %{city}',
        deployarmy: 'Desplegando tropas',
        deploynavy: 'Desplegando Flotas',
        plunder: 'Saquear',
        transport: 'Transportar',
      },
      settings: {
        general: 'Optciones generales',
        language: 'Idioma',
        overviews: 'Tablas',
        tweaks: 'Ajustes',
        auto_accept_daily_bonus: 'Aceptar automaticamente el bono diario',
        hide_ads: 'Ocultar Publicidad',
        hide_facebook: 'Ocultar Facebook',
        hide_friends_bar: 'Ocultar barra de amigos',
        hide_chat: 'Ocultar chat',
        transport_buttons: 'Botones de transporte: -500, +500, +1k, +5k',
        donation_buttons: 'Botones para donaciones: +1k, +10k, +100k',
        alerts: 'Alertas',
        do_test: 'Probar',
        test_desktop_alert: 'Notificacion en el escritorio',
        test_desktop_alert_title: 'Titulo de la notificacion',
        test_desktop_alert_text: 'Mensaje de la notificacion.',
        building_completion_alert_desktop: 'Alerta: Ampliacion de edificio completa',
        transport_loaded_alert_desktop: 'Alerta: Carga completa',
        transport_arrived_alert_desktop: 'Alerta: Transporte arribó',
        transport_returned_alert_desktop: 'Alerta: trasnsporte volvió',
        deploy_army_loaded_alert_desktop: 'Alerta: Carga de Tropas completa',
        deploy_army_arrived_alert_desktop: 'Alerta: Tropas desplegadas',
        deploy_army_returned_alert_desktop: 'Alerta: Retorno de tropas',
        deploy_navy_arrived_alert_desktop: 'Alerta: Flotas desplegadas',
        deploy_navy_returned_alert_desktop: 'Alerta: Retorno de Flotas',
        pillage_loaded_alert_desktop: 'Alerta: Cargando saqueo',
        pillage_arrived_alert_desktop: 'Alerta: Saqueo en curso',
        pillage_returned_alert_desktop: 'Alerta: Retorno del saqueo',
        debug: 'Debug',
      },
    },
    fr: {
      misc: {
        resource_overview: 'Vue générale des Ressources',
        buildings_overview: 'Vue générale des Bâtiments',
        military_overview: 'Vue générale des Troupes',

        upkeep: "Entretien",
        growth: "Croissance",
        trade_good: "Trade Good",
        city_name: "Cité",
        action_points: "Points d'Action",
        actions: "Actions",
        research: "Recherche",
        building_spots: "Emplacement de Construction",

        constructing: "En cours de construction",
        summary: "Résumé:",

        population: "Population",
        population_growth: "Croissance",

        resources: 'Ressources',
        buildings: 'Bâtiments',
        military: 'Armée',

        resource_overview: 'Vue générale des Ressources',
        buildings_overview: 'Vue générale des Bâtiments',
        military_overview: 'Vue générale des Troupes',

        resource_cost: 'Coût',
        next_level_cost: 'Coût du prochain niveau',
        missing: 'Manquant',

        full: 'Plein',
        time_to_full: 'Jusqu\'au maximum',
        time_to_empty: 'Jusqu\'au minimum',

        maximum_capacity: 'Capacité',
        safe_capacity: 'Sécurisé',
        employed: 'Utilisé',

        satisfaction: 'Satisfaction',
        tavern_wine_serving_level: 'Niveau de la Taverne',
        cultural_goods: 'Biens Culturels',

        units: 'Unités',
        training: 'Formation',
        deploying: 'Déploiement',
        plundering: 'Pillage',

        in_transit: 'En transit',
      },
      tweaks: {
        transport_minus_500: '-',
        transport_plus_500: '+500',
        transport_plus_1000: '+1k',
        transport_plus_5000: '+5k',

        transport_minus_500_text: 'Enlever 500 unités',
        transport_plus_500_text: 'Ajouter 500 unités',
        transport_plus_1000_text: 'Ajouter 1000 unités',
        transport_plus_5000_text: 'Ajouter 5000 unités',

        donate_plus_1000: '+1k',
        donate_plus_10000: '+10k',
        donate_plus_100000: '+100k',

        donate_plus_1000_text: 'Ajouter 1000 unités de bois en donation',
        donate_plus_10000_text: 'Ajouter 10000 unités de bois en donation',
        donate_plus_100000_text: 'Ajouter 100000 unités de bois en donation',
      },
      actions: {
        deploy_army: 'Déployer Troupes',
        deploy_navy: 'Déployer Flottes',
        transport_goods: 'Transporter des Marchandises',
        to_town_hall: 'Montrer l\'Hôtel de Ville',
        to_city_view: 'Montrer la Ville',
        to_barracks: 'Montrer la Caserne',
        to_shipyard: 'Montrer le Chantier Naval',
      },
      resources: {
        wood: 'Bois',
        wine: 'Vin',
        marble: 'Marbre',
        glass: 'Cristal',
        sulfur: 'Souffre',
      },
      buildings: {
        townHall: 'Hôtel de Ville',
        palace: 'Palais',
        palaceColony: 'Résidence du Gouverneur',
        tavern: 'Taverne',
        museum: 'Musée',
        academy: 'Académie',
        workshop: 'Atelier',
        temple: 'Temple',
        embassy: 'Ambassade',
        warehouse: 'Entrepôt',
        dump: 'Dépôt',
        port: 'Port commercial',
        branchOffice: 'Comptoir',
        wall: 'Mur d\'enceinte',
        safehouse: 'Cachette',
        barracks: 'Caserne',
        shipyard: 'Chantier naval',
        forester: 'Maison Forestière',
        carpentering: 'Menuisier',
        winegrower: 'Pressoir à vin',
        vineyard: 'Cave à vin',
        stonemason: 'Tailleur de pierres',
        architect: 'Bureau de l\'architecte',
        glassblowing: 'Verrier',
        optician: 'Opticien',
        alchemist: 'Tour des alchimistes',
        fireworker: 'Zone de test des artificiers',
      },
      units: {
        phalanx: 'Phalange',
        steamgiant: 'Géant à vapeur',
        spearman: 'Lancier',
        swordsman: 'Epéiste',
        slinger: 'Lance-pierre',
        archer: 'Archer',
        marksman: 'Tireur d`élite',
        ram: 'Bélier',
        catapult: 'Catapulte',
        mortar: 'Mortier',
        gyrocopter: 'Gyrocoptère',
        bombardier: 'Bombardier',
        cook: 'Cuisinier',
        medic: 'Médecin',

        ship_ram: 'Bateau bélier',
        ship_flamethrower: 'Lance-flammes',
        ship_steamboat: 'Bélier à vapeur',
        ship_ballista: 'Bateau Baliste',
        ship_catapult: 'Bateau à catapulte',
        ship_mortar: 'Bateau à mortier',
        ship_submarine: 'Bateau de plongée',
        ship_paddlespeedship: 'Bateau de soutien',
        ship_ballooncarrier: 'Porte-ballons',
        ship_tender: 'Bateau rapide à aubes',
        ship_rocketship: 'Bateau lance-missiles',
      },
      alerts: {
        building_upgrade_complete: 'Expansion du bâtiment terminée',
        building_upgrade_complete_text: '%{building} niveau %{level} terminé(e) à%{city}',

        mission_update: 'Mission mise à jour',

        loading: 'Chargement de %{type} terminé à %{city}',
        en_route: '%{type} sont arrivés à %{city}',
        returning: '%{type} sont retournés à %{city}',

        deployarmy: 'Déploiement de l’Armée',
        deploynavy: 'Déploiement de la Flotte',
        plunder: 'Pillage',
        transport: 'Transport',
      },
      settings: {
        general: 'Options générales',
        language: 'Language',

        overviews: 'Vues',

        tweaks: 'Tweaks',
        auto_accept_daily_bonus: 'Soumettre automatiquement sous forme de bonus quotidien',
        hide_ads: 'Masquer les publicités',
        hide_facebook: 'Masquer le bouton Facebook',
        hide_friends_bar: 'Masquer la barre de contact',
        hide_chat: 'Masquer le chat',
        transport_buttons: 'Ajouter boutons de transport: -500, +500, +1k, +5k',
        donation_buttons: 'Ajouter boutons de donation: +1k, +10k, +100k',

        alerts: 'Alertes',
        do_test: 'Test',
        test_desktop_alert: 'Tester la notification bureau',
        test_desktop_alert_title: 'Tester le titre de la notification',
        test_desktop_alert_text: 'Notification Réussie ! Cliquez pour fermer.',
        desktop_alerts_not_supported: 'Les alertes ne sont pas supportées par votre navigateur. Vous pouvez essayer d\'intégrer l\'add-on HTML-Desktop-Notifications' + 'Notification extension for Firefox ' + '(https://addons.mozilla.org/en-us/firefox/addon/...) ' + 'ou passer à Chrome (www.google.com/chrome/).',

        building_completion_alert_desktop: 'Notification: Expansion du Bâtiment terminée',
        transport_loaded_alert_desktop: 'Notification: Chargement terminé',
        transport_arrived_alert_desktop: 'Notification: Transport terminé',
        transport_returned_alert_desktop: 'Notification: Retour terminé',
        deploy_army_loaded_alert_desktop: 'Notification: Chargement de Troupes terminé',
        deploy_army_arrived_alert_desktop: 'Notification: Troupes déployées',
        deploy_army_returned_alert_desktop: 'Notification: Retour des Troupes',
        deploy_navy_arrived_alert_desktop: 'Notification: Flottes déployées',
        deploy_navy_returned_alert_desktop: 'Notification: Retour des Flottes',
        pillage_loaded_alert_desktop: 'Notification: Chargement pillage',
        pillage_arrived_alert_desktop: 'Notification: Pillage en cours',
        pillage_returned_alert_desktop: 'Notification: Retour du pillage',

        debug: 'Debug',
      },
    },
    hu: {
      misc: {
        resource_overview: 'Nyersanyagok listája',
        buildings_overview: 'Épületek listája',
        military_overview: 'Egységek listája',

        upkeep: "Fenntartási költség",
        growth: "Növekedés",
        trade_good: "Nyersanyagok küldése",
        city_name: "Város",
        action_points: "Műveleti pontok",
        actions: "Műveletek",
        research: "Kutatás",
        building_spots: "Építési helyek",

        constructing: "Építés",
        summary: "Összegzés:",

        population: "Népesség",
        population_growth: "Népesség növekedés",

        resources: 'Nyersanyagok',
        buildings: 'Épületek',
        military: 'Egységek',

        resource_overview: 'Nyersanyagok listája',
        buildings_overview: 'Épületek listája',
        military_overview: 'Egységek listája',

        resource_cost: 'Nyersanyag szükséglet',
        next_level_cost: 'Következős szinthez szükséges',
        missing: 'Hiányzik',

        full: 'Tele',
        time_to_full: 'Tele',
        time_to_empty: 'Üres',

        maximum_capacity: 'Kapacitás',
        safe_capacity: 'Védett',
        employed: 'Tudósok',

        satisfaction: 'Elégedettség',
        tavern_wine_serving_level: 'Fogadó szintje',
        cultural_goods: 'Kulturális egyezmény',

        units: 'Egységek',
        training: 'Képzés',
        deploying: 'Csapat mozgás',
        plundering: 'Fosztás',

        in_transit: 'Szállítás',
      },
      tweaks: {
        transport_minus_500: '-',
        transport_plus_500: '+500',
        transport_plus_1000: '+1k',
        transport_plus_5000: '+5k',

        transport_minus_500_text: 'Elvesz 500 nyersanyagot',
        transport_plus_500_text: 'Hozzáad 500 nyersanyagot',
        transport_plus_1000_text: 'Hozzáad 1000 nyersanyagot',
        transport_plus_5000_text: 'Hozzáad 5000 nyersanyagot',

        donate_plus_1000: '+1k',
        donate_plus_10000: '+10k',
        donate_plus_100000: '+100k',

        donate_plus_1000_text: '1000 fát adományoz',
        donate_plus_10000_text: '10000 fát adományoz',
        donate_plus_100000_text: '100000 fát adományoz',
      },
      actions: {
        deploy_army: 'Katonák küldése',
        deploy_navy: 'Hajók küldése',
        transport_goods: 'Nyersanyagok szállítása',
        to_town_hall: 'Ugrás városházához',
        to_city_view: 'Ugrás a városhoz',
        to_barracks: 'Ugrás a barakkhoz',
        to_shipyard: 'Ugrás a hajógyárhoz',
      },
      resources: {
        wood: 'Fa',
        wine: 'Bor',
        marble: 'Márvány',
        glass: 'Kristály',
        sulfur: 'Kén',
      },
      buildings: {
        townHall: 'Városháza',
        palace: 'Palota',
        palaceColony: 'Helytartó székhelye',
        tavern: 'Fogadó',
        museum: 'Múzeum',
        academy: 'Akadémia',
        workshop: 'Műhely',
        temple: 'Templom',
        embassy: 'Nagykövetség',
        warehouse: 'Raktár',
        dump: 'Depó',
        port: 'Kereskedelmi kikötő',
        branchOffice: 'Kereskedő poszt',
        wall: 'Fal',
        safehouse: 'Rejtekhely',
        barracks: 'Barakk',
        shipyard: 'Hajógyár',
        pirateFortress: 'Kalóz erőd',
        forester: 'Erdész',
        carpentering: 'Ácsmester',
        winegrower: 'Bortermelő',
        vineyard: 'Szőlőprés',
        stonemason: 'Kőműves',
        architect: 'Építész irodája',
        glassblowing: 'Üvegfúvó',
        optician: 'Optikus',
        alchemist: 'Alkimista torony',
        fireworker: 'Tűzszerész',
      },
      units: {
        phalanx: 'Hoplita',
        steamgiant: 'Gőzóriás',
        spearman: 'Dárdás',
        swordsman: 'Kardforgató',
        slinger: 'Parittyás',
        archer: 'Íjász',
        marksman: 'Kén Karabélyos',
        ram: 'Faltörő Kos',
        catapult: 'Katapult',
        mortar: 'Ágyú',
        gyrocopter: 'Gyrokopter',
        bombardier: 'Ballonos-Bombázó',
        cook: 'Séf',
        medic: 'Felcser',

        ship_ram: 'Törő-hajó',
        ship_flamethrower: 'Lánghajó',
        ship_steamboat: 'Gőzkos',
        ship_ballista: 'Balliszta Hajó',
        ship_catapult: 'Katapult Hajó',
        ship_mortar: 'Ágyú Hajó',
        ship_submarine: 'Búvárhajó',
        ship_paddlespeedship: 'Lapátkerekes Gyorshajó',
        ship_ballooncarrier: 'Léghajó hordozó',
        ship_tender: 'Úszó bázis',
        ship_rocketship: 'Rakétás Hajó',
      },
      alerts: {
        building_upgrade_complete: 'Az épület fejlesztése befejeződött',
        building_upgrade_complete_text: 'A(z) %{building}, %{city}-ban/ben fejlesztve lett a(z) %{level}. szintre.',

        mission_update: 'Küldetés Lista',

        loading: '%{type} befejezte a rakodást itt: %{city}',
        en_route: '%{type} megérkezett ide: %{city}',
        returning: '%{type} visszatért ide: %{city}',

        deployarmy: 'Sereg küldés',
        deploynavy: 'Hajó küldés',
        plunder: 'Fosztás',
        transport: 'Szállítás',
      },
      settings: {
        general: 'Általános',
        language: 'Nyelv választás',

        overviews: 'Listák',

        tweaks: 'Egyéb',
        auto_accept_daily_bonus: 'Automatikus napi bónusz elfogadás',
        hide_ads: 'Hírdetések elrejtése',
        hide_facebook: 'Facebook gomb elrejtése',
        hide_friends_bar: 'Barátlista elrejtése',
        hide_chat: 'Chat elrejtése',
        transport_buttons: 'Szállítási gombok hozzáadása: -500, +500, +1k, +5k',
        donation_buttons: 'Adományozás gombok hozzáadása: +1k, +10k, +100k',

        alerts: 'Riasztások',
        do_test: 'Teszt',
        test_desktop_alert: 'Értesítés tesztelése',
        test_desktop_alert_title: 'Teszt értesítés',
        test_desktop_alert_text: 'Sikeres értesítés! Kattincs a bezáráshoz.',
        desktop_alerts_not_supported: 'Az értesítéseket nem támogatja a böngésződ. Próbáld a HTML Desktop ' + 'Notification extension for Firefox ' + '(https://addons.mozilla.org/en-us/firefox/addon/...) ' + 'vagy telepítsd a Chrome-ot (www.google.com/chrome/).',

        building_completion_alert_desktop: 'Értesítés: Épület fejlesztés elkészült',
        transport_loaded_alert_desktop: 'Értesítés: Kereskedő hajók rakodása befejeződött',
        transport_arrived_alert_desktop: 'Értesítés: Kereskedő hajók megérkeztek',
        transport_returned_alert_desktop: 'Értesítés: Kereskedő hajók visszatértek',
        deploy_army_loaded_alert_desktop: 'Értesítés: Egységeid elindultak',
        deploy_army_arrived_alert_desktop: 'Értesítés: Egységeid megérkeztek',
        deploy_army_returned_alert_desktop: 'Értesítés: Egységeid visszatértek',
        deploy_navy_arrived_alert_desktop: 'Értesítés: A hajóid megérkeztek',
        deploy_navy_returned_alert_desktop: 'Értesítés: A hajóid visszatértek',
        pillage_loaded_alert_desktop: 'Értesítés: A fosztogatók elindultak',
        pillage_arrived_alert_desktop: 'Értesítés: A fosztogatás elkezdődött',
        pillage_returned_alert_desktop: 'Értesítés: A fosztogatók visszatértek',

        debug: 'Debug',
      },
    },
    pl: {
      misc: {
        resource_overview: 'Podglad - Zasoby',
        buildings_overview: 'Podglad - Budynki',
        military_overview: 'Podglad - Wojsko',
      
        upkeep: "Utrzymanie",
        growth: "Wzrost",
        trade_good: "Handel",
        city_name: "Miasto",
        action_points: "Punkty Akcji",
        actions: "Akcja",
        research: "Badania",
        building_spots: "Miejsca pod Budowe",

        constructing: "Budowa",
        summary: "Razem:",
        
        population: "Populacja",
        population_growth: "Przyrost",
        
        resources: 'Zasoby',
        buildings: 'Budynki',
        military: 'Wojsko',
        
        resource_overview: 'Podglad: Zasoby',
        buildings_overview: 'Podglad: Budynki',
        military_overview: 'Podglad: Wojsko',
        
        resource_cost: 'Koszt',
        missing: 'Zagubiony',
        
        full: 'Pelno',
        time_to_full: 'Pelno za',
        time_to_empty: 'Pusto za',
        
        maximum_capacity: 'Pojemnosc',
        safe_capacity: 'Bezpieczne',
        employed: 'Zatrudnieni',
        
        satisfaction: 'Zadowolenie',
        tavern_wine_serving_level: 'Poziom Tawerny',
        cultural_goods: 'Dobra Kulturowe',
        
        units: 'Jednostki',
        training: 'Szkolenie',
        deploying: 'Deploying',
        plundering: 'Pladrowanie',
        
        in_transit: 'Transport',
      },
      actions: {
        deploy_army: 'Wyslij Armie',
        deploy_navy: 'Wyslij Flote',
        transport_goods: 'Transport Surowców',
        to_town_hall: 'Ratusz',
        to_city_view: 'Podglad Miasta',
      },
      resources: {
        wood: 'Drewno',
        wine: 'Wino',
        marble: 'Marmur',
        glass: 'Krysztal',
        sulfur: 'Siarka',
      },
      buildings: {
        townHall: 'Ratusz',
        palace: 'Palac',
        palaceColony: 'Rezydencja Gubernatora',
        tavern: 'Tawerna',
        museum: 'Muzeum',
        academy: 'Akademia',
        workshop: 'Warsztat',
        temple: 'Swiatynia',
        embassy: 'Ambasada',
        warehouse: 'Magazyn',
        dump: 'Skladowisko',
        port: 'Port',
        branchOffice: 'Bazar',
        wall: 'Mur',
        safehouse: 'Kryjówka',
        barracks: 'Koszary',
        shipyard: 'Stocznia',
        forester: 'Lesniczówka',
        carpentering: 'Ciesla',
        winegrower: 'Winnica',
        vineyard: 'Tlocznia Win',
        stonemason: 'Kamieniarz',
        architect: 'Architekt',
        glassblowing: 'Huta Szkla',
        optician: 'Optyk',
        alchemist: 'Alchemik',
        fireworker: 'Pirotechnik',
      },
      units: {
        phalanx: 'Hoplita',
        steamgiant: 'Gigant Parowy',
        spearman: 'Oszczepnik',
        swordsman: 'Wojownik',
        slinger: 'Procarz',
        archer: 'Lucznik',
        marksman: 'Strzelec',
        ram: 'Taran',
        catapult: 'Katapulta',
        mortar: 'Mozdzierz',
        gyrocopter: 'Zyrokopter',
        bombardier: 'Balonowy Bombardier',
        cook: 'Kucharz',
        medic: 'Medyk',
        
        ship_ram: 'Taran', 
        ship_flamethrower: 'Miotacz Ognia',
        ship_steamboat: 'Taran Parowy', 
        ship_ballista: 'Balista', 
        ship_catapult: 'Okret z Katapulta', 
        ship_mortar: 'Okret z Mozdzierzem', 
        ship_submarine: 'Okret Podwodny',
        ship_paddlespeedship: 'Smigacz z Napedem Kolowym',
        ship_ballooncarrier: 'Balonowiec',
        ship_tender: 'Statek Pomocniczy',
        ship_rocketship: 'Krazownik Rakietowy',
      },
      settings: {
        general: 'Ogólne',
        language: 'Jezyk',
      
        overviews: 'Podglad',
        
        tweaks: 'Ustawienia',
        auto_accept_daily_bonus: 'Automatyczne zatwierdzenie dziennego bonusa',
        hide_ads: 'Ukryj dodatki',
        hide_facebook: 'Ukryj guzik facebook',
        hide_friends_bar: 'Ukryj listę przyjaciól',
        hide_chat: 'Ukryj czat',
        transport_buttons: 'Dodaj przyciski załadunku: -500, +500, +1k, +5k',
        donation_buttons: 'Dodaj przyciski wpłat: +1k, +10k, +100k',
        
        alerts: 'Powiadomienia',
        do_test: 'Test',
        test_desktop_alert: 'Testuj powiadomienia',
        test_desktop_alert_title: 'Test powiadomienia',
        test_desktop_alert_text: 'Test zakończony powodzeniem!  Kliknij aby wyjść',
        desktop_alerts_not_supported: 
             'Twoja przeglądarka nie obsługuje powiadomień.  ' + 
             'Zainstaluj powiadomienia dla Firefox ' + 
             '(https://addons.mozilla.org/en-us/firefox/addon/html-notifications/) ' + 
             'albo przejdź na Chrome (www.google.com/chrome/).',
             
        building_completion_alert_desktop: 'Powiadomienie o ukończeniu modernizacji budynku',
        transport_loaded_alert_desktop: 'Powiadomienie o zakończeniu załadunku towarów',
        transport_arrived_alert_desktop: 'Powiadomienie o przybyciu statków handlowych',
        transport_returned_alert_desktop: 'Powiadomienie o powrocie statków handlowych',
        deploy_army_loaded_alert_desktop: 'Powiadomienie o załadowaniu wojsk',
        deploy_army_arrived_alert_desktop: 'Powiadomienie o przybyciu wojsk',
        deploy_army_returned_alert_desktop: 'Powiadomienie o powrocie wojsk',
        deploy_navy_arrived_alert_desktop: 'Powiadomienie o dopłynięciu okrętów wojennych',
        deploy_navy_returned_alert_desktop: 'Powiadomienie o powrocie okrętów wojennych',
        pillage_loaded_alert_desktop: 'Powiadomienie o grabieży',
        pillage_arrived_alert_desktop: 'Powiadomienie o rozpoczęciu grabieży',
        pillage_returned_alert_desktop: 'Powiadomienie o powrocie z grabieży',
      },
    },
    tr: {
      misc: {
        resource_overview: 'Kaynak Durumu',
        buildings_overview: 'Binaların Durumu',
        military_overview: 'Orduya Bakış',
        espionage_overview: 'Casusluk Sistemi',
      
        upkeep: "Bakım",
        growth: "Büyüme",
        trade_good: "Ticaret",
        city_name: "Şehir",
        action_points: "Aksiyon Puanı",
        actions: "Aksiyonlar",
        research: "Araştırma",
        building_spots: "Bina Noktaları",

        constructing: "İnşaat",
        summary: "Özet:",
        
        population: "Nüfus",
        population_growth: "Büyüme",
        
        resources: 'Kaynaklar',
        buildings: 'Binalar',
        military: 'Ordu',
        espionage: 'Casusluk',
        
        resource_overview: 'Kaynak Durumu',
        buildings_overview: 'Binaların Durumu',
        military_overview: 'Orduya Bakış',
        
        resource_cost: 'Maliyet',
        next_level_cost: 'Sonraki Seviye Maliyeti',
        missing: 'Kayıp',
        
        full: 'Dolu',
        time_to_full: 'Dolacak',
        time_to_empty: 'Boşalacak',
        
        maximum_capacity: 'Kapasite',
        safe_capacity: 'Korunan',
        employed: 'Mevcut',
        
        satisfaction: 'Memnuniyet',
        tavern_wine_serving_level: 'Taverna Seviyesi',
        cultural_goods: 'Kültürel Ürünler',
        
        units: 'Birimler',
        training: 'Eğitimde',
        deploying: 'Dağılmış',
        plundering: 'Seferde',
        
        in_transit: 'Yüklenen',
        none: 'Yok',
      },
      tweaks: {
        transport_minus_500: '-',
        transport_plus_500: '+500',
        transport_plus_1000: '+1k',
        transport_plus_5000: '+5k',
        
        transport_minus_500_text: '-500',
        transport_plus_500_text: '+500',
        transport_plus_1000_text: '+1000',
        transport_plus_5000_text: '+5000',
        
        donate_plus_1000: '+1k',
        donate_plus_10000: '+10k',
        donate_plus_100000: '+100k',
        
        donate_plus_1000_text: '+1000',
        donate_plus_10000_text: '+10000',
        donate_plus_100000_text: '+100000',
        
        completely_demolish_building_prompt: 'Bu binayı tamamen yıkmak istiyor musunuz?',
        destroy_non_mobile_colony_prompt: 
            'Mobil olmayan koloninin yıkımı "Ikariam Imperator" tarafından bloke edildi!  Eğer gerçekten ' +
            'bu şehri yıkmak istiyorsanız, önce "Ikariam Imperator" şeçeneklerindeki koruma ' +
            'seçeneğini kapatınız.',
      },
      actions: {
        deploy_army: 'Asker Gönder',
        deploy_navy: 'Gemi Gönder',
        transport_goods: 'Malzeme Gönder',
        to_town_hall: 'Belediye Binasına Git',
        to_city_view: 'Şehir Görünümü',
        to_island_view: 'Ada Görünümü',
        to_barracks: 'Kışla',
        to_shipyard: 'Tersane',
        spy_mission: 'Görev Seç',
        blockade: 'Limanı Fethet',
        pillage: 'Yağmala',
        occupy: 'Şehri İşgalet',
        send_spy: 'Casus Yolla',
        view_high_score: 'Puan Bilgileri',
        view_alliance_page: 'İttifak Sayfasına Bak',
      },
      resources: {
        wood: 'Odun',
        wine: 'Üzüm',
        marble: 'Mermer',
        glass: 'Kristal',
        sulfur: 'Sülfür',
      },
      buildings: {
        townHall: 'Belediye',
        palace: 'Saray',
        palaceColony: 'Valilik',
        tavern: 'Taverna',
        museum: 'Müze',
        academy: 'Akademi',
        workshop: 'Mucit Atölyesi',
        temple: 'Tapınak',
        embassy: 'Büyük Elçilik',
        warehouse: 'Depo',
        dump: 'Yığın Sahası',
        port: 'Ticaret Limanı',
        branchOffice: 'Ticaret Merkezi',
        wall: 'Sur',
        safehouse: 'İstihbarat Merkezi',
        barracks: 'Kışla',
        shipyard: 'Donanma Tersanesi',
        pirateFortress: 'Korsan Kalesi',
        forester: 'Ormancı Kulübesi',
        carpentering: 'Marangoz Atölyesi',
        winegrower: 'Bağ Evi',
        vineyard: 'Şarap Mahzeni',
        stonemason: 'Mermer Atölyesi',
        architect: 'Mimarlık Bürosu',
        glassblowing: 'Cam Eşya Atölyesi',
        optician: 'Optician',
        alchemist: 'Simya Kulesi',
        fireworker: 'Fişekçi',
      },
      units: {
        phalanx: 'Hoplit',
        steamgiant: 'Buhar Devi',
        spearman: 'Mızrakçı',
        swordsman: 'Kılıççı',
        slinger: 'Slinger',
        archer: 'Okçu',
        marksman: 'Sülfür Tüfekçisi',
        ram: 'Şahmerdan',
        catapult: 'Mancınık',
        mortar: 'Topçu',
        gyrocopter: 'Gyrokopter',
        bombardier: 'Balon Bombardımancısı',
        cook: 'Aşçı',
        medic: 'Doktor',
        
        ship_ram: 'Şahmerdan Gemisi', 
        ship_flamethrower: 'Alev Gemisi',
        ship_steamboat: 'Buharlı Şahmerdan', 
        ship_ballista: 'Ballista Ship', 
        ship_catapult: 'Mancınık Gemisi', 
        ship_mortar: 'Havantopu Gemisi', 
        ship_submarine: 'Diving Boat',
        ship_paddlespeedship: 'Süratli Kürekbotu',
        ship_ballooncarrier: 'Balon Taşıyıcı',
        ship_tender: 'Tender',
        ship_rocketship: 'Füze Gemisi',
      },
      alerts: {
        building_upgrade_complete: 'Bina inşaası tamamlandı',
        building_upgrade_complete_text: '%{city} şehrindeki %{building} binası %{level} seviyeye yükseltildi.',
        
        mission_update: 'Görev Güncelleştirme',
        
        loading: '%{city} şehrindeki %{type} yüklemesi tamamlandı',
        en_route: '%{type} has arrived in %{city}',
        returning: '%{type} has returned to %{city}',
        
        deployarmy: 'Asker Gönderme',
        deploynavy: 'Donanma Gönderme',
        plunder: 'Yağmala',
        transport: 'Transport',
      },
      espionage: {
        player: 'Oyuncu',
        townhall_level: 'Belediye Seviyesi',
        wall_level: 'Sur Seviyesi',
        travel_time: 'Varış Zamanı',
        resources_lootable: 'Lootable',
        resources_looted: 'Looted',
        combats: 'Savaşlar',
        military_score: 'General Puanı',
        location: 'Koordinat',
        view_island: 'Ada Görünümü',
        occupied_by: 'İşgalde',
        blockaded_by: 'Limanı İşgalde',
        time_since: 'beri',
        remove_target: 'Listeden Çıkar',
      },
      settings: {
        general: 'Genel',
        language: 'Dil',
      
        overviews: 'Genel Bakış',
        
        tweaks: 'Tweaks',
        auto_accept_daily_bonus: 'Günlük Bonusları otomatik onayla',
        hide_ads: 'Reklamları gizle',
        hide_facebook: 'Facebook butonunu gizle',
        hide_friends_bar: 'Arkadaşlar çubuğunu gizle',
        hide_chat: 'Sohbeti gizle',
        transport_buttons: 'Add transport buttons: -500, +500, +1k, +5k',
        donation_buttons: 'Add donation buttons: +1k, +10k, +100k',
        show_city_owners: 'Şehir adının yanında şehir sahibi göster (ada görünümünde)',
        prevent_accidental_colony_destruction: 'Mobil olmayan kolonilerin imhasını önle',
        initialize_colonization_missions_for_pirate_raiding: 
            'Ahşap ve mermer ile seviye 1 korsan kale inşa etmek ve kolonizasyon misyonları başlatmak için maksimum taslak hızı kullanın',
        
        alerts: 'Bildirimler',
        do_test: 'Test',
        test_desktop_alert: 'Masaüstü bildirimlerini test et',
        test_desktop_alert_title: 'Test Bildirimi',
        test_desktop_alert_text: 'Bildirim başarılı! Kapatmak için tıklayın.',
        desktop_alerts_not_supported: 
             'Masaüstü bildirimleri tarayıcınız tarafından desteklenmiyor.  You can try the HTML Desktop' + 
             'Firefox için bir HTML masaüstü bildirim uzantısı indirin ' + 
             '(https://addons.mozilla.org/en-us/firefox/addon/html-notifications/) ' + 
             'veya Chrome\'dan giriş yapın (www.google.com/chrome/).',
             
        building_completion_alert_desktop: 'Bina yükseltmesi tamamlandı',
        transport_loaded_alert_desktop: 'Kaynaklar yüklendi',
        transport_arrived_alert_desktop: 'Kaynaklar hedefe vardı',
        transport_returned_alert_desktop: 'Nakliye gemileri geri döndü',
        deploy_army_loaded_alert_desktop: 'Ordu yüklendi',
        deploy_army_arrived_alert_desktop: 'Ordu hedefe vardı',
        deploy_army_returned_alert_desktop: 'Ordu geri döndü',
        deploy_navy_arrived_alert_desktop: 'Donanma hedefe vardı',
        deploy_navy_returned_alert_desktop: 'Donanma geri döndü',
        pillage_loaded_alert_desktop: 'Yağma yüklendi',
        pillage_arrived_alert_desktop: 'Yağma geldi',
        pillage_returned_alert_desktop: 'Yağma geri döndü',
        
        debug: 'Debug',
      },
    },
  };
  var localizer = new IkaTools.Intl.Localizer(localizations);
  
  function addStyles() {
    GM_addStyle('\
      /*-------------------------main board ----------------------*/ \
\
      .imperator_overview { \
        //width: 990px; \
        //margin: 0 auto; \
        //padding: 15px 0; \
      } \
\
      .imperator_overview.ltr, \
      .imperator_overview.ltr * { \
        direction: ltr; \
      } \
\
      .imperator_overview.rtl, \
      .imperator_overview.rtl * { \
        direction: rtl; \
      } \
\
      /*************************************************************/ \
      /* Generic */ \
\
      .nowrap { \
        white-space: nowrap; \
      } \
\
      /*************************************************************/ \
      /* Main overview table formatting */ \
\
      .imperator_overview table.overview { \
        width: 851px !important; \
        margin-bottom: 3px; \
        background-color: #FAF3D7 \
        border-collapse: collapse; \
        border: 1px solid #E4B873; \
        color: #542C0F; \
\
        height: auto; \
        line-height: 12px; \
        font-size: 11px; \
        min-width: 10px; \
        vertical-align: top; \
        text-align: right; \
\
        cursor:default; \
        overflow-x: scroll; \
      } \
\
      .imperator_overview a, \
      .imperator_overview p { \
        line-height: 12px; \
        font-size: 11px; \
      } \
\
      .imperator_overview table.overview tbody tr { \
        min-height: 22px; \
        height: 22px; \
      } \
\
      .imperator_overview table.overview colgroup { \
        border-left: 2px solid #DEC285; \
        border-right: 2px solid #DEC285; \
      } \
\
      .imperator_overview table.overview td { \
        padding: 1px 2px; \
        min-width: 11px; \
      } \
\
      .imperator_overview table.overview tbody td { \
        vertical-align: top; \
      } \
\
      .imperator_overview table.overview col { \
        border-left: 1px dashed #ECCF8E; \
        border-right: 1px dashed #ECCF8E; \
        min-width: 20px; \
      } \
\
      .imperator_overview table.overview col { \
        border-left: 1px dashed #ECCF8E; \
        border-right: 1px dashed #ECCF8E; \
        min-width: 20px; \
      } \
\
      .imperator_overview table.overview col.city_name { \
        border-left: none; \
        text-align: left; \
        width: 95px; \
      } \
\
      .imperator_overview table.overview td.city_name { \
        text-align: left; \
      } \
\
      .imperator_overview table.overview col.city_tradegood { \
        border-right: none; \
        width: 20px; \
      } \
\
      .imperator_overview table.overview td.city_tradegood img { \
        height: 12pt; \
      } \
\
      .imperator_overview table.overview thead { \
        background: #F8E7B3 url(skin/input/button.png) repeat-x scroll 0 bottom; \
      } \
\
      .imperator_overview table.overview tfoot {  \
        background: #E7C680 url(skin/input/button.png) repeat-x scroll 0 0; \
        border-top: 2px solid #CB9B6A; \
        vertical-align: top; \
      } \
\
      .imperator_overview table.overview tbody tr { \
        border-top: 1px solid #ECCF8E; \
      } \
\
      .imperator_overview table.overview tbody tr:nth-child(odd) { \
        background-color: #FAEEC0; \
      } \
\
      .imperator_overview table.overview td.city_name, \
      .imperator_overview table.overview th.city_name { \
        width: 95px; \
        max-width: 95px; \
        overflow: hidden; \
      } \
\
      .imperator_overview table.overview tbody tr.current { \
        background-color: #FAE0BB; \
      } \
\
      .imperator_overview table.overview tbody tr:hover { \
        background-color: #FAF7EB; \
        border:1px solid #CB9B6A; \
      } \
\
      .imperator_overview table.overview tfoot tr {  \
      } \
\
      .imperator_overview table.overview th { \
        height: 22px; \
        width: auto; \
        padding: 1px; \
        padding-bottom: 2px; \
        padding-left: 3px; \
        text-align: center; \
        font-weight: bold; \
      } \
\
      .imperator_overview table.overview th.city_name, \
      .imperator_overview table.overview td.city_name { \
        overflow: hidden; \
      } \
\
      .imperator_overview table.overview td.totals_sigma_cell:after { \
        content: url("skin/layout/sigma.png"); \
      } \
\
      /**************************************************************/ \
      /* Tool tip formatting */ \
\
      .tool_tip_container { \
        background-color: #FAF3D7; \
        border: 1px solid #CB9B6A; \
        font-size: 11px; \
        position: absolute; \
        text-align: left; \
        z-index: 110000; \
        white-space: nowrap; \
      } \
\
      .tool_tip_container * { \
        padding: 2px 3px; \
      } \
\
      .tool_tip_container thead,  \
      .imperator_tool_tip_title { \
        background: #F8E7B3 url("skin/input/button.png") repeat-x scroll 0 bottom; \
        white-space: nowrap; \
        border-bottom: 1px solid #CB9B6A; \
      } \
\
      .tool_tip_container tfoot { \
        background: #E7C680 url("skin/input/button.png") repeat-x scroll 0 0; \
        border-top: 1px solid #CB9B6A; \
      } \
\
      table.building_upgrade_costs { \
        width: 100%; \
      } \
\
      table.building_upgrade_costs td *, \
      table.lootable_resources td *, \
      table.target_military_garrison tfoot td *, \
      table.combat_looted td * { \
        padding: 0px 2px; \
      } \
\
      table.espionage_combats > tbody > tr:nth-child(even), \
      table.travel_time tr:nth-child(even) { \
        background-color: #FAEEC0; \
      } \
\
      table.building_upgrade_costs td.resource_icon img, \
      table.building_upgrade_costs td.resource_missing img, \
      table.lootable_resources td.resource_icon img, \
      table.combat_looted td.resource_icon img { \
        height: 11px; \
      } \
\
      table.resource_use_tool_tip, \
      table.lootable_resources tbody td.resource_lootable, \
      table.target_military_garrison tbody td { \
        text-align: right; \
      } \
\
      table.resource_use_tool_tip col { \
        border-left: 1px dashed #ECCF8E; \
        border-right: 1px dashed #ECCF8E; \
      } \
       \
      table.resource_use_tool_tip col:first-of-type { \
        border-left: none; \
      } \
\
      table.resource_use_tool_tip col:last-of-type { \
        border-right: none; \
      } \
\
      table.building_upgrade_costs td.resource_missing { \
        color: #AA0303; \
        text-align: right; \
      } \
\
      table.building_upgrade_costs td.resource_cost { \
        text-align: right; \
      } \
\
      table.resources_in_transit_tool_tip img, \
      table.resource_use_tool_tip img { \
        padding: 0px 0px; \
        padding-top: 1px; \
      } \
\
      table.resources_in_transit_tool_tip .resource_count, \
      table.training_units_tool_tip .training_count, \
      table.deploying_units_tool_tip .deploying_count  \
      table.plundering_units_tool_tip .plundering_count{ \
        text-align: right; \
      } \
\
      div.combat_type_blockade, \
      div.combat_type_plunder { \
        max-width: 25px; \
        width: 25px; \
        height: 15px; \
        max-height: 15px; \
        background-size: 25px auto; \
        background-position: left top; \
        background-repeat: no-repeat; \
        background-position: 0px 0px; \
      } \
      div.combat_type_blockade { \
        background-image: url("skin/actions/blockade.jpg"); \
      } \
      div.combat_type_plunder { \
        background-image: url("skin/actions/plunder.jpg"); \
      } \
\
      /**************************************************************/ \
      /* Resource table specific formatting */ \
\
      #ImperatorOverviewResourceTable .resource_consumption, \
      #ImperatorOverviewResourceTable .resource_consumption a { \
        font-size: 9px; \
      } \
\
      #ImperatorOverviewResourceTable .resources_transporting { \
        font-size: 9px; \
        line-height: 10px; \
        color: #4455EB; \
      } \
\
      #ImperatorOverviewResourceTable .is_under_safe_limit:before { \
        content: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAJCAYAAAD+WDajAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAEFJREFUeNpi/P//PwMIhOrzQhhAsPriZ0YQzYQugcxnQhaE6YABxhA9HhRdyICJAQ/AayzxOtFdzYRuFLIVAAEGANwqFwuukYKqAAAAAElFTkSuQmCC"); \
        float: left; \
      } \
\
      #ImperatorOverviewResourceTable .resource_current { \
        white-space: nowrap; \
      } \
\
      #ImperatorOverviewResourceTable td.research, \
      #ImperatorOverviewResourceTable td.population, \
      #ImperatorOverviewResourceTable td.population_growth { \
        text-align: center;; \
      } \
\
      #ImperatorOverviewResourceTable td.population_growth_icon img { \
        width: 18px; \
      } \
\
      #ImperatorOverviewResourceTable a.transport_goods, \
      #ImperatorOverviewResourceTable a.to_town_hall, \
      #ImperatorOverviewBuildingsTable a.transport_goods, \
      #ImperatorOverviewBuildingsTable a.to_city_view, \
      #ImperatorOverviewMilitaryTable a.deploy_army, \
      #ImperatorOverviewMilitaryTable a.deploy_navy, \
      #ImperatorOverviewMilitaryTable a.to_barracks, \
      #ImperatorOverviewMilitaryTable a.to_shipyard, \
      #ImperatorOverviewEspionageTable a.spy_mission, \
      #ImperatorOverviewEspionageTable a.pillage_mission, \
      #ImperatorOverviewEspionageTable a.blockade_mission, \
      #ImperatorOverviewEspionageTable a.occupy_mission, \
      #ImperatorOverviewEspionageTable a.send_spy_mission, \
      #ImperatorOverviewEspionageTable a.remove_espionage_target { \
       \
        max-width: 25px; \
        width: 25px; \
        height: 17px; \
        display: inline-block; \
        background-size: 25px auto; \
        background-position: left top; \
        background-repeat: no-repeat; \
        background-position: 0px 0px; \
      } \
\
      #ImperatorOverviewResourceTable a.transport_goods, \
      #ImperatorOverviewBuildingsTable a.transport_goods { \
        background-image: url("skin/actions/transport.jpg"); \
        margin-left: 2px; \
      } \
\
      #ImperatorOverviewResourceTable a.to_town_hall, \
      #ImperatorOverviewBuildingsTable a.to_city_view { \
        background-image: url("skin/layout/icon-city2.png"); \
      } \
\
      #ImperatorOverviewResourceTable a.transport_goods:hover, \
      #ImperatorOverviewBuildingsTable a.transport_goods:hover, \
      #ImperatorOverviewMilitaryTable a.deploy_navy:hover, \
      #ImperatorOverviewMilitaryTable a.deploy_army:hover, \
      #ImperatorOverviewEspionageTable a.pillage_mission:hover, \
      #ImperatorOverviewEspionageTable a.blockade_mission:hover, \
      #ImperatorOverviewEspionageTable a.occupy_mission:hover, \
      #ImperatorOverviewEspionageTable a.send_spy_mission:hover { \
        background-position: 0px -17px; \
      } \
\
      #ImperatorOverviewResourceTable tr.current a.transport_goods, \
      #ImperatorOverviewBuildingsTable tr.current a.transport_goods, \
      #ImperatorOverviewMilitaryTable tr.current a.deploy_navy, \
      #ImperatorOverviewMilitaryTable tr.current a.deploy_army { \
        background-position: 0px -34px; \
      } \
\
      #ImperatorOverviewResourceTable.city_type_deployedCities a.transport_goods, \
      #ImperatorOverviewResourceTable.city_type_occupiedCities a.transport_goods, \
      #ImperatorOverviewBuildingsTable.city_type_deployedCities a.transport_goods, \
      #ImperatorOverviewBuildingsTable.city_type_occupiedCities a.transport_goods { \
        background-position: 0px -34px; \
      } \
\
      .imperator_overview table.overview td.actions { \
        text-align: left; \
      } \
\
      #ImperatorOverviewResourceTable th.actions, \
      #ImperatorOverviewBuildingsTable th.actions, \
      #ImperatorOverviewBuildingsTable td.actions, \
      #ImperatorOverviewMilitaryTable th.actions { \
        width: 52px !important; \
        max-width: 52px !important; \
        min-width: 52px !important; \
      }  \
\
      /************************************************************/ \
      /* Percent bars and warning indications */ \
       \
      .imperator_overview .percent_bar { \
        border-radius: 2px; \
        height: 3px; \
        background-color: !transparent; \
        border: 1px solid #B07D56; \
        overflow: hidden; \
        min-width: 45px; \
        margin-top: 1px; \
      } \
\
      .imperator_overview .percent_bar .percent_bar_active {  \
        height: 100%; \
        border-top-left-radius: 2px; \
        border-bottom-left-radius: 2px; \
        background-color: #481010; \
      } \
\
      .imperator_overview .percent_bar.expiration_forseeable .percent_bar_active { \
        background-color: #7F1D1A; \
      } \
\
      .imperator_overview .percent_bar.expiration_soon .percent_bar_active {  \
        background-color: #B42521; \
      } \
\
      .imperator_overview .percent_bar.expiration_imminent .percent_bar_active, \
      .imperator_overview .percent_bar.expiration_now .percent_bar_active {  \
        background-color: #FF0000; \
      } \
\
      .imperator_overview .percent_bar.percent_bar_desire_filled.percent_bar_filled \
         .percent_bar_active { \
        background-color: #285E28; \
      } \
\
      .imperator_overview .expiration_now, \
      .imperator_overview .expiration_imminent { \
        font-weight: bold; \
        color: red; \
      } \
\
      .imperator_overview .expiration_soon { \
        font-weight: bold; \
        color: #B42521; \
      } \
\
      .imperator_overview .expiration_forseeable { \
        color: #8F1D1A; \
      } \
\
      .imperator_overview .imperator_warning { \
        color: red; \
      } \
\
      /***************************************************************/ \
      /* Buildings table specific formatting */ \
\
      #ImperatorOverviewBuildingsTable tbody td{ \
        vertical-align: middle; \
      } \
\
      #ImperatorOverviewBuildingsTable th {  \
        max-width: 15px; \
        width: 15px; \
        overflow: hidden;  \
        cursor: default; \
        height: 36px; \
      } \
\
      #ImperatorOverviewBuildingsTable td {  \
        width: 15px; \
      } \
      #ImperatorOverviewBuildingsTable th.building[colspan="2"] { max-width: 20px; } \
      #ImperatorOverviewBuildingsTable th.building[colspan="3"] { max-width: 35px;} \
      #ImperatorOverviewBuildingsTable th.building[colspan="4"] { max-width: 45px;} \
      #ImperatorOverviewBuildingsTable th.building[colspan="5"] { max-width: 55px;} \
      #ImperatorOverviewBuildingsTable th.building[colspan="6"] { max-width: 65px;} \
      #ImperatorOverviewBuildingsTable th.building[colspan="7"] { max-width: 75px;} \
      #ImperatorOverviewBuildingsTable th.building[colspan="8"] { max-width: 85px;} \
      #ImperatorOverviewBuildingsTable th.building[colspan="9"] { max-width: 95px;} \
      #ImperatorOverviewBuildingsTable th.building[colspan="10"] { max-width: 100px;} \
      #ImperatorOverviewBuildingsTable th.building[colspan="11"] { max-width: 105px;} \
      #ImperatorOverviewBuildingsTable th.building[colspan="12"] { max-width: 110px;} \
\
\
      #ImperatorOverviewBuildingsTable td.building_upgrading a { \
        font-weight: bold; \
        color: green; \
      } \
\
      #ImperatorOverviewBuildingsTable col.building.building_additional { \
        border-left: none; \
      } \
\
      #ImperatorOverviewBuildingsTable col.building { \
        border-right: none; \
      } \
\
      /**************************************************************/ \
      /* Military table specific formatting */ \
\
      #ImperatorOverviewMilitaryTable thead { \
        height: 36px; \
        cursor: default; \
      } \
\
      #ImperatorOverviewMilitaryTable th { \
        overflow: hidden; \
        max-width: 23px; \
      } \
\
      #ImperatorOverviewMilitaryTable a.deploy_army { \
        background-image: url("skin/actions/move_army.jpg"); \
      } \
\
      #ImperatorOverviewMilitaryTable a.deploy_navy { \
        background-image: url("skin/actions/move_fleet.jpg"); \
        margin-left: 2px; \
      } \
\
      #ImperatorOverviewMilitaryTable a.to_barracks { \
        background-image:url("skin/img/city/barracks_l.png"); \
        background-size: 30px auto; \
        background-position: bottom left; \
      } \
\
      #ImperatorOverviewMilitaryTable a.to_shipyard { \
        background-image:url("skin/img/city/shipyard_l.png"); \
      } \
\
      #ImperatorOverviewMilitaryTable a.to_barracks+a.to_shipyard { \
        margin-left: 2px; \
      } \
\
      #ImperatorOverviewMilitaryTable .military_training { \
        font-size: 9px; \
        line-height: 10px; \
        color: green; \
      } \
\
      #ImperatorOverviewMilitaryTable .military_deploying { \
        font-size: 9px; \
        line-height: 10px; \
        color: #4455EB; \
      } \
\
      #ImperatorOverviewMilitaryTable .military_plundering { \
        font-size: 9px; \
        line-height: 10px; \
        color: #8302A3; \
      } \
      /**************************************************************/ \
      /* Espionage table specific formatting */ \
\
      #ImperatorOverviewEspionageTable td.city_tradegood { \
        width: auto; \
        min-width: 50px; \
        text-align: left; \
      } \
      #ImperatorOverviewEspionageTable td.actions { \
        min-width: 160px; \
      } \
      #ImperatorOverviewEspionageTable a.spy_mission { \
        /*background-image: url("skin/friends/citymenu.png"); \
        background-position: 0px -129px; */\
        background-image: url("skin/layout/icon-mission.png"); \
      } \
      #ImperatorOverviewEspionageTable a.pillage_mission { \
        background-image: url("skin/actions/plunder.jpg"); \
        margin-left: 2px; \
      } \
      #ImperatorOverviewEspionageTable a.blockade_mission { \
        background-image: url("skin/actions/blockade.jpg"); \
        margin-left: 2px; \
      } \
      #ImperatorOverviewEspionageTable a.occupy_mission { \
        background-image: url("skin/actions/occupy.jpg"); \
        margin-left: 2px; \
      } \
      #ImperatorOverviewEspionageTable a.send_spy_mission { \
        background-image: url("skin/actions/espionage.jpg"); \
        margin-left: 2px; \
      } \
      #ImperatorOverviewEspionageTable a.remove_espionage_target { \
        background-image: url("skin/actions/defend.jpg"); \
        background-position: 0px -34px; \
        margin-left: 2px; \
      } \
      #ImperatorOverviewEspionageTable a.player_state_inactive { \
        color: grey; \
      } \
      #ImperatorOverviewEspionageTable a.player_state_vacation { \
        color: green; \
      } \
      #ImperatorOverviewEspionageTable tbody td { \
        vertical-align: middle; \
      } \
      #ImperatorOverviewEspionageTable td.player, \
      #ImperatorOverviewEspionageTable td.location { \
        text-align: left; \
      } \
      .espionage_blockader, \
      .espionage_occupier { \
        margin-left: 1pt; \
        margin-right: 1pt; \
      } \
      .target_military_garrison thead th { \
        height: 36px; \
        cursor: default; \
      } \
      .target_military_garrison th { \
        overflow: hidden; \
        max-width: 23px; \
      } \
      .target_military_garrison th.military { \
        background-size: auto 33px; \
      } \
      .target_military_garrison th.military_phalanx { \
        background-image:url("skin/characters/military/x60_y60/y60_phalanx_faceright.png"); \
      } \
      .target_military_garrison th.military_steamgiant { \
        background-image:url("skin/characters/military/x60_y60/y60_steamgiant_faceright.png"); \
      } \
      .target_military_garrison th.military_spearman { \
        background-image:url("skin/characters/military/x60_y60/y60_spearman_faceright.png"); \
      } \
      .target_military_garrison th.military_swordsman { \
        background-image:url("skin/characters/military/x60_y60/y60_swordsman_faceright.png"); \
      } \
      .target_military_garrison th.military_slinger { \
        background-image:url("skin/characters/military/x60_y60/y60_slinger_faceright.png"); \
      } \
      .target_military_garrison th.military_archer { \
        background-image:url("skin/characters/military/x60_y60/y60_archer_faceright.png"); \
      } \
      .target_military_garrison th.military_marksman { \
        background-image:url("skin/characters/military/x60_y60/y60_marksman_faceright.png"); \
      } \
      .target_military_garrison th.military_ram { \
        background-image:url("skin/characters/military/x60_y60/y60_ram_faceright.png"); \
        background-size: auto 18px; \
      } \
      .target_military_garrison th.military_catapult { \
        background-image:url("skin/characters/military/x60_y60/y60_catapult_faceright.png"); \
        background-size: auto 23px; \
      } \
      .target_military_garrison th.military_mortar { \
        background-image:url("skin/characters/military/x60_y60/y60_mortar_faceright.png"); \
        background-size: auto 22px; \
      } \
      .target_military_garrison th.military_gyrocopter { \
        background-image:url("skin/characters/military/x60_y60/y60_gyrocopter_faceright.png"); \
        background-size: auto 21px; \
      } \
      .target_military_garrison th.military_bombardier { \
        background-image:url("skin/characters/military/x60_y60/y60_bombardier_faceright.png"); \
      } \
      .target_military_garrison th.military_cook { \
        background-image:url("skin/characters/military/x60_y60/y60_cook_faceright.png"); \
      } \
      .target_military_garrison th.military_medic { \
        background-image:url("skin/characters/military/x60_y60/y60_medic_faceright.png"); \
      } \
      .target_military_garrison th.military_ship_flamethrower { \
        background-image:url("skin/characters/fleet/60x60/ship_flamethrower_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_steamboat { \
        background-image:url("skin/characters/fleet/60x60/ship_steamboat_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_ram { \
        background-image:url("skin/characters/fleet/60x60/ship_ram_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_ballista { \
        background-image:url("skin/characters/fleet/60x60/ship_ballista_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_catapult { \
        background-image:url("skin/characters/fleet/60x60/ship_catapult_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_mortar { \
        background-image:url("skin/characters/fleet/60x60/ship_mortar_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_submarine { \
        background-image:url("skin/characters/fleet/60x60/ship_submarine_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_paddlespeedship { \
        background-image:url("skin/characters/fleet/60x60/ship_paddlespeedship_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_ballooncarrier { \
        background-image:url("skin/characters/fleet/60x60/ship_ballooncarrier_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_tender { \
        background-image:url("skin/characters/fleet/60x60/ship_tender_faceright.png"); \
        background-size: 33px auto; \
      } \
      .target_military_garrison th.military_ship_rocketship { \
        background-image:url("skin/characters/fleet/60x60/ship_rocketship_faceright.png"); \
        background-size: 33px auto; \
      } \
\
      /*****************************************************************/ \
      /* Image styling for table headers */ \
\
      #ImperatorOverviewBuildingsTable th.building, \
      #ImperatorOverviewMilitaryTable th.military, \
      .imperator_overview table.overview th.action_points, \
      #ImperatorOverviewResourceTable th.population, \
      #ImperatorOverviewResourceTable th.population_growth, \
      #ImperatorOverviewResourceTable th.research, \
      #ImperatorOverviewResourceTable th.resource, \
      #ImperatorOverviewEspionageTable th.location, \
      #ImperatorOverviewEspionageTable th.travel_time, \
      #ImperatorOverviewEspionageTable th.townhall_level, \
      #ImperatorOverviewEspionageTable th.wall_level, \
      #ImperatorOverviewEspionageTable th.resources_lootable, \
      #ImperatorOverviewEspionageTable th.combats, \
      #ImperatorOverviewEspionageTable th.military_score, \
      .target_military_garrison th.military \
       { \
        -webkit-user-select: none; \
        -khtml-user-select: none; \
        -moz-user-select: none; \
        -o-user-select: none; \
        user-select: none; \
        cursor: default; \
        color: transparent; \
        background-repeat: no-repeat; \
        background-attachment: center; \
        background-position: center; \
      } \
\
      .imperator_overview table.overview td.action_points, \
      .imperator_overview table.overview th.action_points { \
        max-width: 20px; \
        width: 20px; \
        overflow: hidden; \
      } \
\
      .imperator_overview table.overview th.action_points { \
        background-image:url("skin/resources/icon_actionpoints.png"); \
        max-width: 20px; \
      } \
      .imperator_overview table.overview td.action_points { \
        max-width: 20px; \
      } \
       \
      #ImperatorOverviewResourceTable th.population { \
        background-image:url("skin/resources/icon_population.png"); \
      } \
       \
      #ImperatorOverviewResourceTable th.population_growth { \
        background-image:url("skin/icons/growth_positive.png"); \
      } \
       \
      #ImperatorOverviewResourceTable th.research { \
        background-image:url("skin/layout/bulb-on.png"); \
      } \
       \
      #ImperatorOverviewResourceTable th.resource_wood { \
        background-image:url("skin/resources/icon_wood.png"); \
      } \
       \
      #ImperatorOverviewResourceTable th.resource_wine { \
        background-image:url("skin/resources/icon_wine.png"); \
      } \
       \
      #ImperatorOverviewResourceTable th.resource_marble { \
        background-image:url("skin/resources/icon_marble.png"); \
      } \
       \
      #ImperatorOverviewResourceTable th.resource_crystal { \
        background-image:url("skin/resources/icon_crystal.png"); \
      } \
       \
      #ImperatorOverviewResourceTable th.resource_sulfur { \
        background-image:url("skin/resources/icon_sulfur.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building { \
        background-size: 55px; \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_spots { \
        background-image:url("skin/img/city/flag_red.png"); \
        background-size: 25px; \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_townHall { \
        background-image:url("skin/img/city/townhall_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_palace { \
        background-image:url("skin/img/city/palace_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_palaceColony { \
        background-image:url("skin/img/city/palaceColony_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_tavern { \
        background-image:url("skin/img/city/taverne_r.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_museum { \
        background-image:url("skin/img/city/museum_r.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_academy { \
        background-image:url("skin/img/city/academy_l.png"); \
      }       \
\
      #ImperatorOverviewBuildingsTable th.building_workshop { \
        background-image:url("skin/img/city/workshop_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_temple { \
        background-image:url("skin/img/city/temple_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_embassy { \
        background-image:url("skin/img/city/embassy_l.png"); \
      }  \
\
      #ImperatorOverviewBuildingsTable th.building_warehouse { \
        background-image:url("skin/img/city/warehouse_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_dump { \
        background-image:url("skin/img/city/dump_l.png"); \
      }  \
\
      #ImperatorOverviewBuildingsTable th.building_branchOffice { \
        background-image:url("skin/img/city/branchoffice_l.png"); \
      }  \
\
      #ImperatorOverviewBuildingsTable th.building_port { \
        background-image:url("skin/img/city/port_l.png"); \
      }  \
\
      #ImperatorOverviewBuildingsTable th.building_wall { \
        background-image:url("skin/img/city/wall.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_safehouse { \
        background-image:url("skin/img/city/safehouse_l.png"); \
        background-size: 65px; \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_barracks { \
        background-image:url("skin/img/city/barracks_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_shipyard { \
        background-image:url("skin/img/city/shipyard_l.png"); \
        background-size: 45px; \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_pirateFortress { \
        background-image:url("skin/img/city/pirateFortress_l.png"); \
        background-size: 45px; \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_forester { \
        background-image:url("skin/img/city/forester_l.png"); \
      }       \
\
      #ImperatorOverviewBuildingsTable th.building_carpentering { \
        background-image:url("skin/img/city/carpentering_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_winegrower { \
        background-image:url("skin/img/city/winegrower_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_vineyard { \
        background-image:url("skin/img/city/vineyard_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_stonemason { \
        background-image:url("skin/img/city/stonemason_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_architect { \
        background-image:url("skin/img/city/architect_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_glassblowing { \
        background-image:url("skin/img/city/glassblowing_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_optician { \
        background-image:url("skin/img/city/optician_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_alchemist { \
        background-image:url("skin/img/city/alchemist_l.png"); \
      } \
\
      #ImperatorOverviewBuildingsTable th.building_fireworker { \
        background-image:url("skin/img/city/fireworker_l.png"); \
      } \
\
      #ImperatorOverviewMilitaryTable th.military { \
        background-size: auto 33px; \
      } \
\
      #ImperatorOverviewMilitaryTable th.military_phalanx { \
        background-image:url("skin/characters/military/x60_y60/y60_phalanx_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_steamgiant { \
        background-image:url("skin/characters/military/x60_y60/y60_steamgiant_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_spearman { \
        background-image:url("skin/characters/military/x60_y60/y60_spearman_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_swordsman { \
        background-image:url("skin/characters/military/x60_y60/y60_swordsman_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_slinger { \
        background-image:url("skin/characters/military/x60_y60/y60_slinger_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_archer { \
        background-image:url("skin/characters/military/x60_y60/y60_archer_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_marksman { \
        background-image:url("skin/characters/military/x60_y60/y60_marksman_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_ram { \
        background-image:url("skin/characters/military/x60_y60/y60_ram_faceright.png"); \
        background-size: auto 18px; \
      } \
      #ImperatorOverviewMilitaryTable th.military_catapult { \
        background-image:url("skin/characters/military/x60_y60/y60_catapult_faceright.png"); \
        background-size: auto 23px; \
      } \
      #ImperatorOverviewMilitaryTable th.military_mortar { \
        background-image:url("skin/characters/military/x60_y60/y60_mortar_faceright.png"); \
        background-size: auto 22px; \
      } \
      #ImperatorOverviewMilitaryTable th.military_gyrocopter { \
        background-image:url("skin/characters/military/x60_y60/y60_gyrocopter_faceright.png"); \
        background-size: auto 21px; \
      } \
      #ImperatorOverviewMilitaryTable th.military_bombardier { \
        background-image:url("skin/characters/military/x60_y60/y60_bombardier_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_cook { \
        background-image:url("skin/characters/military/x60_y60/y60_cook_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_medic { \
        background-image:url("skin/characters/military/x60_y60/y60_medic_faceright.png"); \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_flamethrower { \
        background-image:url("skin/characters/fleet/60x60/ship_flamethrower_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_steamboat { \
        background-image:url("skin/characters/fleet/60x60/ship_steamboat_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_ram { \
        background-image:url("skin/characters/fleet/60x60/ship_ram_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_ballista { \
        background-image:url("skin/characters/fleet/60x60/ship_ballista_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_catapult { \
        background-image:url("skin/characters/fleet/60x60/ship_catapult_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_mortar { \
        background-image:url("skin/characters/fleet/60x60/ship_mortar_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_submarine { \
        background-image:url("skin/characters/fleet/60x60/ship_submarine_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_paddlespeedship { \
        background-image:url("skin/characters/fleet/60x60/ship_paddlespeedship_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_ballooncarrier { \
        background-image:url("skin/characters/fleet/60x60/ship_ballooncarrier_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_tender { \
        background-image:url("skin/characters/fleet/60x60/ship_tender_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewMilitaryTable th.military_ship_rocketship { \
        background-image:url("skin/characters/fleet/60x60/ship_rocketship_faceright.png"); \
        background-size: 33px auto; \
      } \
      #ImperatorOverviewEspionageTable th.location { \
        background-image: url("skin/layout/icon-island.png"); \
      } \
      #ImperatorOverviewEspionageTable th.travel_time { \
        background-image: url("skin/resources/icon_time.png"); \
      } \
      #ImperatorOverviewEspionageTable th.townhall_level { \
        background-image:url("skin/img/city/townhall_l.png"); \
        background-size: auto 100%; \
      } \
      #ImperatorOverviewEspionageTable th.wall_level { \
        background-image:url("skin/img/city/wall.png"); \
        background-size: auto 100%; \
      } \
      #ImperatorOverviewEspionageTable th.resources_lootable { \
        background-image: url("skin/characters/fleet/40x40/ship_transport_r_40x40.png"); \
        background-size: auto 100%; \
      } \
      #ImperatorOverviewEspionageTable th.combats { \
        background-image: url("skin/minimized/plunder.png"); \
        background-size: auto 120%; \
      } \
      #ImperatorOverviewEspionageTable th.military_score { \
        background-image: url("skin/characters/military/x60_y60/y60_phalanx_faceright.png"); \
        background-size: auto 100%; \
      } \
\
      /********************** Settings dialog *************************/ \
      #options .tabmenu .tab { \
        width: auto; \
      } \
'
    );
  }
  
  var settings = new IkaTools.Settings.Settings('ImperatorSettings');
  
  var localizedLanguage = settings.choice(
      'language',
      '',
      { 
        'Automatic': '',
        'Türkçe': 'tr',
        'English': 'en',
        'Bosnian': 'ba',
        'Spanish': 'es',
        'French': 'fr',
        'German': 'de',
        'Hungarian': 'hu',
        'Polish': 'pl',
      },
      localizer.delayedLocalize('settings','language'));
  
  var showResourceOverview = settings.boolean(
      'show_resource_overview',
      true,
      localizer.delayedLocalize('misc','resource_overview'));
  var showBuildingsOverview = settings.boolean(
      'show_buildings_overview',
      true,
      localizer.delayedLocalize('misc','buildings_overview'));
  var showMilitaryOverview = settings.boolean(
      'show_military_overview',
      true,
      localizer.delayedLocalize('misc','military_overview'));
  var showEspionageOverview = settings.boolean(
      'show_espionage_overview',
      true,
      localizer.delayedLocalize('misc','espionage_overview'));
      
  
  var autoAcceptDailyBonus = settings.boolean(
      'auto_accept_daily_bonus',
      true,
      localizer.delayedLocalize('settings','auto_accept_daily_bonus'));
  var hideAds = settings.boolean(
      'hide_ads',
      true,
      localizer.delayedLocalize('settings','hide_ads'));
  var hideFacebook = settings.boolean(
      'hide_facebook',
      true,
      localizer.delayedLocalize('settings','hide_facebook'));
  var hideFriendsBar = settings.boolean(
      'hide_friends_bar',
      false,
      localizer.delayedLocalize('settings','hide_friends_bar'));
  var hideChat = settings.boolean(
      'hide_chat',
      false,
      localizer.delayedLocalize('settings','hide_chat'));
  var transportButtons = settings.boolean(
      'transport_buttons',
      true,
      localizer.delayedLocalize('settings','transport_buttons'));
  var donationButtons = settings.boolean(
      'donation_buttons',
      true,
      localizer.delayedLocalize('settings','donation_buttons'));
  var showCityOwners = settings.boolean(
      'show_city_owners',
      false,
      localizer.delayedLocalize('settings', 'show_city_owners'));
  var preventAccidentalColonyDestruction = settings.boolean(
      'prevent_accidental_colony_destruction',
      true,
      localizer.delayedLocalize('settings', 'prevent_accidental_colony_destruction'));
  var initializeColonizationMissionsForPirateRaiding = settings.boolean(
      'initialize_colonization_missions_for_pirate_raiding',
      false,
      localizer.delayedLocalize('settings', 'initialize_colonization_missions_for_pirate_raiding'));
      
  var testDesktopAlert = settings.html(
      function desktopAlertHtml() { 
        return '<a id="DesktopAlertTest" class="button">%s</a>'.format(
            localizer.localize('settings','do_test'));
      },
      function desktopAlertPostRender() {
        function showTestDesktopAlert() {
          if (window.webkitNotifications) {
            if (window.webkitNotifications.checkPermission() == 0) { // PERMISSION_ALLOWED
              var notification = window.webkitNotifications.createNotification(
                  'http://' + document.domain + '/skin/layout/advisors/general_alert.png', 
                  localizer.localize('settings','test_desktop_alert_title'),
                  localizer.localize('settings','test_desktop_alert_text'));
              notification.onclick = IkaTools.Logging.debuggable(
                  'Imperator.testDesktopAlert.dismiss',
                  function closeNotification() {
                    notification.cancel();
                  });
              notification.show();
              return true;
            }
          } else {
            alert(localizer.localize('settings','desktop_alerts_not_supported'));
          }
          return false;
        }
        $('#DesktopAlertTest').click(IkaTools.Logging.debuggable(
            'Imperator.testDesktopAlert',
            function testDesktopAlert() {
              if (!showTestDesktopAlert()) {
                window.webkitNotifications.requestPermission(
                   IkaTools.Logging.debuggable(
                       'Imperator.testDesktopAlert.requestPermission',
                       showTestDesktopAlert));
              }
            }));
      },
      localizer.delayedLocalize('settings','test_desktop_alert'));
  
  var buildingCompletionAlert_Desktop = settings.boolean(
      'building_completion_alert_desktop',
      false,
      localizer.delayedLocalize('settings','building_completion_alert_desktop'));
  var transportMissionLoaded_Desktop = settings.boolean(
      'transport_loaded_alert_desktop',
      false,
      localizer.delayedLocalize('settings','transport_loaded_alert_desktop'));
  var transportMissionArrived_Desktop = settings.boolean(
      'transport_arrived_alert_desktop',
      false,
      localizer.delayedLocalize('settings','transport_arrived_alert_desktop'));
  var transportMissionReturned_Desktop = settings.boolean(
      'transport_returned_alert_desktop',
      false,
      localizer.delayedLocalize('settings','transport_returned_alert_desktop'));
  var deployArmyLoaded_Desktop = settings.boolean(
      'deploy_army_loaded_alert_desktop',
      false,
      localizer.delayedLocalize('settings','deploy_army_loaded_alert_desktop'));
  var deployArmyArrived_Desktop = settings.boolean(
      'deploy_army_arrived_alert_desktop',
      false,
      localizer.delayedLocalize('settings','deploy_army_arrived_alert_desktop'));
  var deployArmyReturned_Desktop = settings.boolean(
      'deploy_army_returned_alert_desktop',
      false,
      localizer.delayedLocalize('settings','deploy_army_returned_alert_desktop'));
  var deployNavyArrived_Desktop = settings.boolean(
      'deploy_navy_arrived_alert_desktop',
      false,
      localizer.delayedLocalize('settings','deploy_navy_arrived_alert_desktop'));
  var deployNavyReturned_Desktop = settings.boolean(
      'deploy_navy_returned_alert_desktop',
      false,
      localizer.delayedLocalize('settings','deploy_navy_returned_alert_desktop'));
  var pillageLoaded_Desktop = settings.boolean(
      'pillage_loaded_alert_desktop',
      false,
      localizer.delayedLocalize('settings','pillage_loaded_alert_desktop'));
  var pillageArrived_Desktop = settings.boolean(
      'pillage_arrived_alert_desktop',
      false,
      localizer.delayedLocalize('settings','pillage_arrived_alert_desktop'));
  var pillageReturned_Desktop = settings.boolean(
      'pillage_returned_alert_desktop',
      false,
      localizer.delayedLocalize('settings','pillage_returned_alert_desktop'));
  var ignoredHostileMissions = settings.text(
      'ignored_hostile_missions',
      '[]',
      localizer.delayedLocalize('settings', 'ignored_hostile_missions'));
      
      
  var debugSetting = settings.html(
      function debugHtml() {
        return '<input id="EmpireDataDebug" type="text" style="width:100%"/>';
      },
      function debugPostRender() {
        $('#EmpireDataDebug').val(IkaTools.EmpireData.getDebugString());
      },
      IkaTools.Utils.fixedFunction('Empire data'));
  var resetData = settings.html(
      function resetDataHtml() {
        return '<a id="ResetImperatorData" class="button">Reset</a>';
      },
      function resetDataPostRender() {
        $('#ResetImperatorData').click(function resetDataClicked() {
          IkaTools.EmpireData.resetData();
          window.location.reload();
        });
      },
      IkaTools.Utils.fixedFunction('Reset data'));
  var espionageDebugSetting = settings.html(
      function debugHtml() {
        return '<input id="EspionageDataDebug" type="text" style="width:100%"/>';
      },
      function debugPostRender() {
        $('#EspionageDataDebug').val(IkaTools.EmpireData.Espionage.getDebugString());
      },
      IkaTools.Utils.fixedFunction('Espionage data'));
  var resetEspionageData = settings.html(
      function resetDataHtml() {
        return '<a id="ResetEspionageData" class="button">Reset Espionage</a>';
      },
      function resetDataPostRender() {
        $('#ResetEspionageData').click(function resetDataClicked() {
          IkaTools.EmpireData.Espionage.resetData();
          window.location.reload();
        });
      },
      IkaTools.Utils.fixedFunction('Reset espionage data'));
  var exceptionLogSetting = settings.html(
      function exceptionLogHtml() {
        return '<input id="ExceptionLog" type="text" style="width:100%"/>';
      },
      function exceptionLogPostRender() {
        $('#ExceptionLog').val(JSON.stringify(IkaTools.Logging.getExceptionLog()));
      },
      IkaTools.Utils.fixedFunction('Errors'));

  function addSettingsLink() {
    var settingsWindow = new IkaTools.UI.SettingsWindow(
      'ImperatorSettings',
      'Imparatorluk',
      settings, 
      [new IkaTools.UI.SettingsWindow.Group(localizer.localize('settings','general'),
          [localizedLanguage]),
       new IkaTools.UI.SettingsWindow.Group(localizer.localize('settings','overviews'),
          [showResourceOverview, showBuildingsOverview, showMilitaryOverview,
           showEspionageOverview]),
       new IkaTools.UI.SettingsWindow.Group(localizer.localize('settings','tweaks'),
          [autoAcceptDailyBonus, hideAds, hideFacebook, hideFriendsBar, hideChat,
           transportButtons, donationButtons, showCityOwners,
           preventAccidentalColonyDestruction, initializeColonizationMissionsForPirateRaiding
           ]),
       new IkaTools.UI.SettingsWindow.Group(localizer.localize('settings','alerts'),
          [testDesktopAlert, buildingCompletionAlert_Desktop,
           transportMissionLoaded_Desktop, transportMissionArrived_Desktop,
           transportMissionReturned_Desktop, deployArmyLoaded_Desktop,
           deployArmyArrived_Desktop, deployArmyReturned_Desktop,
           deployNavyArrived_Desktop, deployNavyReturned_Desktop,
           pillageLoaded_Desktop, pillageArrived_Desktop, pillageReturned_Desktop,
           /*ignoredHostileMissions*/]),
       new IkaTools.UI.SettingsWindow.Group(localizer.localize('settings','debug'),
           [debugSetting, resetData, espionageDebugSetting, resetEspionageData, 
            exceptionLogSetting]),
      ]);
    settingsWindow.registerSavedSettingsHandler(function reloadOnSavedSettings() {
      window.location.reload();
    });
    settingsWindow.addAsScriptOptionsLink();
  }
  
  function Updateable(container, permanent, ids) {
    this.container = container;
    this.ids = $.makeArray(ids);
    this.elements = [];
    if (!this.ids.length) {
      this.ids[0] = IkaTools.Utils.nextId("updateable_");
    }
    this.permanent = permanent;
    this.events = {};
  }

  $.extend(Updateable.prototype, {
    getElement: function getElement(index) {
      var element = this.elements[index];
      if (!element || !element.length) {
        element = $(document.getElementById(this.ids[index]));
        this.elements[index] = element;
      }
      return element;
    },
    getElements: function getElements() {
      for (var i = 0; i < this.ids.length; i++) {
        this.getElement(i);
      }
      return this.elements;
    },
    destroy: function destroy() {
      return this.container.destroy(this);
    },
    getId: function getId(index) {
      return this.ids[index];
    },
    getIdentifier: function getIdentifier() {
      return this.ids.join(',');
    },
    isPermanent: function isPermanent() {
      return this.permanent;
    },
    registerUpdate: function registerUpdate(eventName, f) {
      this.events[eventName] = f;
      return this;
    },
    updateForEvent: function updateForEvent(eventName) {
      var f = this.events[eventName];
      if (f) {
        f.apply(this, this.getElements());
      }
    },
    registerTickerUpdate: function registerTickerUpdate(f) {
      return this.registerUpdate('ticker', f);
    },
    registerFastTickerUpdate: function registerFastTickerUpdate(f) {
      return this.registerUpdate('fastTicker', f);
    },
  });
  
  function Updateables(name) {
    this.name = name;
    this.active = false;
    this.undispatchedEvents = {};
    this.updateables = {};
  }
  
  $.extend(Updateables.prototype, {
    create: function create() {
      var updateable = new Updateable(this, false, arguments);
      this.updateables[updateable.getIdentifier()] = updateable;
      return updateable;
    },
    createPermanent: function createPermanent() {
      var updateable = new Updateable(this, true, arguments)
      this.updateables[updateable.getIdentifier()] = updateable;
      return updateable;
    },
    destroy: function destroy(updateable) {
      delete this.updateables[updateable.getIdentifier()];
    },
    activate: function activate() {
      $.each(this.updateables, function (key, updateable) {
        updateable.getElements();
      });
      if (!this.tickerEvent) {
        this.tickerEvent = setInterval(IkaTools.Logging.debuggable(
            { label: 'Imperator.Updateable.tickerUpdate[' +  this.name + ']', },
            this.updateForEvent.bind(this, 'ticker')),
          4000);
      }
      if (!this.fastTickerEvent) {
        this.fastTickerEvent = setInterval(IkaTools.Logging.debuggable(
            {label: 'Imperator.Updateable.fastTickerUpdate[' +  this.name + ']', },
            this.updateForEvent.bind(this, 'fastTicker')),
          1000);
      }
      this.active = true;
      $.each(this.undispatchedEvents, this.updateForEvent.bind(this));
      this.undispatchedEvents = {};
    },
    deactivate: function deactivate() {
      this.active = false;
      if (this.tickerEvent) {
        clearInterval(this.tickerEvent);
        delete this.tickerEvent;
      }
      if (this.fastTickerEvent) {
        clearInterval(this.fastTickerEvent);
        delete this.fastTickerEvent;
      }
    },
    updateForEvent: function updateForEvent(eventName) {
      if (this.active) {
        $.each(this.updateables, function(id, updateable) {
          updateable.updateForEvent(eventName);
        });
      } else {
        this.undispatchedEvents[eventName] = true;
      }
    },
    clear: function clear() {
      var that = this;
      $.each(this.updateables, function(id, updateable) {
        if (!updateable.isPermanent()) {
          delete that.updateables[id];
        }
      });
      this.undispatchedEvents = {};
    },
  });
  
  var clickHandler = function() {
    var idToHandlerMap = {};

    return {
      register: function register(id, f) {
        idToHandlerMap[id] = f;
      },
      dispatch: function(element) {
        var handler = idToHandlerMap[element.id];
        if (handler) {
          handler();
          return true;
        } else {
          IkaTools.Logging.debug("No registered handler for ", element.id, element);
          return false;
        }
      },
    }
  }();
  
  $('#container').on('click.imperator_link_handler', '.imperator_link', 
      IkaTools.Logging.debuggable('Imperator.overview.imperator_link.clicked', 
          function(e) { 
            if (clickHandler.dispatch(e.currentTarget)) {
              e.preventDefault();
            }
          }));

  function Link(id) {
    this.id = id;
  }

  $.extend(Link.prototype, {
    getId: function getId() {
      return this.id;
    },
    toFunction: function toFunction(f, predicate) {
      clickHandler.register(this.id, function() {
        if (!predicate || predicate()) {
          f();
        }
      });
      return this;
    },
    toCitysIslandView: function toCitysIslandView(city, view, params, predicate) {
      clickHandler.register(this.id, function() {
        if (!predicate || predicate()) {
          IkaTools.View.goToCitysIslandView(city, view, params);
        }
      });
      return this;
    },
    /*toIslandView: function toIslandView(islandId, view, params, predicate) {
      clickHandler.register(this.id,
        function() {
          if (!predicate || predicate()) {
            IkaTools.View.goToIslandView(
                IkaTools.View.getCurrentCity(), islandId, view, params);
          }
        });
      return this;
    },*/
    toLocalView: function toLocalView(view, params, predicate) {
      clickHandler.register(this.id, function() {
        if (!predicate || predicate()) {
          IkaTools.View.goToLocalView(view, params);
        }
      });
      return this;
    },
    toCityView: function toCityView(city, view, params, predicate) {
      clickHandler.register(this.id, function() {
         if (!predicate || predicate()) {
           IkaTools.View.goToCityView(city, view, params);
         }
       });
      return this;
    },
    toCityActivation: function toCityActivation(city, predicate) {
      clickHandler.register(this.id, function() {
        if (!predicate || predicate(this)) {
          IkaTools.View.activateCity(city);
        }
      });
      return this;
    },
    toIkariamPage: function toIkariamPage(params, anchor, predicate) {
      clickHandler.register(this.id, function() {
        if (!predicate || predicate(this)) {
          IkaTools.View.goToIkariamFullPage(params, anchor);
        }
      });
      return this;
    },
  });
  
  var toolTips = new IkaTools.UI.ToolTipHandler(
       'imperator_tool_tip', $('<div class="tool_tip_container"/>'));
  toolTips.startHandling($('body'));
  
  function overviewTables() {
    function Tab(name, tabText, tabContentHolder, tabContentId, init, renderer) {
      this.updateables = new Updateables(name);
      
      var render = renderer.bind(this);
      this.mainUpdateable = this.updateables.createPermanent(tabContentId);
      this.mainUpdateable.registerUpdate('redraw', function(element) {
        element.removeClass(
            'city_type_ownCity city_type_deployedCities city_type_occupiedCities');
        element.addClass('city_type_' + IkaTools.View.getCurrentCity().getType());
        element.html(render());
      });
      this.mainUpdateable.registerUpdate('cityChanged', function updateTabTableType(table) {
        table.removeClass(
            'city_type_ownCity city_type_deployedCities city_type_occupiedCities');
        table.addClass('city_type_' + IkaTools.View.getCurrentCity().getType());
      });

      this.isActive = false;
      this.needsRedraw = true;
      //this.render = renderer;

      var tab = this;
      this.initFirstTime = IkaTools.Utils.thunk(function() {
        IkaTools.View.registerIkariamAjaxResponseCallback(function tab_CityChanged() {
          tab.updateables.updateForEvent('cityChanged');
        });
        init.call(tab);
      });

      this.tab = new IkaTools.UI.TabPane.Tab(
          $('<b>%s</b>'.format(tabText)), 
          tabContentHolder,
          { 
            activatedCallback: function() {
              this.isActive = true;
              this.maybeRedraw();
              this.initFirstTime();
              this.updateables.activate();
            }.bind(this),
            deactivatedCallback: function() {
              this.isActive = false;
              this.updateables.deactivate();
            }.bind(this),
          });
    }

    $.extend(Tab.prototype, {
      maybeRedraw: function maybeRedraw(redraw) {
        this.needsRedraw = this.needsRedraw || redraw;
        if (this.isActive && this.needsRedraw) {
          this.updateables.clear();
          this.mainUpdateable.updateForEvent('redraw');
          this.needsRedraw = false;
        }
      },
      getTab: function getTab() {
        return this.tab;
      }
    });
    
    function makeCityNameCells(table, city, excludeTradeGood) {
      var cityLink = new Link('CityLink_%s_%s'.format(table, city.getId()))
          .toCityActivation(city);
      return ('%s' +
              '<td class="city_name">' +
                '<a class="imperator_link" id="%s" href="javascript:void(0)">%s</a>' + 
              '</td>').format(
                  (excludeTradeGood ? '' : ('<td class="city_tradegood imperator_link ">' +
                                              '<img src="skin/resources/icon_%s.png">' + 
                                            '</td>').format(city.getTradeGoodType())),
                   cityLink.getId(),
                   city.getName());
    }
    
    function makeCityNameColGroup(extraCols, excludeTradeGood) {
      return ('<colgroup class="city_name">' + 
                '%s' + 
                '<col class="city_name">' + 
                '%s' +
              '</colgroup>').format(
                  excludeTradeGood ? '' : '<col class="city_tradegood">',
                  extraCols || '');
    }
  
    function makeCityNameHeaderCells(excludeTradeGood) {
      return '<th class="city_name" colspan="%s">%s</th>'.format(
          excludeTradeGood ? '1' : '2',
          localizer.localize('misc','city_name'));
    }
    
    function makeResourceTab() {
      function makeResourceUseTableRow(displaySign, usePerHour, usePerDay, usePerWeek) {
        return makeResourceUseTableRowRaw(
            displaySign,
            IkaTools.Intl.formatInteger(usePerHour),
            IkaTools.Intl.formatInteger(usePerDay || 
                usePerHour * IkaTools.Constants.Time.HOURS_PER_DAY),
            IkaTools.Intl.formatInteger(usePerWeek || 
                usePerHour * IkaTools.Constants.Time.HOURS_PER_WEEK));
      }
      
      function makeResourceUseTableRowRaw(displaySign, usePerHour, usePerDay, usePerWeek) {
        return '<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>'.format(
            displaySign, usePerHour, usePerDay, usePerWeek);
      }
      
      function makeResourceUseToolTip(icon, rows, footerRows) {
        return ('<table class="resource_use_tool_tip">' + 
                  '<colgroup><col/><col/><col/><col/></colgroup>' +
                  '<thead>' + 
                    '<tr>' + 
                      '<th><img src="%s" height="12"/></th>' + 
                      '<th>%s</th>' + 
                      '<th>%s</th>' + 
                      '<th>%s</th>' + 
                    '</tr>' + 
                  '</thead>' + 
                  '<tbody>%s</tbody>' +
                  '<tfoot>%s</tfoot>' +
                '</table>').format(
                    icon,
                    IkaTools.Intl.localizer.localize('timeunits','long','hour'),
                    IkaTools.Intl.localizer.localize('timeunits','long','day'),
                    IkaTools.Intl.localizer.localize('timeunits','long','week'),
                    rows.join(''),
                    footerRows ? footerRows.join('') : '')
      }
      
      function makeTableContent() {
        var updateables = this.updateables;
        var civData = IkaTools.EmpireData.getCivilizationData();
        
        function getResourceData(resource) {
          var current = resource.getCurrent();
          var capacity = resource.getCapacity();

          var millisUntilFull = Math.ceil(resource.getTimeUntilFull());
          var millisUntilEmpty = Math.ceil(resource.getTimeUntilEmpty());

          var fullClass = '';
          if (millisUntilFull < 1 * IkaTools.Constants.Time.MILLIS_PER_HOUR) {
            fullClass = 'expiration_now';
          } else if (millisUntilFull <= 6 * IkaTools.Constants.Time.MILLIS_PER_HOUR) {
            fullClass = 'expiration_imminent';
          } else if (millisUntilFull <= 24 * IkaTools.Constants.Time.MILLIS_PER_HOUR) {
            fullClass = 'expiration_soon';
          } else if (millisUntilFull <= 48 * IkaTools.Constants.Time.MILLIS_PER_HOUR) {
            fullClass = 'expiration_forseeable';
          }

          var emptyClass = '';
          if (millisUntilEmpty < 1 * IkaTools.Constants.Time.MILLIS_PER_HOUR) {
            emptyClass = 'expiration_now';
          } else if (millisUntilEmpty <= 6 * IkaTools.Constants.Time.MILLIS_PER_HOUR) {
            emptyClass = 'expiration_imminent';
          } else if (millisUntilEmpty <= 24 * IkaTools.Constants.Time.MILLIS_PER_HOUR) {
            emptyClass = 'expiration_soon';
          } else if (millisUntilEmpty <= 48 * IkaTools.Constants.Time.MILLIS_PER_HOUR) {
            emptyClass = 'expiration_forseeable';
          }
          
          return {
            current: current,
            max: capacity.maximum,
            percent: current / capacity.maximum * 100,
            safe: capacity.safe,
            fullClass: fullClass,
            emptyClass: emptyClass,
          };
        }
        
        function makeResourceCells(movements, city, resourceName) {
          var resource = city.getResource(resourceName);
          var cityId = city.getId();
          
          var currentUpdateable = updateables.create(
              IkaTools.Utils.nextId('resource_current_'),
              IkaTools.Utils.nextId('resource_current_percent_bar_'),
              IkaTools.Utils.nextId('resource_current_percent_bar_active_'));
              
          var resourceLink = new Link('Resource_%s_%s'.format(city.getId(), resourceName));
  
          if (resourceName == IkaTools.Constants.Resources.WOOD) {
            resourceLink.toCitysIslandView(
                city, IkaTools.Constants.View.RESOURCE, { type: 'resource' });
          } else if (resourceName == city.getTradeGoodType()) {
            resourceLink.toCitysIslandView(
                city, IkaTools.Constants.View.TRADE_GOOD, 
                { type: IkaTools.Constants.TradeGoodOrdinals[city.getTradeGoodType()] });
          }
          
          var data = getResourceData(resource);
          
          var inTransit = 0;
          
          function isCountableMovement(movement) {
            if (movement.getResource(resourceName) > 0) {
              if (movement.getMission() == IkaTools.Constants.Movements.Mission.PLUNDER) {
                return movement.getOriginCityId() == cityId;
              }
              if (movement.getStage() == IkaTools.Constants.Movements.Stage.LOADING ||
                  movement.getStage() == IkaTools.Constants.Movements.Stage.EN_ROUTE) {
                return movement.getTargetCityId() == cityId;
              }
              if (movement.getStage() == IkaTools.Constants.Movements.Stage.RETURNING) {
                return movement.getOriginCityId() == cityId;
              }
            }
            return false;
          } 
          
          $.each(movements, function totalMovements(index, movement) {
            var mission = movement.getMission();
            var stage = movement.getStage();
            if (isCountableMovement(movement)) {
              inTransit += movement.getResource(resourceName) || 0;
            }
          });
          
          var inTransitDivId = 'ResourcesInTransit_%s_%s'.format(city.getId(), resourceName);
          if (inTransit) {
            toolTips.registerRefreshable(inTransitDivId, function() {
              return ('<table class="resources_in_transit_tool_tip">' + 
                        '<thead>' + 
                          '<tr>' + 
                            '<th>' + 
                              '<img src="skin/resources/icon_%s.png" height="12"/>' + 
                            '</th>' + 
                            '<th>%s</th>' +
                          '</tr>' + 
                        '</thead>' + 
                        '<tbody>%s</tbody>' + 
                      '</table').format(
                  resourceName,
                  localizer.localize('misc','in_transit'),
                  $.map(movements, function makeResourcesInTransitRow(movement) {
                    var count = movement.getResource(resourceName);
                    if (isCountableMovement(movement)) {
                      return '<tr><td class="resource_count">%s</td><td>%s</td></tr>'.format(
                          IkaTools.Intl.formatInteger(count, true),
                          IkaTools.Intl.formatRemainingTime(
                              movement.getArrivalTime() - IkaTools.View.gameTimeNow()));
                    } else {
                      return '';
                    }
                  }).join(''));
            });
          } else {
            toolTips.deregister(inTransitDivId);
          }
          
          toolTips.registerRefreshable(currentUpdateable.getId(1), function() {
            var timeToFull = resource.getTimeUntilFull();
            var timeToEmpty = resource.getTimeUntilEmpty();
            
            var timeRow = '';
            if (isFinite(timeToFull)) {
              timeRow = '<tr><td>%s:</td><td>%s</td>'.format(
                  localizer.localize('misc','time_to_full'),
                  IkaTools.Intl.formatRemainingTime(timeToFull, 
                      localizer.localize('misc','full')));
            } else if (isFinite(timeToEmpty)) {
              timeRow = '<tr><td>%s:</td><td>%s</td>'.format(
                  localizer.localize('misc','time_to_empty'),
                  IkaTools.Intl.formatRemainingTime(timeToEmpty, 
                      localizer.localize('misc','empty')));
            }
            
            var capacity = city.getResourceCapacity();
            return ('<table>' + 
                      '<colgroup><col/><col/></colgroup>' + 
                      '<tbody>' + 
                        '<tr><td>%s:</td><td>%s</td></tr>' + 
                        '<tr><td>%s:</td><td>%s</td></tr>' + 
                        '%s' + 
                      '<tbody>' + 
                    '<table>').format(
                        localizer.localize('misc','maximum_capacity'),
                        IkaTools.Intl.formatInteger(data.max),
                        localizer.localize('misc','safe_capacity'),
                        IkaTools.Intl.formatInteger(data.safe),
                        timeRow);
          });

          var currentContent = '?';
          if (data.current) {
            currentContent = (
                '<div id="%s" class="resource_current %s %s">%s</div>' + 
                '<div id="%s" class="resources_transporting imperator_tool_tip">%s</div>' + 
                '<div id="%s" class="percent_bar imperator_tool_tip %s">' + 
                  '<div id="%s" class="percent_bar_active" style="width: %s%;" />' +
                '</div>').format(
                     currentUpdateable.getId(0),
                     data.emptyClass,
                     data.current <= data.safe ? 'is_under_safe_limit' : '',
                     IkaTools.Intl.formatInteger(data.current),
                     inTransitDivId,
                     inTransit ? IkaTools.Intl.formatInteger(inTransit, true)
                               : '-',
                     currentUpdateable.getId(1),
                     data.fullClass,
                     currentUpdateable.getId(2),
                     data.percent);

            currentUpdateable.registerTickerUpdate(function(amount, percentBar, activeBar) {
              var data = getResourceData(resource);
              if (data.current <= data.safe) {
                amount.addClass('is_under_safe_limit');
              } else {
                amount.removeClass('is_under_safe_limit');
              }
              amount.html(IkaTools.Intl.formatInteger(data.current));
              amount.removeClass(
                  'expiration_now expiration_imminent expiration_soon expiration_forseeable');
              amount.addClass(data.emptyClass);
              percentBar.removeClass(
                  'expiration_now expiration_imminent expiration_soon expiration_forseeable');
              percentBar.addClass(data.fullClass);
              activeBar.css('width', '%s%'.format(data.percent));
            });
          }
  
          var productionContent = '&nbsp;';
          var production = resource.getProduction();
          if (production !== undefined) {
            var productionPerHour = production * IkaTools.Constants.Time.SECONDS_PER_HOUR;
            productionContent = IkaTools.Intl.formatInteger(productionPerHour, true);
            toolTips.registerSimple(resourceLink.getId(), 
                makeResourceUseToolTip('skin/resources/icon_%s.png'.format(resourceName),
                    [makeResourceUseTableRow('+', productionPerHour)]));
          }

          
          var consumptionContent = '';
          var consumption = resource.getConsumption();
          var tavernLink = new Link('WineConsumptionTavern_%s'.format(city.getId()));
          var tavern = city.getBuildingByType(IkaTools.Constants.Buildings.TAVERN);
          if (tavern) {
            tavernLink.toCityView(city, IkaTools.Constants.Buildings.TAVERN,
                { position: tavern.getPosition(), cityId: city.getId() });
          }
          if (tavern && consumption !== undefined) {
            var consumptionPerHour = 
                Math.round(consumption * IkaTools.Constants.Time.SECONDS_PER_HOUR);
            toolTips.registerSimple(tavernLink.getId(), 
                makeResourceUseToolTip('skin/resources/icon_%s.png'.format(resourceName),
                    [makeResourceUseTableRow('-', consumptionPerHour)]));
            consumptionContent = 
                ('<a id="%s" class="imperator_link imperator_tool_tip" ' + 
                    'href="javascript:void(0);">%s</a>').format(
                     tavernLink.getId(),
                     IkaTools.Intl.formatInteger(-consumptionPerHour, true));
          }              
          
          return ('<td class="resource resource_%s">%s</td>' +
                  '<td class="resource resource_%s resource_change">' + 
                    '<div class="resource_production">' +
                      '<a id="%s" class="imperator_link imperator_tool_tip" ' + 
                         'href="javascript:void(0);">%s</a>' + 
                    '</div>' +  
                    '<div class="resource_consumption">%s</div>' +  
                  '</td>').format(
               resourceName,
               currentContent,
               resourceName,
               resourceLink.getId(),
               productionContent,
               consumptionContent);
        }
        
        function makeResearchCell(city) {
          var scientists = city.getScientists();
          var academy = city.getBuildingByType('academy');
          
          if (academy) {
            var research = city.getResearch();
            var link = new Link('ResearchTableAcademy_%s'.format(city.getId()))
                .toCityView(city, IkaTools.Constants.Buildings.ACADEMY,
                     { position: academy.getPosition(), cityId: city.getId() });
            var maxScientists = IkaTools.Constants.BuildingData[
                IkaTools.Constants.Buildings.ACADEMY].maxScientists[academy.getLevel()];
            var percent = scientists / maxScientists * 100;
            var percentBarId = IkaTools.Utils.nextId('research_percent_bar');
            
            toolTips.registerSimple(link.getId(),
                makeResourceUseToolTip('skin/layout/bulb-on.png',
                    [makeResourceUseTableRow('+', research)]));
            toolTips.registerSimple(percentBarId,
                ('<table><tbody>' +
                   '<tr><td>%s:</td><td>%s</td></tr>' + 
                   '<tr><td>%s:</td><td>%s</td></tr>' +
                 '</tbody></table>').format(
                     localizer.localize('misc','employed'),
                     scientists, 
                     localizer.localize('misc','maximum_capacity'),
                     maxScientists));
                
            return ('<td class="research">' + 
                      '<div>' +
                        '<a id="%s" href="javascript:void(0)" ' + 
                           'class="imperator_link imperator_tool_tip">%s</a>' + 
                      '</div>' + 
                      '<div id ="%s" class="percent_bar imperator_tool_tip percent_bar_desire_filled %s">' + 
                        '<div class="percent_bar_active" style="width: %s%;" />' +
                      '</div>' + 
                    '</td>').format(
                        link.getId(),
                        IkaTools.Intl.formatInteger(research, true),
                        percentBarId,
                        percent == 100 ? 'percent_bar_filled' : '',
                        percent);
          }
          
          return '<td class="research"></td>';
        }
        
        function getPopulationData(city) {
          var populationData = city.getPopulationData();
          var icon = 'neutral';
          if (populationData.happiness < -50) {
            icon = 'outraged';
          } else if (populationData.happiness < -.50) {
            icon = 'sad';
          } else if (populationData.happiness > 300) {
            icon = 'ecstatic';
          } else if (populationData.happiness > 50) {
            icon = 'happy';
          }
          var percent = populationData.population / populationData.max * 100;
          return $.extend({
            icon: "skin/smilies/%s_x25.png".format(icon),
            percent: percent,
            percentClass: percent == 100 ? 'percent_bar_filled' : '',
            happinessClass: percent == 100 && populationData.happiness >= 60 
                && city.getTavernWineLevel() > 0
                ? 'imperator_warning' : '',
          }, populationData);
        }
        
        function makePopulationCells(city) {
          var populationData = getPopulationData(city);
          if (!populationData.population) {
            return ('<td class="population">%s</td>' + 
                    '<td class="population_growth_icon"></td>' + 
                    '<td class="population_growth"/>').format(
                IkaTools.Intl.formatInteger(populationData.population));
          }
          
          var updateable = updateables.create(
              IkaTools.Utils.nextId('population_current_'),
              IkaTools.Utils.nextId('population_current_percent_bar_'),
              IkaTools.Utils.nextId('population_current_percent_bar_active_'),
              IkaTools.Utils.nextId('population_growth_icon_'),
              IkaTools.Utils.nextId('population_growth_'));
              
          updateable.registerTickerUpdate(
              function(population, percentBar, activeBar, icon, growth) {
                var populationData = getPopulationData(city);
                population.html(IkaTools.Intl.formatInteger(
                    Math.floor(populationData.population)));
                percentBar.removeClass('percent_bar_filled');
                percentBar.addClass(populationData.percentClass);
                activeBar.css('width', '%s%'.format(populationData.percent));
                icon.attr('src', populationData.icon);
                growth.removeClass('imperator_warning');
                growth.addClass(populationData.happinessClass);
                growth.html(
                    IkaTools.Intl.formatDecimal(populationData.growth, 2, true));
              });
              
          toolTips.registerRefreshable(updateable.getId(3), function() {
            var data = city.getPopulationData();
            var tavern = city.getBuildingByType(IkaTools.Constants.Buildings.TAVERN);
            var museum = city.getBuildingByType(IkaTools.Constants.Buildings.MUSEUM);
            
            var culturalGoods = city.getCulturalGoods();
            var tavernWineLevel = city.getTavernWineLevel();
            
            return ('<table>' + 
                      '<tbody>' + 
                        '<tr><td>%s:</td><td>%s</td></tr>' +
                        '<tr><td>%s:</td><td>%s/%s</td></tr>' +
                        '<tr><td>%s:</td><td>%s/%s</td></tr>' +
                      '<tbody>' + 
                    '</table>').format(
                        localizer.localize('misc','satisfaction'),
                        IkaTools.Intl.formatInteger(data.happiness, true),
                        localizer.localize('misc','cultural_goods'),
                        IkaTools.Intl.formatInteger(culturalGoods),
                        IkaTools.Intl.formatInteger(museum ? museum.getLevel() : 0),
                        localizer.localize('misc','tavern_wine_serving_level'),
                        IkaTools.Intl.formatInteger(tavernWineLevel),
                        IkaTools.Intl.formatInteger(tavern ? tavern.getLevel() : 0));                        
          });
              
          toolTips.registerRefreshable(updateable.getId(4), function() {
            var data = city.getPopulationData();
            function growthIn(hours) {
              var growth = data.happiness * ( 1 - Math.pow(Math.E, -hours / 50));
              if (growth + data.population > data.max) {
                growth = data.max - data.population;
              }
              return growth;
            }

            return makeResourceUseToolTip(
                data.happiness >= 0 ? 'skin/icons/growth_positive.png'
                                    : 'skin/icons/growth_negative.png',
                [makeResourceUseTableRowRaw(data.happiness >= 0 ? '+' : '-', 
                    IkaTools.Intl.formatDecimal(growthIn(1), 2), 
                    IkaTools.Intl.formatDecimal(growthIn(24), 2), 
                    IkaTools.Intl.formatDecimal(growthIn(168), 2))]);
          });
              
          toolTips.registerRefreshable(updateable.getId(1), function() {          
            var data = city.getPopulationData();
            var timeToFull = Number.POSITIVE_INFINITY;
            
            if (data.population == data.max) {
              timeToFull = 0;
            } else if (data.population + data.happiness > data.max) {
              var finalHappiness = data.population + data.happiness - data.max;
              timeToFull = (Math.log(data.happiness) - Math.log(finalHappiness)) *
                  50 * IkaTools.Constants.Time.MILLIS_PER_HOUR;
            }
            
            return ('<table>' + 
                      '<tbody>' + 
                        '<tr><td>%s:</td><td>%s</td></tr>' + 
                        '<tr><td>%s:</td><td>%s</td></tr>' + 
                      '<tbody>' + 
                    '<table>').format(
                        localizer.localize('misc','maximum_capacity'),
                        IkaTools.Intl.formatInteger(data.max),
                        localizer.localize('misc','time_to_full'),
                        IkaTools.Intl.formatRemainingTime(timeToFull, 
                            localizer.localize('misc','full')));
          });
          
          return ('<td class="population">' + 
                    '<div id="%s">%s</div>' + 
                    '<div id="%s" ' +
                         'class="percent_bar percent_bar_desire_filled imperator_tool_tip %s">' + 
                      '<div id="%s"class="percent_bar_active" style="width: %s%;" />' +
                    '</div>' + 
                  '</td>' + 
                  '<td class="population_growth_icon nowrap">' +
                    '<img id="%s" class="imperator_tool_tip" src="%s" />' +
                  '</td>'+
                  '<td class="population_growth %s">' +
                    '<span id="%s" class="imperator_tool_tip">%s</span>' +
                  '</td>'
                  ).format(
                      updateable.getId(0),
                      IkaTools.Intl.formatInteger(Math.floor(populationData.population)),
                      updateable.getId(1),
                      populationData.percentClass,
                      updateable.getId(2),
                      populationData.percent,
                      updateable.getId(3),
                      populationData.icon,
                      populationData.happinessClass,
                      updateable.getId(4),
                      IkaTools.Intl.formatDecimal(populationData.growth, 2, true));
        }
        
        function makeRow(movements, city) {
          var transportLink = new Link('TransportGoods_%s'.format(city.getId())).toLocalView(
              IkaTools.Constants.View.TRANSPORT, 
              { 
                templateView: IkaTools.Constants.View.CITY_DETAIL, 
                destinationCityId: city.getId(),
              },
              function() {
                var go = !IkaTools.View.isActiveCity(city) && 
                    IkaTools.View.getCurrentCity().isOwn();
                if (go) {
                  openResourcesTabOnTransportClose = true;
                }
                return go;
              });
          var cityLink = new Link('ResourceTabToTownHall_%s'.format(city.getId()))
              .toCityView(city, IkaTools.Constants.View.TOWN_HALL,
                  { position: 0, cityId: city.getId() });
              
  
          var rowUpdateable = updateables.create('ResourceTableRow_%s'.format(city.getId()))
              .registerUpdate('cityChanged', 
                  function(element) {
                    if (IkaTools.View.isActiveCity(city)) {
                      element.addClass('current');
                    } else {
                      element.removeClass('current');
                    }
                  });
              
          return ('<tr id="%s" class="%s">' + 
                  '%s' + 
                  '<td class="action_points">%s</td>' + 
                  '<td class="actions">' +
                    '<a id="%s" class="imperator_link to_town_hall" ' +
                       'title="%s" href="javascript:void(0);"/>' +
                    '<a id="%s" class="imperator_link transport_goods" ' + 
                       'title="%s" href="javascript:void(0);"/>' +
                  '</td>' + 
                  '%s' + 
                  '%s' + 
                  '%s%s%s%s%s' + 
                  '</tr>'
              ).format(
                  rowUpdateable.getId(0),
                  IkaTools.View.isActiveCity(city) ? 'current' : '',
                  makeCityNameCells('resources', city),
                  IkaTools.Intl.formatInteger(city.getActionPoints()),
                  cityLink.getId(),
                  localizer.localize('actions','to_town_hall'),
                  transportLink.getId(),
                  localizer.localize('actions','transport_goods'),
                  makePopulationCells(city),
                  makeResearchCell(city),
                  makeResourceCells(movements, city, IkaTools.Constants.Resources.WOOD),
                  makeResourceCells(movements, city, IkaTools.Constants.Resources.WINE),
                  makeResourceCells(movements, city, IkaTools.Constants.Resources.MARBLE),
                  makeResourceCells(movements, city, IkaTools.Constants.Resources.GLASS),
                  makeResourceCells(movements, city, IkaTools.Constants.Resources.SULFUR));
        }
  
        function makeTotalsRow(cities) {
          function makeResourceCells(cities, resourceName) {
            var currentUpdateable =
                updateables.create(IkaTools.Utils.nextId('resource_current_total'));
  
            function makeCurrentContent() {
              var total = 0;
  
              $.each(cities, function(index, city) {
                var resource = city.getResource(resourceName);
                total += resource.getCurrent() || 0;
              });
              return IkaTools.Intl.formatInteger(total);
            }
            
            currentUpdateable.registerTickerUpdate(function(element) {
              element.html(makeCurrentContent());
            });
            
            var production = 0;
            var consumption = 0;

            $.each(cities, function(index, city) {
              var resource = city.getResource(resourceName);
              production += resource.getProduction() || 0;
              consumption += resource.getConsumption() || 0;
            });
            
            var rows = [makeResourceUseTableRow('+', 
                production * IkaTools.Constants.Time.SECONDS_PER_HOUR)];
            var footer = null;
            if (consumption) {
              rows.push(makeResourceUseTableRow('-',
                  consumption * IkaTools.Constants.Time.SECONDS_PER_HOUR));
              footer = [makeResourceUseTableRow('&sum;',
                  (production - consumption) * IkaTools.Constants.Time.SECONDS_PER_HOUR)];
            }
            
            toolTips.registerSimple('ResourceProductionTotal_' + resourceName, 
                makeResourceUseToolTip(
                    'skin/resources/icon_%s.png'.format(resourceName), rows, footer));
  
            return ('<td><span id="%s">%s</span></td>' + 
                    '<td id="ResourceProductionTotal_%s" class="imperator_tool_tip">' +
                      '<div class="resource_production">%s</div>' + 
                      '<div class="resource_consumption">%s</div>' +
                    '</td>').format(
                       currentUpdateable.getId(0), 
                       makeCurrentContent(),
                       resourceName,
                       IkaTools.Intl.formatInteger(
                           production * IkaTools.Constants.Time.SECONDS_PER_HOUR, true),
                       consumption ? IkaTools.Intl.formatInteger(
                           -consumption * IkaTools.Constants.Time.SECONDS_PER_HOUR) : '');
          }
          
          function makeResearchCell(cities) {
            var total = 0;
            var culturalGoods = 0;
            var isDemocracy = IkaTools.Constants.Government.DEMOCRACY ==
                IkaTools.EmpireData.getCivilizationData().getGovernment();

            $.each(cities, function(index, city) {
              total += city.getResearch() || 0;
              if (isDemocracy) {
                culturalGoods += city.getCulturalGoods();
              }
            });
            
            var rows = [makeResourceUseTableRow('+', total)];
            var footer = undefined;
            if (isDemocracy) {
              rows.push(makeResourceUseTableRow(
                  '<img src="skin/museum/icon32_culturalgood.png" height="10"/>', culturalGoods));
              footer = [makeResourceUseTableRow('&sum;', total + culturalGoods)];
            }
            
            toolTips.registerSimple('ResearchTotal',
                makeResourceUseToolTip(
                    'skin/layout/bulb-on.png', rows, footer));
            
            return ('<td id="ResearchTotal" class="research imperator_tool_tip">%s</td>')
                .format(IkaTools.Intl.formatInteger(total + culturalGoods, true));
          }
          
          function makePopulationCells(cities) {
            function getData() {
              var population = 0;
              var growth = 0;
              
              $.each(cities, function(index, city) {
                var populationData = city.getPopulationData();
                population += populationData.population || 0;
                growth += populationData.growth;
              });
              return {
                population: population,
                growth: growth,
              }
            }
            
            var updateable = updateables.create('population_total', 'population_growth_total');
                
            updateable.registerTickerUpdate(function(populationCell, growthCell) {
              var data = getData();
              populationCell.html(IkaTools.Intl.formatInteger(data.population));
              growthCell.html(IkaTools.Intl.formatDecimal(data.growth, 2, true));
            });
            
            var data = getData();
            return ('<td id="%s" class="population">%s</td>' + 
                    '<td/>' +
                    '<td id="%s" class="population_growth">%s</td>').format(
                        updateable.getId(0),
                        IkaTools.Intl.formatInteger(data.population),
                        updateable.getId(1),
                        IkaTools.Intl.formatDecimal(data.growth, 2, true));
          }
          
          return ('<tr><td colspan="4" class="totals_sigma_cell"/>' + 
                  '%s%s%s%s%s%s%s</tr>').format(
                     makePopulationCells(cities),
                     makeResearchCell(cities),
                     makeResourceCells(cities, IkaTools.Constants.Resources.WOOD),
                     makeResourceCells(cities, IkaTools.Constants.Resources.WINE),
                     makeResourceCells(cities, IkaTools.Constants.Resources.MARBLE),
                     makeResourceCells(cities, IkaTools.Constants.Resources.GLASS),
                     makeResourceCells(cities, IkaTools.Constants.Resources.SULFUR));
        }
        
        function makeResourceColGroup(resource) {
          return ('<colgroup class="resource resource_%s">' +
                    '<col class="resource_on_hand resource_%s"/>' + 
                    '<col class="resource_use resource_%s"/>' + 
                  '</colgroup>').format(
                      resource, resource, resource);
        }
        
        function makeCols() {
          return ('%s' +
                  '<colgroup class="actions">' + 
                    '<col class="actions"/>' + 
                  '</colgroup>' +
                  '<colgroup class="population">' + 
                    '<col class="population"/>' + 
                    '<col class="population_growth_icon"/>' + 
                    '<col class="population_growth"/>' + 
                  '</colgroup>' +
                  '<colgroup class="research">' + 
                    '<col class="research"/>' + 
                  '</colgroup>' +
                  //'<colgroup class="financial">' + 
                  //  '<col class="financial"/>' + 
                  //'</colgroup>' +
                  '%s%s%s%s%s')
                  .format(makeCityNameColGroup('<col class="action_points">'),
                          makeResourceColGroup('wood'),
                          makeResourceColGroup('wine'),
                          makeResourceColGroup('marble'),
                          makeResourceColGroup('crystal'),
                          makeResourceColGroup('sulfur'));
        }
        
        function makeTableHead() {
          toolTips.registerSimple('ResourcePopulationHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('misc','population')));
          toolTips.registerSimple('ResourcePopulationGrowthHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('misc','population_growth')));
          toolTips.registerSimple('ResourceResearchHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('misc','research')));
          toolTips.registerSimple('ResourceTableActionPoints',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('misc','action_points')));
          toolTips.registerSimple('ResourceWoodHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('resources','wood')));
          toolTips.registerSimple('ResourceWineHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('resources','wine')));
          toolTips.registerSimple('ResourceMarbleHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('resources','marble')));
          toolTips.registerSimple('ResourceCrystalHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('resources','glass')));
          toolTips.registerSimple('ResourceSulfurHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('resources','sulfur')));
          return ('<thead>' +
                  '<tr>%s' +
                    '<th id="ResourceTableActionPoints" ' + 
                        'class="action_points imperator_tool_tip">%s</th>' +
                    '<th class="actions">%s</th>' +
                    '<th colspan="1" id="ResourcePopulationHeader" ' +
                        'class="population imperator_tool_tip">%s</th>' +
                    '<th colspan="2" id="ResourcePopulationGrowthHeader" ' +
                        'class="population_growth imperator_tool_tip">%s</th>' +
                    '<th colspan="1" id="ResourceResearchHeader" ' + 
                        'class="research imperator_tool_tip">%s</th>' +
                    '<th colspan="2" id="ResourceWoodHeader" ' + 
                        'class="resource resource_wood imperator_tool_tip">%s</th>' +
                    '<th colspan="2" id="ResourceWineHeader" ' + 
                        'class="resource resource_wine imperator_tool_tip">%s</th>' +
                    '<th colspan="2" id="ResourceMarbleHeader" ' + 
                        'class="resource resource_marble imperator_tool_tip">%s</th>' +
                    '<th colspan="2" id="ResourceCrystalHeader" ' + 
                        'class="resource resource_crystal imperator_tool_tip">%s</th>' +
                    '<th colspan="2" id="ResourceSulfurHeader" ' + 
                        'class="resource resource_sulfur imperator_tool_tip">%s</th>' +
                  '</tr>' + 
                 '</thead>').format(
                     makeCityNameHeaderCells(),
                     localizer.localize('misc','action_points'),
                     localizer.localize('misc','actions'),
                     localizer.localize('misc','population'),
                     localizer.localize('misc','population_growth'),
                     localizer.localize('misc','research'),
                     localizer.localize('resources','wood'),
                     localizer.localize('resources','wine'),
                     localizer.localize('resources','marble'),
                     localizer.localize('resources','glass'),
                     localizer.localize('resources','sulfur'));
                     
        }
        
        var cities = IkaTools.EmpireData.getOwnCities();
        var movements = IkaTools.EmpireData.getCivilizationData().getMovements();
        return '%s%s<tbody>%s</tbody><tfoot>%s</tfoot>'.format(
            makeCols(),
            makeTableHead(),
            $.map(cities, makeRow.bind(null, movements)).join(''),
            makeTotalsRow(cities));
      }
      
      var tab = new Tab('resources', localizer.localize('misc','resources'), $(
          '<div class="imperator_overview">' +
            '<table class="overview" id="ImperatorOverviewResourceTable"/>' +
          '</div>'),
          'ImperatorOverviewResourceTable',
          function() {
            IkaTools.EmpireData.registerResourcesChangedHandler(function(changes) {
              tab.maybeRedraw(true);
            });
            IkaTools.EmpireData.registerBuildingsChangedHandler(function(changes) {
              var redraw = false;
              $.each(changes, function(index, change) {
                var type = change.building.getType();
                if (type == IkaTools.Constants.Buildings.TAVERN ||
                    type == IkaTools.Constants.Buildings.MUSEUM ||
                    type == IkaTools.Constants.Buildings.ACADEMY ||
                    type == IkaTools.Constants.Buildings.TOWN_HALL) {
                  redraw = true;
                }
              });
              tab.maybeRedraw(redraw);
            });
            IkaTools.EmpireData.registerCivilizationDataChangedHandler(function(changes) {
              tab.maybeRedraw(true);
            });
            IkaTools.EmpireData.registerMovementsChangedHandler(function(changes) {
              var redraw = false;
              $.each(changes, function(index, change) {
                var mission = change.movement.mission;
                if (mission == IkaTools.Constants.Movements.Mission.TRANSPORT || 
                    mission == IkaTools.Constants.Movements.Mission.PLUNDER) {
                  redraw = true;
                }
              });
              tab.maybeRedraw(redraw);
            });
          },
          makeTableContent);
  
      return tab.getTab();
    }
    
    function makeBuildingsTab() {    
      var BUILDING_ORDER = [
        { name: 'growth', 
          buildings: [IkaTools.Constants.Buildings.TOWN_HALL,
                      IkaTools.Constants.Buildings.PALACE,
                      IkaTools.Constants.Buildings.GOVERNORS_RESIDENCE,
                      IkaTools.Constants.Buildings.TAVERN,
                      IkaTools.Constants.Buildings.MUSEUM] },
        { name: 'research', 
          buildings: [IkaTools.Constants.Buildings.ACADEMY,
                      IkaTools.Constants.Buildings.WORKSHOP,
                      IkaTools.Constants.Buildings.TEMPLE] },
        { name: 'diplomacy', 
          buildings: [IkaTools.Constants.Buildings.EMBASSY] },
        { name: 'trading', 
          buildings: [IkaTools.Constants.Buildings.WAREHOUSE,
                      IkaTools.Constants.Buildings.DUMP,
                      IkaTools.Constants.Buildings.TRADING_PORT,
                      IkaTools.Constants.Buildings.TRADING_POST] },
        { name: 'military',
          buildings: [IkaTools.Constants.Buildings.WALL,
                      IkaTools.Constants.Buildings.HIDEOUT,
                      IkaTools.Constants.Buildings.BARRACKS,
                      IkaTools.Constants.Buildings.SHIPYARD,
                      IkaTools.Constants.Buildings.PIRATE_FORTRESS] },
        { name: 'wood', 
          buildings: [IkaTools.Constants.Buildings.FORESTER,
                      IkaTools.Constants.Buildings.CARPENTER] },
        { name: 'wine', 
          buildings: [IkaTools.Constants.Buildings.WINERY,
                      IkaTools.Constants.Buildings.WINE_PRESS] },
        { name: 'marble', 
          buildings: [IkaTools.Constants.Buildings.STONEMASON,
                      IkaTools.Constants.Buildings.ARCHITECT] },
        { name: 'crystal', 
          buildings: [IkaTools.Constants.Buildings.GLASSBLOWER,
                      IkaTools.Constants.Buildings.OPTICIAN] },
        { name: 'sulfur', 
          buildings: [IkaTools.Constants.Buildings.ALCHEMISTS_TOWER,
                      IkaTools.Constants.Buildings.FIREWORK_TEST_AREA] },
      ];
  
      function makeTableContent() {
        var updateables = this.updateables;
        
        var empireBuildingCounts = {};
  
        $.each(IkaTools.EmpireData.getOwnCities(), function(index, city) {
          var cityBuildingCounts = {};
          $.each(city.getBuildings(), function(index, building) {
            if (!building.isEmpty()) {
              cityBuildingCounts[building.getType()] =
                  (cityBuildingCounts[building.getType()] || 0) + 1;
            }
          });
          $.each(cityBuildingCounts, function(key, value) {
            empireBuildingCounts[key] = Math.max(
                empireBuildingCounts[key] || 0, cityBuildingCounts[key]);
          });
        });
  
        function makeCols(type) {
          var count = empireBuildingCounts[type];
          if (count) {
            var html = '<col class="building building_%s"/>'.format(type);
            for (var i = 1; i < count; i++) {
              html += '<col class="building building_additional building_%s"/>'.format(type);
            }
            return html;
          } else {
            return '';
          }
        }
  
        function makeColGroup(info) {
          var group = $.map(info.buildings, makeCols).join('');
          return !group ? '' :
              '<colgroup class="buildings buildings_%s">%s</colgroup>'.format(
                  info.name, group);
        }
  
        function makeTableHeaderCells(type) {
          var count = empireBuildingCounts[type];
          var displayName = localizer.localize('buildings', type);
          var toolTip = toolTips.registerSimple('ImperatorBuildingHeader_' + type, 
              $('<div class="nowrap">%s</div>'.format(displayName)));
          return !count ? '' :
              ('<th class="building building_%s imperator_tool_tip" ' +
                  'id="ImperatorBuildingHeader_%s" colspan="%s">%s</td>').format(
                   type, 
                   type,
                   count, 
                   displayName);
        }
  
        function makeTableHeadContent() {
          var displayName = localizer.localize('misc','building_spots');
          toolTips.registerSimple('ImperatorBuildingHeaderBuildingSpots',
              '<div class="nowrap">%s</div>'.format(displayName));
          return ('%s' + 
                  '<th class="actions">%s</th>' +
                  '<th class="building building_spots imperator_tool_tip" ' +
                         'id="ImperatorBuildingHeaderBuildingSpots">%s</th>' + 
                  '%s').format(
              makeCityNameHeaderCells(),
              localizer.localize('misc','actions'),
              displayName,
              $.map(BUILDING_ORDER, function(info) {
                return $.map(info.buildings, makeTableHeaderCells);
              }).join(''));
        }
  
        function makeTableCell(city, building) {
          var link = new Link('Building_%s_%s'.format(city.getId(), building.getPosition()))
              .toCityView(city, building.getType(),
                  { position: building.getPosition(), cityId: city.getId() });
          var isUpgrading = building.isUpgrading();
          var toolTip = '';
          if (!isUpgrading && building.isMaxLevel()) {
            toolTips.deregister(link.getId());
          } else if (!building.isMaxLevel()) {
            toolTips.registerRefreshable(link.getId(), function() {
              function makeCostRow(resource) {
                var required = costs[resource];
                if (!required) {
                  return '';
                }

                var onHand = city.getResource(resource).getCurrent();

                return ('<tr>' + 
                          '<td class="resource_icon">' + 
                            '<img src="skin/resources/icon_%s.png">' + 
                          '</td>' +
                          '<td class="resource_cost">%s</td>' + 
                          '<td class="resource_missing">%s</td>' + 
                        '</tr>').format(
                            resource,
                            IkaTools.Intl.formatInteger(required),
                            onHand >= required 
                                ? '<img src="skin/interface/check_mark_17px.png"/>' 
                                : IkaTools.Intl.formatInteger(onHand - required, true));
              }
              
              var upgradingHtml = '';
              if (isUpgrading) {
                upgradingHtml = ('<div class="imperator_tool_tip_title">%s</div>' +
                                 '<div class="nowrap">%s (%s)</div>').format(
                                     localizer.localize('misc','constructing'),
                                     IkaTools.Intl.formatRemainingTime(
                                         building.getRemainingUpgradeTime()),
                                     IkaTools.Intl.formatAbsoluteTime(
                                         building.getCompletionTime()));
              }
                
              var costs = building.getUpgradeCosts();
                
              return ('%s<table class="building_upgrade_costs">' +
                        '<thead class="imperator_tool_tip_title">' + 
                          '<tr><th colspan="3">%s</th></tr>' +
                        '</thead>' +
                        '<tbody>' + 
                          '%s%s%s%s%s' + 
                        '</tbody>' +
                        '<tfoot>' +
                          '<tr>' +
                            '<td class="resource_icon">' + 
                              '<img src="skin/resources/icon_time.png"/>' + 
                            '</td>' + 
                            '<td class="nowrap" colspan="2">%s</td>' + 
                          '</tr>' + 
                        '</tfoot>' + 
                      '<table>')
                  .format(
                      upgradingHtml,
                      isUpgrading ? 
                          localizer.localize('misc','next_level_cost') :
                          localizer.localize('misc','resource_cost'),
                      makeCostRow(IkaTools.Constants.Resources.WOOD),
                      makeCostRow(IkaTools.Constants.Resources.WINE),
                      makeCostRow(IkaTools.Constants.Resources.MARBLE),
                      makeCostRow(IkaTools.Constants.Resources.GLASS),
                      makeCostRow(IkaTools.Constants.Resources.SULFUR),
                      IkaTools.Intl.formatRemainingTime(costs.time));
            });
          }
          return ('<td class="%s">%s' + 
                   '<a id="%s" class="imperator_link imperator_tool_tip" ' + 
                       'href="javascript:void(0);">' + 
                     '%s%s' + 
                   '</a>' +
                 '</td>').format(
              isUpgrading ? 'building_upgrading' : '',
              toolTip,
              link.getId(), 
              building.getLevel(), 
              isUpgrading ? ('&raquo;' + (building.getLevel() + 1)) : '');
        }
  
        function makeTableCells(city, type) {
          var count = empireBuildingCounts[type];
          var html = '';
          if (count) {
            var buildings = city.getBuildingsByType(type);
            for (var i = 0; i < count; i++) {
              if (i < buildings.length) {
                html += makeTableCell(city, buildings[i]);
              } else {
                html += '<td/>';
              }
            }
          }
          return html;
        }
  
        function makeRow(city) {
          var buildingSpots = city.getBuildingsByType('').length;
          var rowUpdateable = updateables.create('BuildingsTableRow_%s'.format(city.getId()))
              .registerUpdate('cityChanged',
                  function(element) {
                    if (IkaTools.View.isActiveCity(city)) {
                      element.addClass('current');
                    } else {
                      element.removeClass('current');
                    }
                  });
          var cityLink = new Link('BuildingTabToCity_%s'.format(city.getId()))
              .toCityView(city, undefined, { },
                  function() {
                    makePopup().close();
                    return true;
                  });
          var transportLink = new Link('BuildingTabTransportGoods_%s'.format(city.getId()))
              .toLocalView(
                    IkaTools.Constants.View.TRANSPORT, 
                    { 
                      templateView: IkaTools.Constants.View.CITY_DETAIL, 
                      destinationCityId: city.getId(),
                    },
                    function() {
                      var go = !IkaTools.View.isActiveCity(city) && 
                          IkaTools.View.getCurrentCity().isOwn();
                      if (go) {
                        openBuildingsTabOnTransportClose = true;
                      }
                      return go;
                    });
              
          return ('<tr id="%s" class="%s">%s' + 
                    '<td class="actions">' + 
                      '<a id="%s" class="imperator_link to_city_view" ' +
                          'title="%s" href="javascript:void(0);"/>' +
                      '<a id="%s" class="imperator_link transport_goods" ' + 
                          'title="%s" href="javascript:void(0);"/>' +
                    '</td>' +
                    '<td class="building building_spots">%s</td>' + 
                    '%s' +
                  '</tr>').format(
                      rowUpdateable.getId(0),
                      (IkaTools.View.isActiveCity(city) ? 'current' : ''),
                      makeCityNameCells('buildings', city), 
                      cityLink.getId(),
                      localizer.localize('actions','to_city_view'),
                      transportLink.getId(),
                      localizer.localize('actions','transport_goods'),
                      buildingSpots > 0 ? buildingSpots : '',
                      $.map(BUILDING_ORDER, function(info) {
                        return $.map(info.buildings, makeTableCells.bind(null, city));
                      }).join(''));
        }
  
        return ('%s<colgroup class="actions"><col class="actions"/></colgroup>' +
                '%s<thead>%s</thead><tbody>%s</tbody>').format(
                   makeCityNameColGroup('<col class="building building_spots">'),
                   $.map(BUILDING_ORDER, makeColGroup).join(''),
                   makeTableHeadContent(),
                   $.map(IkaTools.EmpireData.getOwnCities(), makeRow).join(''));
      }
      
      var tab = new Tab('buildings', localizer.localize('misc','buildings'), $(
          '<div class="imperator_overview">' +
            '<table class="overview" id="ImperatorOverviewBuildingsTable"/>' +
          '</div>'),
          'ImperatorOverviewBuildingsTable',
          function() {
            IkaTools.EmpireData.registerBuildingsChangedHandler(function(changes) {
              tab.maybeRedraw(true);
            });
          },
          makeTableContent);
  
      return tab.getTab();
    }

    var UNIT_ORDER = [
      { name: 'army_front_line', 
        units: [IkaTools.Constants.Military.HOPLITE, 
                IkaTools.Constants.Military.STEAM_GIANT]},
      { name: 'army_flank', 
        units: [IkaTools.Constants.Military.SPEARMAN,
                IkaTools.Constants.Military.SWORDSMAN]},
      { name: 'army_ranged', 
        units: [IkaTools.Constants.Military.SLINGER,
                IkaTools.Constants.Military.ARCHER,
                IkaTools.Constants.Military.GUNNER]},
      { name: 'army_seige', 
        units: [IkaTools.Constants.Military.BATTERING_RAM,
                IkaTools.Constants.Military.CATAPULT,
                IkaTools.Constants.Military.MORTAR]},
      { name: 'army_flying',
        units: [IkaTools.Constants.Military.GYROCOPTER,
                IkaTools.Constants.Military.BALLOON_BOMBADIER]},
      { name: 'army_support', 
        units: [IkaTools.Constants.Military.COOK,
                IkaTools.Constants.Military.DOCTOR]},
      { name: 'navy_front_line', 
        units: [IkaTools.Constants.Military.FLAME_THROWER,
                IkaTools.Constants.Military.STEAM_RAM]},
      { name: 'navy_flank', 
        units: [IkaTools.Constants.Military.RAM_SHIP]},
      { name: 'navy_ranged',
        units: [IkaTools.Constants.Military.BALLISTA_SHIP,
                IkaTools.Constants.Military.CATAPULT_SHIP,
                IkaTools.Constants.Military.MORTAR_SHIP]},
      { name: 'navy_seige', 
        units: [IkaTools.Constants.Military.SUBMARINE,
                IkaTools.Constants.Military.ROCKET_SHIP]},
      { name: 'navy_flying', 
        units: [IkaTools.Constants.Military.PADDLE_SPEED_SHIP,
                IkaTools.Constants.Military.BALLOON_CARRIER]},
      { name: 'navy_support', 
        units: [IkaTools.Constants.Military.TENDER]}
    ];
      
    function makeMilitaryTab() {
      function makeTableContent() {
        var cities = IkaTools.EmpireData.getCities();
        
        var updateables = this.updateables;
        var empireHasTroopType = {};
  
        $.each(cities, function(index, city) {
          $.each(city.getMilitary().getPresent().getCounts(), function(unit, count) {
            if (count) {
              empireHasTroopType[unit] = true;
            }
          });
          $.each(city.getMilitary().getTrainingBatches(), function(index, batch) {
            $.each(batch.getUnits().getCounts(), function(unit, count) {
              if (count) {
                empireHasTroopType[unit] = true;
              }
            });
          });
        });
        $.each(IkaTools.EmpireData.getCivilizationData().getMovements(), 
            function(index, movement) {
              $.each(movement.getUnits().getCounts(), function(unit, count) {
                if (count) {
                  empireHasTroopType[unit] = true;
                }
              });
            });
  
        function makeCol(type) {
          return !empireHasTroopType[type] ? '' :
             '<col class="military military_%s"/>'.format(type);
        }
  
        function makeColGroup(info) {
          var group = $.map(info.units, makeCol).join('');
          return !group ? '' :
              '<colgroup class="military military_%s">%s</colgroup>'.format(
                  info.name, group);
        }
  
        function makeTableHeaderCell(type) {
          var displayName = localizer.localize('units', type);
          var toolTip = toolTips.registerSimple('ImperatorMilitaryHeader_' + type,
              '<div class="nowrap">%s</div>'.format(displayName));
          return !empireHasTroopType[type] ? '' :
              ('<th class="military military_%s imperator_tool_tip" ' +
                  'id="ImperatorMilitaryHeader_%s">%s</td>').format(
                   type, 
                   type, 
                   displayName);
        }
  
        function makeTableHeadContent() {
          toolTips.registerSimple('MilitaryTableActionPoints',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('misc','action_points')));
          return ('%s<th id="MilitaryTableActionPoints" ' + 
                         'class="action_points imperator_tool_tip">%s</th>' + 
                  '<th class="actions">%s</th>%s').format(
              makeCityNameHeaderCells(true),
              localizer.localize('misc','action_points'),
              localizer.localize('misc','actions'),
              $.map(UNIT_ORDER, function(info) {
                return $.map(info.units, makeTableHeaderCell);
              }).join(''));
        }
  
        function makeTableCell(city, military, movements, type) {
          var cityId = city.getId();
          var count = military.getPresent().getCount(type);

          function isDeploymentCountableMovement(movement) {
            if (movement.getUnits().getCount(type) > 0) {
              var mission = movement.getMission();
              var stage = movement.getStage();
              if (mission == IkaTools.Constants.Movements.Mission.DEPLOY_ARMY ||
                  mission == IkaTools.Constants.Movements.Mission.DEPLOY_NAVY) {
                if (stage == IkaTools.Constants.Movements.Stage.LOADING ||
                    stage == IkaTools.Constants.Movements.Stage.EN_ROUTE) {
                  return movement.getTargetCityId() == cityId;
                }
                if (stage == IkaTools.Constants.Movements.Stage.RETURNING) {
                  return movement.getOriginCityId() == cityId;
                }
              }
            }
            return false;
          }
          
          function isPlunderCountableMovement(movement) {
            if (movement.getUnits().getCount(type) > 0) {
              var mission = movement.getMission();
              if (mission == IkaTools.Constants.Movements.Mission.PLUNDER) {
                return movement.getOriginCityId() == cityId;
              }
            }
            return false;
          }
          
          var trainingBatches = military.getTrainingBatches();
          var trainingCount = 0;
          $.each(trainingBatches, function countTraining(index, batch) {
            trainingCount += batch.getUnits().getCount(type) || 0;
          });

          var hasIncomingDeployments = false;
          $.each(movements, function isIncomingDeployment(index, movement) {
            var mission = movement.getMission();
            var stage = movement.getStage();
            if (mission == IkaTools.Constants.Movements.Mission.DEPLOY_ARMY ||
                mission == IkaTools.Constants.Movements.Mission.DEPLOY_NAVY) {
              if (stage == IkaTools.Constants.Movements.Stage.LOADING ||
                  stage == IkaTools.Constants.Movements.Stage.EN_ROUTE) {
                hasIncomingDeployments = true;
              }
              if (stage == IkaTools.Constants.Movements.Stage.RETURNING) {
                hasIncomingDeployments = true;
              }
            }
          });          
          var deployingCount = 0;
          $.each(movements, function countDeploying(index, movement) {
            if (isDeploymentCountableMovement(movement)) {
              deployingCount += movement.getUnits().getCount(type) || 0;
            }
          });
          
          var plunderingCount = 0;
          $.each(movements, function countPlundering(index, movement) {
            if (isPlunderCountableMovement(movement)) {
              plunderingCount += movement.getUnits().getCount(type) || 0;
            }
          });
          
          var trainingDivId = 'MilitaryTraining_%s_%s'.format(city.getId(), type);
          if (trainingCount) {
            var isArmy = IkaTools.Constants.UnitData[type].isArmy;
            toolTips.registerRefreshable(trainingDivId, function() {
              return ('<table class="training_units_tool_tip">' + 
                        '<thead>' + 
                          '<tr>' + 
                            '<th>' + 
                              '<img src="skin/characters/%s%s_faceright.png" ' +
                                   '%s="15" />' + 
                            '</th>' + 
                            '<th>%s</th>' +
                          '</tr>' + 
                        '</thead>' + 
                        '<tbody>%s</tbody>' + 
                      '</table').format(
                  isArmy ? 'military/x60_y60/y60_' : 'fleet/60x60/',
                  type,
                  isArmy ? 'height' : 'width',
                  localizer.localize('misc','training'),
                  $.map(trainingBatches, function makeTrainingToolTipRow(batch) {
                    var count = batch.getUnits().getCount(type);
                    if (count) {
                      return '<tr><td class="training_count">%s</td><td>%s</td></tr>'.format(
                          IkaTools.Intl.formatInteger(count, true),
                          IkaTools.Intl.formatRemainingTime(
                              batch.getCompletionTime() - IkaTools.View.gameTimeNow()));
                    } else {
                      return '';
                    }
                  }).join(''));
            });
          } else {
            toolTips.deregister(trainingDivId);
          }
          
          var deployingDivId = 'MilitaryDeployment_%s_%s'.format(city.getId(), type);
          if (deployingCount) {
            var isArmy = IkaTools.Constants.UnitData[type].isArmy;
            toolTips.registerRefreshable(deployingDivId, function() {
              return ('<table class="deploying_units_tool_tip">' + 
                        '<thead>' + 
                          '<tr>' + 
                            '<th>' + 
                              '<img src="skin/characters/%s%s_faceright.png" ' +
                                   '%s="15" />' + 
                            '</th>' + 
                            '<th>%s</th>' +
                          '</tr>' + 
                        '</thead>' + 
                        '<tbody>%s</tbody>' + 
                      '</table').format(
                  isArmy ? 'military/x60_y60/y60_' : 'fleet/60x60/',
                  type,
                  isArmy ? 'height' : 'width',
                  localizer.localize('misc','deploying'),
                  $.map(movements, function makeDeployingToolTipRow(movement) {
                    var count = movement.getUnits().getCount(type);
                    if (isDeploymentCountableMovement(movement)) {
                      return '<tr><td class="deploying_count">%s</td><td>%s</td></tr>'.format(
                          IkaTools.Intl.formatInteger(count, true),
                          IkaTools.Intl.formatRemainingTime(
                              movement.getArrivalTime() - IkaTools.View.gameTimeNow()));
                    } else {
                      return '';
                    }
                  }).join(''));
            });
          } else {
            toolTips.deregister(deployingDivId);
          }
          
          var plunderingDivId = 'MilitaryPludering_%s_%s'.format(city.getId(), type);
          if (plunderingCount) {
            var isArmy = IkaTools.Constants.UnitData[type].isArmy;
            toolTips.registerRefreshable(plunderingDivId, function() {
              return ('<table class="plundering_units_tool_tip">' + 
                        '<thead>' + 
                          '<tr>' + 
                            '<th>' + 
                              '<img src="skin/characters/%s%s_faceright.png" ' +
                                   '%s="15" />' + 
                            '</th>' + 
                            '<th>%s</th>' +
                          '</tr>' + 
                        '</thead>' + 
                        '<tbody>%s</tbody>' + 
                      '</table').format(
                  isArmy ? 'military/x60_y60/y60_' : 'fleet/60x60/',
                  type,
                  isArmy ? 'height' : 'width',
                  localizer.localize('misc','plundering'),
                  $.map(movements, function makeDeployingToolTipRow(movement) {
                    var count = movement.getUnits().getCount(type);
                    if (isPlunderCountableMovement(movement)) {
                      return '<tr><td class="plundering_count">%s</td><td>%s</td></tr>'.format(
                          IkaTools.Intl.formatInteger(count, true),
                          IkaTools.Intl.formatRemainingTime(
                              movement.getArrivalTime() - IkaTools.View.gameTimeNow()));
                    } else {
                      return '';
                    }
                  }).join(''));
            });
          } else {
            toolTips.deregister(plunderingDivId);
          }
          
          return !empireHasTroopType[type] ? '' : 
              ('<td class="military military_%s">' + 
                 '<div>%s</div>' + 
                 '<div id="%s" class="military_training imperator_tool_tip">%s</div>' + 
                 '<div id="%s" class="military_deploying imperator_tool_tip">%s</div>' +
                 '<div id="%s" class="military_plundering imperator_tool_tip">%s</div>' +
               '</td>').format(
                  type, 
                  count ? IkaTools.Intl.formatInteger(count) : '&nbsp;',
                  trainingDivId,
                  trainingCount ? IkaTools.Intl.formatInteger(trainingCount, true) 
                                : (trainingBatches.length ? '&nbsp;' : ''),
                  deployingDivId,
                  deployingCount ? IkaTools.Intl.formatInteger(deployingCount, true) 
                                 : (hasIncomingDeployments ? '&nbsp;' : ''),
                  plunderingDivId,
                  plunderingCount ? 
                      IkaTools.Intl.formatInteger(plunderingCount, true) : '');
        }
        
        function makeActionsCell(city) {
          var deployTroopsLink = new Link('DeployArmy_%s'.format(city.getId())).toLocalView(
              IkaTools.Constants.View.DEPLOY, 
              { 
                templateView: IkaTools.Constants.View.CITY_DETAIL,
                destinationCityId: city.getId(),
                deploymentType: 'army',
              },
              function() {
                var go = !IkaTools.View.isActiveCity(city);
                if (go) {
                  openMilitaryTabOnDeploymentClose = true;
                }
                return go;
              });
          var deployNavyLink = new Link('DeployNavy_%s'.format(city.getId())).toLocalView(
              IkaTools.Constants.View.DEPLOY,
              { 
                templateView: IkaTools.Constants.View.CITY_DETAIL,
                destinationCityId: city.getId(),
                deploymentType: 'fleet',
              },
              function() {
                var go = !IkaTools.View.isActiveCity(city);
                if (go) {
                  openMilitaryTabOnDeploymentClose = true;
                }
                return go;
              });
              
          var barracksLinkHtml = ''
          var shipyardLinkHtml = '';
          
          var barracks = city.getBuildingByType(IkaTools.Constants.Buildings.BARRACKS);
          var shipyard = city.getBuildingByType(IkaTools.Constants.Buildings.SHIPYARD);
          
          if (city.isOwn() && barracks) {
            var barracksLink = new Link('MilitaryBarracks_%s'.format(city.getId()))
                .toCityView(city, IkaTools.Constants.View.BARRACKS, 
                    { position: barracks.getPosition(), cityId: city.getId() });
            barracksLinkHtml = ('<a id="%s" class="imperator_link to_barracks" ' + 
                                'title="%s" href="javascript:void(0);"></a>').format(
                                    barracksLink.getId(),
                                    localizer.localize('actions','to_barracks'));
          }
          
          if (city.isOwn() && shipyard) {
            var shipyardLink = new Link('MilitaryShipyard_%s'.format(city.getId()))

                .toCityView(city, IkaTools.Constants.View.SHIPYARD, 
                    { position: shipyard.getPosition(), cityId: city.getId() });
            shipyardLinkHtml = ('<a id="%s" class="imperator_link to_shipyard" ' + 
                                'title="%s" href="javascript:void(0);"></a>').format(
                                    shipyardLink.getId(),
                                    localizer.localize('actions','to_shipyard'));
          }
          return ('<td class="actions">' + 
                    '<a id="%s" class="imperator_link deploy_army" ' + 
                       'title="%s" href="javascript:void(0);"></a>' +
                    '<a id="%s" class="imperator_link deploy_navy" ' +
                       'title="%s" href="javascript:void(0);"></a>' + 
                    '%s%s' +
                  '</td>').format(
                      deployTroopsLink.getId(),
                      localizer.localize('actions','deploy_army'),
                      deployNavyLink.getId(),
                      localizer.localize('actions','deploy_navy'),
                      barracksLinkHtml,
                      shipyardLinkHtml);
        }
  
        function makeRow(movements, city) {
          var rowUpdateable = updateables.create('MilitaryTableRow_%s'.format(city.getId()))
              .registerUpdate('cityChanged', 
                  function(element) {
                    if (IkaTools.View.isActiveCity(city)) {
                      element.addClass('current');
                    } else {
                      element.removeClass('current');
                    }
                  });
          
          return ('<tr id="%s" class="%s">' + 
                    '%s' +
                    '<td class="action_points">%s</td>' +
                    '%s' +
                    '%s' + 

                  '</tr>')
              .format(
                  rowUpdateable.getId(0),
                  (IkaTools.View.isActiveCity(city) ? 'current' : ''),
                  makeCityNameCells('military', city, true), 
                  IkaTools.Intl.formatInteger(city.getActionPoints()),
                  makeActionsCell(city),
                  $.map(UNIT_ORDER, function(info) {
                    return $.map(info.units, makeTableCell.bind(
                        null, city, city.getMilitary(), movements));
                  }).join(''));
        }
        
        function makeSummaryCell(type) {
          if (!empireHasTroopType[type]) {
            return '';
          }
          var count = 0;
          $.each(cities, function(index, city) {
            count += city.getMilitary().getPresent().getCount(type) || 0;
          });
          return '<td>%s</td>'.format(IkaTools.Intl.formatInteger(count));
        }
        
        function makeSummaryRow(cities) {
          return '<tr><td colspan="3" class="totals_sigma_cell"/>%s</tr>'.format(
              $.map(UNIT_ORDER, function(info) {
                return $.map(info.units, makeSummaryCell);
              }).join(''));
        }
  
        return '%s%s%s<thead>%s</thead><tbody>%s</tbody><tfoot>%s</tfoot>'.format(
            makeCityNameColGroup('<col class="action_points">', true),
            '<colgroup class="actions"><col class="actions"/></colgroup>',
            $.map(UNIT_ORDER, makeColGroup).join(''),
            makeTableHeadContent(),
            $.map(cities, makeRow.bind(
                null, IkaTools.EmpireData.getCivilizationData().getMovements())).join(''),
            makeSummaryRow(cities));
      }
      
      var tab = new Tab('military', localizer.localize('misc','military'), $(
          '<div class="imperator_overview">' +
            '<table class="overview" id="ImperatorOverviewMilitaryTable"/>' +
          '</div>'),
          'ImperatorOverviewMilitaryTable',
          function() {
            IkaTools.EmpireData.registerMilitaryChangedHandler(function(changes) {
              tab.maybeRedraw(true);
            });
            IkaTools.EmpireData.registerResourcesChangedHandler(function(changes) {
              var redraw = false;
              $.each(changes, function(index, change) {
                if (change.type == IkaTools.Constants.Resources.ACTION_POINTS) {
                  redraw = true;
                }
              });
              tab.maybeRedraw(redraw);
            });
            IkaTools.EmpireData.registerMovementsChangedHandler(function(changes) {
              var redraw = false;
              $.each(changes, function(index, change) {
                var mission = change.movement.getMission();
                if (mission == IkaTools.Constants.Movements.Mission.DEPLOY_ARMY ||
                    mission == IkaTools.Constants.Movements.Mission.DEPLOY_NAVY || 
                    mission == IkaTools.Constants.Movements.Mission.PLUNDER) {
                  redraw = true;
                }
              });
              tab.maybeRedraw(redraw);
            });
          },
          makeTableContent);
     
      return tab.getTab();
    }

    function makeEspionageTab() {
      function makeTableContent() {
        var updateables = this.updateables;

        function renderTarget(target) {
          var player = target.getPlayer();
          var alliance = player.getAlliance();

          // TODO: Add predicate when no spies.
          var cityLink = new Link('EspionageCityLink_%s'.format(target.getId()))
              .toIkariamPage({ view: IkaTools.Constants.BaseView.CITY, cityId: target.getId() });
          var cityLinkHtml = ('<a id="%s" class="imperator_link espionage_to_city_view player_state_%s" ' + 
                              'title="%s" href="javascript:void(0);">%s</a>').format(
                                  cityLink.getId(),
                                  player.getState(),
                                  localizer.localize('actions','to_city_view'),
                                  target.getName());
          var occupierHtml = '';
          if (target.getOccupier()) {
            occupierHtml = ('<img id="EspionageOccupier_%s" ' + 
                            '     class="espionage_occupier imperator_tool_tip" ' + 
                            '     src="skin/img/island/soldat_red.png" />').format(
                                target.getId());
            toolTips.registerSimple('EspionageOccupier_%s'.format(target.getId()),
                '<div class="nowrap">%s %s</div>'.format(
                    localizer.localize('espionage','occupied_by'), target.getOccupier().getName()));
          }

          var blockaderHtml = '';
          if (target.getBlockader()) {
            blockaderHtml = ('<img id="EspionageBlockader_%s" ' + 
                            '     class="espionage_blockader imperator_tool_tip" ' + 
                            '     src="skin/img/island/schiff_red.png" />').format(
                                target.getId());
            toolTips.registerSimple('EspionageBlockader_%s'.format(target.getId()),
                '<div class="nowrap">%s %s</div>'.format(
                    localizer.localize('espionage','blockaded_by'), target.getBlockader().getName()));
          }                  

          var allianceLinkHtml = '';
          if (alliance) {
            var allianceLink = new Link('EspionageAllianceLink_%s'.format(target.getId()))
                .toLocalView(IkaTools.Constants.View.ALLIANCE_PAGE, { allyId: alliance.getId()});
            var allianceLinkHtml = ('[<a id="%s" class="imperator_link" ' + 
                                    'title="%s" href="javascript:void(0);">%s</a>]').format(
                                        allianceLink.getId(),
                                        localizer.localize('actions','view_alliance_page'),
                                        alliance.getName());
          }
          var playerLink = new Link('EspionagePlayerLink_%s'.format(target.getId()))
              .toLocalView(IkaTools.Constants.View.HIGH_SCORE, { searchUser: player.getName() });
          var playerLinkHtml = ('<a id="%s" class="imperator_link player_state_%s" ' + 
                                'title="%s" href="javascript:void(0);">%s</a> %s').format(
                                    playerLink.getId(),
                                    player.getState(),
                                    localizer.localize('actions','view_high_score'),
                                    player.getName(),
                                    allianceLinkHtml);
                                    
          var islandLink = new Link('EspionageIslandLink_%s'.format(target.getId()))
              .toIkariamPage({ view: IkaTools.Constants.BaseView.ISLAND, cityId: target.getId() });
          var islandLinkHtml = ('<a id="%s" class="imperator_link espionage_to_island_view" ' + 
                                'title="%s" href="javascript:void(0);">[%s:%s]</a>').format(
                                   islandLink.getId(),
                                   localizer.localize('actions','to_island_view'),
                                   target.getIslandCoordinates()[0], target.getIslandCoordinates()[1]);

          var spyActionLink = new Link('EspionageSpyActionLink_%s'.format(target.getId()))
              .toIkariamPage(
                  { view : IkaTools.Constants.BaseView.CITY, cityId: target.getId() },
                  IkaTools.View.makeIkariamLoadLocalPageAnchor(
                      { view: IkaTools.Constants.View.SPY_MISSION, targetCityId: target.getId() }));
          var spyActionLinkHtml = ('<a id="%s" class="imperator_link spy_mission" ' +
                                   'title="%s" href="javascript:void(0);"></a>').format(
                                       spyActionLink.getId(),
                                       localizer.localize('actions','spy_mission'));
                                       
          var pillageLink = new Link('EspionagePillageLink_%s'.format(target.getId()))
              .toIkariamPage(
                  { view: IkaTools.Constants.BaseView.ISLAND, cityId: target.getId() },
                  IkaTools.View.makeIkariamLoadLocalPageAnchor(
                      { view: IkaTools.Constants.View.PILLAGE, destinationCityId: target.getId() }, true));
          var pillageLinkHtml = ('<a id="%s" class="imperator_link pillage_mission" ' +
                                 'title="%s" href="javascript:void(0);"></a>').format(
                                     pillageLink.getId(),
                                     localizer.localize('actions','pillage'));
                                       
          var blockadeLink = new Link('EspionageBlockageLink_%s'.format(target.getId()))
              .toIkariamPage(
                  { view: IkaTools.Constants.BaseView.ISLAND, cityId: target.getId() },
                  IkaTools.View.makeIkariamLoadLocalPageAnchor(
                      { view: IkaTools.Constants.View.BLOCKADE, destinationCityId: target.getId() }, true));
          var blockadeLinkHtml = ('<a id="%s" class="imperator_link blockade_mission" ' +
                                  'title="%s" href="javascript:void(0);"></a>').format(
                                      blockadeLink.getId(),
                                      localizer.localize('actions','blockade'));

          var sendSpyLink = new Link('EspionageSendSpyLink_%s'.format(target.getId()))
              .toLocalView(IkaTools.Constants.View.SEND_SPY, 
                  { isMission: 1, destinationCityId: target.getId() });
          var sendSpyLinkHtml = ('<a id="%s" class="imperator_link send_spy_mission" ' +
                                 'title="%s" href="javascript:void(0);"></a>').format(
                                      sendSpyLink.getId(),
                                      localizer.localize('actions','send_spy'));

          var occupyLink = new Link('EspionageOccupyLink_%s'.format(target.getId()))
              .toIkariamPage(
                  { view: IkaTools.Constants.BaseView.ISLAND, cityId: target.getId() },
                  IkaTools.View.makeIkariamLoadLocalPageAnchor(
                      { view: IkaTools.Constants.View.OCCUPY, destinationCityId: target.getId() }, true));
          var occupyLinkHtml = ('<a id="%s" class="imperator_link occupy_mission" ' +
                                'title="%s" href="javascript:void(0);"></a>').format(
                                    occupyLink.getId(),
                                    localizer.localize('actions','occupy'));
          var removeTargetLink = new Link('EspionageRemoveTarget_%s'.format(target.getId()))
              .toFunction(function removeTarget() {
                target.remove();
              });
          var removeTargetHtml = ('<a id="%s" class="imperator_link remove_espionage_target" ' +
                                  'title="%s" href="javascript:void(0);"></a>').format(
                                      removeTargetLink.getId(),
                                      localizer.localize('espionage','remove_target'));

          function renderTravelTime(city) {
            return IkaTools.Intl.formatRemainingTime(
                  IkaTools.EmpireData.calculateTravelTime(
                      city.getIslandCoordinates(), target.getIslandCoordinates(), null, 1), 
                  false, 3);
          }

          var travelTimeUpdateable = updateables.create('EspionageTravelTime_%s'.format(target.getId()));
          travelTimeUpdateable.registerUpdate('cityChanged', 
            function updateTravelTimeOnCityChange(travelTime) {
              travelTime.html(renderTravelTime(IkaTools.View.getCurrentCity()));
            });

          function makeTravelTimeTable() {
            var cities = IkaTools.EmpireData.getCities();
            cities.sort(function(city1, city2) {
              return IkaTools.EmpireData.calculateTravelTime(
                  city1.getIslandCoordinates(), target.getIslandCoordinates()) - 
                  IkaTools.EmpireData.calculateTravelTime(
                      city2.getIslandCoordinates(), target.getIslandCoordinates());
            });
            return ('<table class="travel_time">' +
                      '<thead><tr><td>%s</td><td>%s</td></tr></head>' + 
                      '<tbody>%s</tbody>' + 
                    '</table>').format(
                        localizer.localize('misc','city_name'),
                        localizer.localize('espionage','travel_time'),
                        $.map(cities, function(city) {
                          if (city.isOwn()) {
                            return '<tr><td>%s</td><td>%s</td></tr>'.format(
                                city.getName(),
                                renderTravelTime(city));
                          } else {
                            return '';
                          }
                        }).join(''));
          }
          
          toolTips.register('EspionageTravelTime_%s'.format(target.getId()), 
              makeTravelTimeTable);
          

          var lootableResources = NaN;
          if (target.hasResourceInfo()) {
            lootableResources = 
                target.getLootableResources(IkaTools.Constants.Resources.WOOD) +
                target.getLootableResources(IkaTools.Constants.Resources.WINE) +
                target.getLootableResources(IkaTools.Constants.Resources.MARBLE) +
                target.getLootableResources(IkaTools.Constants.Resources.GLASS) +
                target.getLootableResources(IkaTools.Constants.Resources.SULFUR);
                
            function makeResourceTable() {
              function makeLootableRow(resource) {
                return ('<tr>' + 
                          '<td class="resource_icon">' + 
                            '<img src="skin/resources/icon_%s.png">' + 
                          '</td>' +
                          '<td class="resource_lootable">%s</td>' + 
                        '</tr>').format(
                            resource,
                            IkaTools.Intl.formatInteger(target.getLootableResources(resource)));
              }
              
              return ('<table class="lootable_resources">' +
                      '<thead class="imperator_tool_tip_title">' + 
                        '<tr><th colspan="2">%s</th></tr>' +
                      '</thead>' +
                      '<tbody>' + 
                        '%s%s%s%s%s' + 
                      '</tbody>' +
                      '<tfoot>' +
                        '<tr>' + 
                          '<td><img src="skin/layout/icon-status-small.png" height="11"/></td>' +
                          '<td>%s</td>' + 
                        '</tr>' +
                      '</tfoot>' +
                    '<table>')
                          .format(
                              localizer.localize('espionage', 'resources_lootable'),
                              makeLootableRow(IkaTools.Constants.Resources.WOOD),
                              makeLootableRow(IkaTools.Constants.Resources.WINE),
                              makeLootableRow(IkaTools.Constants.Resources.MARBLE),
                              makeLootableRow(IkaTools.Constants.Resources.GLASS),
                              makeLootableRow(IkaTools.Constants.Resources.SULFUR),
                              IkaTools.Intl.formatRemainingTime(
                                  IkaTools.View.gameTimeNow() - target.getResourcesSpyTime()));
            }
            
            toolTips.register('EspionageLootableResources_%s'.format(target.getId()), 
                makeResourceTable);
          } else {
            toolTips.deregister('EspionageLootableResources_%s'.format(target.getId()));
          }

          if (target.hasMilitaryInfo()) {
            var military = target.getMilitary();
            var otherMilitary = target.getOtherMilitary();
            
            function makeGarrisonTableHeaderCell(type) {
              var displayName = localizer.localize('units', type);
              return (military.getCount(type) || otherMilitary.getCount(type)) ? 
                  ('<th class="military military_%s">%s</th>').format(type, displayName) : 
                  '';
            }

            function makeGarrisonTableBodyCell(type) {
              var count = military.getCount(type);
              var otherCount = otherMilitary.getCount(type);
              if (!(count || otherCount)) {
                return '';
              }
              var countDisplay = '';
              if (count) {
                countDisplay = IkaTools.Intl.formatInteger(count);
              }
              if (otherCount) {
                countDisplay = '%s (%s)'.format(
                    countDisplay, IkaTools.Intl.formatInteger(otherCount));
              }
              return '<td>%s</td>'.format(countDisplay);
            }
          
            function makeGarrisonTable() {
              var header = $.map(UNIT_ORDER, function(info) {
                            return $.map(info.units, makeGarrisonTableHeaderCell);
                          }).join('') || '<th>%s</th>'.format(localizer.localize('misc','none'));
              return ('<table class="target_military_garrison">' +
                        '<thead><tr>%s</tr></thead>' + 
                        '<tbody><tr>%s</tr></tbody>' + 
                        '<tfoot>' +
                          '<tr>' + 
                            '<td colspan="100"><img src="skin/layout/icon-status-small.png"/ height="11">%s</td>' +
                          '</tr>' +
                        '</tfoot>' +
                      '</table>').format(
                          header,
                          $.map(UNIT_ORDER, function(info) {
                            return $.map(info.units, makeGarrisonTableBodyCell);
                          }).join(''),
                          IkaTools.Intl.formatRemainingTime(
                              IkaTools.View.gameTimeNow() - target.getMilitarySpyTime()));
            }

            toolTips.register('EspionageMilitaryReport_%s'.format(target.getId()),
                makeGarrisonTable);
          } else {
            toolTips.deregister('EspionageMilitaryReport_%s'.format(target.getId()));
          }

          var combats = target.getCombats(7 * IkaTools.Constants.Time.MILLIS_PER_DAY);
          if (combats.length) {
            function makeCombatsTable() {
              function makeLootedRow(combat, resource) {
                var looted = combat.getLooted(resource);
                if (looted) {
                  return ('<tr>' + 
                            '<td class="resource_icon">' + 
                              '<img src="skin/resources/icon_%s.png">' + 
                            '</td>' +
                            '<td class="resource_looted">%s</td>' + 
                          '</tr>').format(
                              resource,
                              IkaTools.Intl.formatInteger(looted));
                } else {
                  return '';
                }
              }
              
              function makeCombatRow(combat) {
                return ('<tr>' + 
                          '<td>' + 
                            '<div class="combat_type_%s"/>' +
                          '</td>' +
                          '<td>%s</td>' + 
                          '<td><table class="combat_looted"><tbody>%s%s%s%s%s</tbody></table></td>' + 
                        '</tr>').format(
                            combat.getType(),
                            IkaTools.Intl.formatRemainingTime(
                                IkaTools.View.gameTimeNow() - combat.getTime()),
                            makeLootedRow(combat, IkaTools.Constants.Resources.WOOD),
                            makeLootedRow(combat, IkaTools.Constants.Resources.WINE),
                            makeLootedRow(combat, IkaTools.Constants.Resources.MARBLE),
                            makeLootedRow(combat, IkaTools.Constants.Resources.GLASS),
                            makeLootedRow(combat, IkaTools.Constants.Resources.SULFUR));
              }
              
              return ('<table class="espionage_combats">' +
                        '<thead>' +
                          '<tr>' + 
                            '<th></th>' + 
                            '<th>%s</th>' + 
                            '<th>%s</th>' +
                          '</tr>' +  
                        '</thead>' +
                        '<tbody>' + 
                          '%s' + 
                        '</tbody>' +
                      '<table>').format(
                          localizer.localize('espionage','time_since'),
                          localizer.localize('espionage','resources_looted'),
                          $.map(combats, makeCombatRow).join(''));
            }
            toolTips.register('EspionageMilitaryActions_%s'.format(target.getId()), 
                makeCombatsTable);
          } else {
            toolTips.deregister('EspionageMilitaryActions_%s'.format(target.getId()));
          }
                                       
          return ('<tr>' + 
                    '<td class="city_tradegood"><img src="skin/resources/icon_%s.png"/>%s%s</td>' + 
                    '<td class="city_name nowrap">%s</td>' + 
                    '<td class="player nowrap">%s</td>' + 
                    '<td class="location">%s</td>' + 
                    '<td class="actions">%s%s%s%s%s%s</td>' + 
                    '<td id="%s" class="travel_time  imperator_tool_tip">%s</td>' + 
                    '<td class="townhall_level">%s</td>' + 
                    '<td class="wall_level">%s</td>' + 
                    '<td id="EspionageLootableResources_%s" class="resources_lootable imperator_tool_tip">%s</td>' + 
                    '<td id="EspionageMilitaryActions_%s" class="combats imperator_tool_tip">%s</td>' + 
                    '<td id="EspionageMilitaryReport_%s" class="military_score imperator_tool_tip">%s</td>' + 
                  '</tr>').format(
                      target.getTradeGoodType(),
                      occupierHtml, blockaderHtml, cityLinkHtml,
                      playerLinkHtml, 
                      islandLinkHtml,
                      spyActionLinkHtml, pillageLinkHtml, blockadeLinkHtml, occupyLinkHtml, sendSpyLinkHtml, removeTargetHtml,
                      travelTimeUpdateable.getId(0), 
                      IkaTools.Intl.formatRemainingTime(
                          IkaTools.EmpireData.calculateTravelTime(
                              IkaTools.View.getCurrentCity().getIslandCoordinates(), target.getIslandCoordinates(), null, 1), 
                          false, 3),
                      IkaTools.Intl.formatInteger(target.getTownLevel()),
                      IkaTools.Intl.formatInteger(target.getWallLevel()),
                      target.getId(), 
                      IkaTools.Intl.formatInteger(Math.ceil(
                          lootableResources / IkaTools.Constants.GamePlay.RESOURCES_PER_TRANSPORT)), 
                      target.getId(), combats.length ? IkaTools.Intl.formatInteger(combats.length) : '-',
                      target.getId(), IkaTools.Intl.formatInteger(player.getMilitaryScore()));
        }
      
        function makeTableHead() {
          toolTips.registerSimple('EspionageLocationHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('espionage','location')));
          toolTips.registerSimple('EspionageTravelTimeHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('espionage','travel_time')));
          toolTips.registerSimple('EspionageTownHallLevelHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('espionage','townhall_level')));
          toolTips.registerSimple('EspionageWallLevelHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('espionage','wall_level')));
          toolTips.registerSimple('EspionageResourcesLootableHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('espionage','resources_lootable')));
          toolTips.registerSimple('EspionageCombatsHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('espionage','combats')));
          toolTips.registerSimple('EspionageMilitaryScoreHeader',
              '<div class="nowrap">%s</div>'.format(
                  localizer.localize('espionage','military_score')));
          return ('<thead>' +
                  '<tr>' +
                    '%s' + 
                    '<th colspan="1" id="EspionagePlayerHeader" ' +
                        'class="player imperator_tool_tip">%s</th>' +
                    '<th colspan="1" id="EspionageLocationHeader" ' + 
                        'class="location imperator_tool_tip">%s</th>' +
                    '<th colspan="1" id="EspionageActionsHeader" ' + 
                        'class="actions imperator_tool_tip">%s</th>' +
                    '<th colspan="1" id="EspionageTravelTimeHeader" ' + 
                        'class="travel_time imperator_tool_tip">%s</th>' +
                    '<th colspan="1" id="EspionageTownHallLevelHeader" ' +
                        'class="townhall_level imperator_tool_tip">%s</th>' +
                    '<th colspan="1" id="EspionageWallLevelHeader" ' + 
                        'class="wall_level imperator_tool_tip">%s</th>' +
                    '<th colspan="1" id="EspionageResourcesLootableHeader" ' + 
                        'class="resources_lootable imperator_tool_tip">%s</th>' +
                    '<th colspan="1" id="EspionageCombatsHeader" ' + 
                        'class="combats imperator_tool_tip">%s</th>' +
                    '<th colspan="1" id="EspionageMilitaryScoreHeader" ' + 
                        'class="military_score imperator_tool_tip">%s</th>' +
                  '</tr>' + 
                 '</thead>').format(
                     makeCityNameHeaderCells(),
                     localizer.localize('espionage','player'),
                     localizer.localize('espionage','location'),
                     localizer.localize('misc','actions'),
                     localizer.localize('espionage','travel_time'),
                     localizer.localize('espionage','townhall_level'),
                     localizer.localize('espionage','wall_level'),
                     localizer.localize('espionage','resources_lootable'),
                     localizer.localize('espionage','combats'), 
                     localizer.localize('espionage','military_score'));
        }
        var targets = IkaTools.EmpireData.Espionage.getTargets();
        
        return '%s<tbody>%s</tbody>'.format(
            makeTableHead(),
            $.map(targets, renderTarget).join(''));
      }
      
      var tab = new Tab('espionage', localizer.localize('misc','espionage'), $(
          '<div class="imperator_overview">' +
            '<table class="overview" id="ImperatorOverviewEspionageTable"/>' +
          '</div>'),
          'ImperatorOverviewEspionageTable',
          function() {
            IkaTools.EmpireData.Espionage.registerEspionageChangedHandler(function(changes) {
              tab.maybeRedraw(true);
            });
          },
          makeTableContent);
     
      return tab.getTab();
    }
    
    var openResourcesTabOnTransportClose = false;
    var openBuildingsTabOnTransportClose = false;
    var openMilitaryTabOnDeploymentClose = false;
  
    var makePopup = IkaTools.Utils.thunk(function makePopup() {
      var resourceTab = makeResourceTab();
      var buildingsTab = makeBuildingsTab();
      var militaryTab = makeMilitaryTab();
      var espionageTab = makeEspionageTab();
      
      var tabPane = new IkaTools.UI.TabPane(
          [resourceTab, buildingsTab, militaryTab, espionageTab],
          {
            tabActivatedCallback: function() {
              IkaTools.UI.resizePopup();
            },
          });
  
      var popup = new IkaTools.UI.PopupWindow(
        'cityBuildings',
        $('<div>Imperator Overview</div>'),
        tabPane.getContainer(),
        { oversized:true,
          deactivatedCallback: function() {
            resourceTab.deactivated();
            buildingsTab.deactivated();
            militaryTab.deactivated();
            espionageTab.deactivated();
          },
        }
      );
      
      function displayResources() {
        popup.display(true);
        resourceTab.activate();
      }
      function displayBuildings() {
        popup.display(true);
        buildingsTab.activate();
      }
      function displayMilitary() {
        popup.display(true);
        militaryTab.activate();
      }
      function displayEspionage() {
        popup.display(true);
        espionageTab.activate();
      }
      
      IkaTools.View.registerIkariamAjaxResponseCallback(
          function resetReopenTabVars(response) {
            IkaTools.Utils.iterateIkariamAjaxResponse(response, 
                function lookForChangeView(index, name, data) {
                  if (name == IkaTools.Constants.IkariamAjaxResponseType.CHANGE_VIEW) {
                    var view = data[0];
                    if (view == IkaTools.Constants.View.CITY_DETAIL) {
                      if (openResourcesTabOnTransportClose) {                        
                        popup.display(true);
                        resourceTab.activate();
                      }
                      if (openBuildingsTabOnTransportClose) {
                        popup.display(true);
                        buildingsTab.activate();
                      }
                      if (openMilitaryTabOnDeploymentClose) {
                        popup.display(true);
                        militaryTab.activate();
                      }
                    }
                    if (view != IkaTools.Constants.View.TRANSPORT) {
                      openResourcesTabOnTransportClose = false;
                      openBuildingsTabOnTransportClose = false;
                    }
                    if (view != IkaTools.Constants.View.DEPLOY) {
                      openMilitaryTabOnDeploymentClose = false;
                    }
                  }
                });
          });
  
      return {
        displayResources: displayResources,
        displayBuildings: displayBuildings,
        displayMilitary: displayMilitary,
        displayEspionage: displayEspionage,
        close: popup.close.bind(popup),
      };
    });
    
    var leftMenuResourceContent = 
        $(('<li>' + 
            '<div class="image" ' + 
                 'style="background-image: url(\'/skin/layout/btn_world.jpg\'); ' +
                 'background-position: -27px -1px;">' + 
            '</div>' +
            '<div class="name"><span class="namebox">%s</span></div>' + 
          '</li>').format(localizer.localize('misc','resource_overview')));
    var leftMenuBuildingsContent = 
        $(('<li>' + 
           '<div class="image" ' + 
                'style="background-image: url(\'/skin/layout/btn_city.png\'); ' +
                'background-position: -22px -1px;">' + 
           '</div>' +
           '<div class="name"><span class="namebox">%s</span></div>' + 
         '</li>').format(localizer.localize('misc','buildings_overview')));
    var leftMenuArmyContent = 
        $(('<li>' + 
            '<div class="image" ' + 
                 'style="background-image: url(\'skin/characters/military/x40_y40/y40_phalanx_faceright.png\'); ' +
                 'background-position: 0px -4px;">' + 
            '</div>' +
            '<div class="name"><span class="namebox">%s</span></div>' + 
          '</li>').format(localizer.localize('misc','military_overview')));
    var leftMenuEspionageContent = 
        $(('<li>' + 
            '<div class="image" ' + 
                 'style="background-image: url(\'/skin/characters/military/120x100/spy_120x100.png\'); ' +
                 'background-position: 1px 3px;' +
                 'background-repeat: no-repeat;' + 
                 'background-size: 100% auto;">' + 
            '</div>' +
            '<div class="name"><span class="namebox">%s</span></div>' + 
          '</li>').format(localizer.localize('misc','espionage_overview')));
          
    menuItems = [];
    if (showResourceOverview.isEnabled()) {
      menuItems.push(new IkaTools.UI.LeftMenu.Item(leftMenuResourceContent));
    }
    if (showBuildingsOverview.isEnabled()) {
      menuItems.push(new IkaTools.UI.LeftMenu.Item(leftMenuBuildingsContent));
    }
    if (showMilitaryOverview.isEnabled()) {
      menuItems.push(new IkaTools.UI.LeftMenu.Item(leftMenuArmyContent));
    }
    if (showEspionageOverview.isEnabled()) {
      menuItems.push(new IkaTools.UI.LeftMenu.Item(leftMenuEspionageContent));
    }
  
    var leftMenu = new IkaTools.UI.LeftMenu(menuItems, { atTop: true });
    leftMenu.display();
  
    return function overviewReady() {
      if (showResourceOverview.isEnabled()) {
        leftMenuResourceContent.mousedown(IkaTools.Logging.debuggable(
          { label: 'Imperator.overview.showResourceTable.mousedown', 
            alwaysTime: true, profile: true },
          function() {
            makePopup().displayResources();
          }));
      }
      if (showBuildingsOverview.isEnabled()) {
        leftMenuBuildingsContent.mousedown(IkaTools.Logging.debuggable(
            { label: 'Imperator.overview.showBuildingsTable.mousedown', 
              alwaysTime: true, profile: true },
            function() {
              makePopup().displayBuildings();
            }));
      }
      if (showMilitaryOverview.isEnabled()) {
        leftMenuArmyContent.mousedown(IkaTools.Logging.debuggable(
            { label: 'Imperator.overview.showMilitaryTable.mousedown',
              alwaysTime: true, profile: true },
            function() {
              makePopup().displayMilitary();
            }));
      }
      if (showEspionageOverview.isEnabled()) {
        IkaTools.EmpireData.Espionage.startTracking();
        leftMenuEspionageContent.mousedown(IkaTools.Logging.debuggable(
            { label: 'Imperator.overview.showEspionageTable.mousedown',
              alwaysTime: true, profile: true},
            function() {
              makePopup().displayEspionage();
            }));
      }
    };
  }
  
  function registerLoggingEventHandlers() {  
    IkaTools.EmpireData.registerResourcesChangedHandler(function(changes) {
      IkaTools.Logging.debug('Resources changed: ', changes);
    });
    IkaTools.EmpireData.registerBuildingsChangedHandler(function(changes) {
      IkaTools.Logging.debug('Buildings changed: ', changes);
    });
    IkaTools.EmpireData.registerMilitaryChangedHandler(function(changes) {
      IkaTools.Logging.debug('Military changed: ', changes);
    });
    IkaTools.EmpireData.registerCivilizationDataChangedHandler(function(changes) {
      IkaTools.Logging.debug('CivilizationData changed: ', changes);
    });
    IkaTools.EmpireData.registerMovementsChangedHandler(function(changes) {
      IkaTools.Logging.debug('Movements changed: ', changes);
    });
    IkaTools.EmpireData.Espionage.registerEspionageChangedHandler(function(changes) {
      IkaTools.Logging.debug('Espionage changed: ', changes);
    });
  }

  function fireFakeKeyboardEvent(input) {
    // fake event so Ikariam handlers update related sliders and stuff
    var e = document.createEvent("KeyboardEvent");
    if (e.initKeyboardEvent) {
      e.initKeyboardEvent(
          'keyup', true, true, window, false, false, false, false, 13, 0);
    } else {
      e.initKeyEvent('keyup', true, true, window, false, false, false, false, 13, 0);
    }
    input.dispatchEvent(e);
  }
  
  function initQuickGoodsButtons() {    
    function createButton(input, textName, increment) {
      var button = $('<a class="button" title="%s">%s</a>'.format(
          localizer.localize('tweaks',textName + '_text'),
          localizer.localize('tweaks',textName)));
      button.click(IkaTools.Logging.debuggable(
          'Imperator.quickGoodsSelectIncrement[' + increment + ']',
          function incrementSelectedGoods() {
            var current = parseInt(input.val()) || 0;
            var newValue = 
                Math.ceil((current + (increment > 0 ? 1 : -1)) / increment) * increment;
            input.val(newValue);
            fireFakeKeyboardEvent(input.get(0));
          }));
      return button;
    }
    
    function addChangeGoodsButtons(input) {
      var span = $('<span class="quick_goods_select"/>');
      var minus500Button = createButton(input, 'transport_minus_500', -500);
      var plus500Button = createButton(input, 'transport_plus_500', 500);
      var plus1000Button = createButton(input, 'transport_plus_1000', 1000);
      var plus5000Button = createButton(input, 'transport_plus_5000', 5000);
      span.append(minus500Button, plus500Button, plus1000Button, plus5000Button);
      
      input.after(span);
    }
    
    var stylesToAdd = 
        '.quick_goods_select a, .quick_goods_select a:active {' + 
          'margin: 3px; padding: 1px 3px; font-size: 10px; font-weight:normal;' + 
        '}' +
        '#transport .quick_goods_select {' + 
          'position: absolute;' + 
          'top: 6px;' + 
          'left: 468px;' + 
        '}' +
        '.quick_goods_select {' +
          '-webkit-user-select: none;' +
          '-khtml-user-select: none;' +
          '-moz-user-select: none;' +
          '-o-user-select: none;' + 
          'user-select: none;' +
        '}';
    
    if (transportButtons.isEnabled()) {
      stylesToAdd += 
          '#mission ul.resourceAssign { width: 640px; }' + 
          '#mission .resourceAssign li { padding:0px; background-position:0 center;}' +
          '#mission .resourceAssign .sliderinput { margin:0 0 0 30px; width:400px;}' +
          '#mission .resourceAssign input.textfield {' + 
            'position:relative;top:-26px;margin-left:-5px;' + 
          '}';
          
      IkaTools.View.registerIkariamAjaxResponseCallback(
          function addTransportButtons(response) {
            IkaTools.Utils.iterateIkariamAjaxResponse(response, 
                function lookForChangeView(index, name, data) {
                  if (name == IkaTools.Constants.IkariamAjaxResponseType.CHANGE_VIEW) {
                    var view = data[0];
                    if (view == IkaTools.Constants.View.TRANSPORT || 
                        view == IkaTools.Constants.View.COLONIZE) {
                      $('#transportForm ul.resourceAssign li input').each(
                          function(index, node) {
                            addChangeGoodsButtons($(node));
                          });
                    } else if (view == IkaTools.Constants.View.TAKE_OFFER) {
                      $('#transportForm td.input input').each(
                          function(index, node) {
                            addChangeGoodsButtons($(node));
                          });
                    } else if (view == IkaTools.Constants.View.BRANCH_OFFICE) {
                      $('#branchOffice form[name=formkontor] tr input').filter(':even').each(
                          function(index, node) {
                            addChangeGoodsButtons($(node));
                          });
                    }
                  }
                });    
          }, true);
    }
    
    if (donationButtons.isEnabled()) {
      stylesToAdd += 
          '#donateForm input.textfield {' + 
            'margin-bottom: 6px;' + 
          '}';
      IkaTools.View.registerIkariamAjaxResponseCallback(
          function addTransportButtons(response) {
            IkaTools.Utils.iterateIkariamAjaxResponse(response, 
                function lookForChangeView(index, name, data) {
                  if (name == IkaTools.Constants.IkariamAjaxResponseType.CHANGE_VIEW) {
                    var view = data[0];
                    if (view == IkaTools.Constants.View.RESOURCE ||
                        view == IkaTools.Constants.View.TRADE_GOOD ) {
                      var input = $('#donateForm input.textfield');
                      
                      var span = $('<span class="quick_goods_select"/>');
                      var plus1kButton = createButton(input, 'donate_plus_1000', 1000);
                      var plus10kButton = createButton(input, 'donate_plus_10000', 10000);
                      var plus100kButton = createButton(input, 'donate_plus_100000', 100000);
                      span.append(plus1kButton, plus10kButton, plus100kButton);
                      
                      input.after(span);
                    }
                  }
                });
          }, true);
    }
        
    return stylesToAdd;
  }
  
  function initBuildingDemolitionHandler() {
    var activeDemolitionInfo = null;
    
    IkaTools.View.registerIkariamAjaxResponseCallback(
        IkaTools.Utils.forEachIkariamAjaxResponseFunction(
            function demolitionHandler(index, name, value) {
              if (name == IkaTools.Constants.IkariamAjaxResponseType.ADD_WINDOW &&
                  value[0] == 'buildings_demolition') {
                var demolitionButton = $('#buildings_demolition a.button');
                var hrefMatch = demolitionButton.attr('href').match(
                    /function=demolishBuilding&level=(\d+)&cityId=(\d+)&position=(\d+)/);
                var level = parseInt(hrefMatch[1]);
                var cityId = parseInt(hrefMatch[2]);
                var position = parseInt(hrefMatch[3]);
                
                if (activeDemolitionInfo && 
                    activeDemolitionInfo.level == level && 
                    activeDemolitionInfo.cityId == cityId && 
                    activeDemolitionInfo.position == position) {
                  activeDemolitionInfo.level = level - 1;
                  demolitionButton[0].click();
                } else {
                  if (confirm(localizer.localize('tweaks', 'completely_demolish_building_prompt'))) {
                    if (level > 1) {
                      activeDemolitionInfo = { level: level - 1, cityId: cityId, position: position };
                      demolitionButton[0].click();
                    } else {
                      activeDemolitionInfo = null;
                    }
                  }
                }
              } else if (name == IkaTools.Constants.IkariamAjaxResponseType.CHANGE_VIEW) {
                var demolitionButton = $('#buildingUpgrade .downgrade .action_btn');
                if (demolitionButton.length > 0) {
                  var hrefMatch = demolitionButton.attr('href').match(
                      /view=buildings_demolition&cityId=(\d+)&position=(\d+)&level=(\d+)/);
                  if (hrefMatch) {
                    var level = parseInt(hrefMatch[3]);
                    var cityId = parseInt(hrefMatch[1]);
                    var position = parseInt(hrefMatch[2]);
                    
                    if (activeDemolitionInfo && 
                        activeDemolitionInfo.level == level && 
                        activeDemolitionInfo.cityId == cityId && 
                        activeDemolitionInfo.position == position) { 
                      demolitionButton[0].click();
                    }
                  }
                }
              }
            }));
  }
  
  function initTweaks() {
    if (autoAcceptDailyBonus.isEnabled()) {
      function submitDailyActivityBonus() {
        $('#dailyActivityBonus form').submit();
      }
      if (IkaTools.Utils.isChrome()) {
        // Who knows why you would send back a page that then immediately turns around
        // and queries the server it came from.  But then, you are not an Ikariam developer.
        // In all likelihood you posess at least a single brain cell (a sufficient but 
        // not necessary condition).
        // In any case, the fact is that in Chrome this starts an ajax call before we 
        // have had a chance to hook in any of the ajax handler overrides in developer
        // tools.  So to counteract the stupid things Ikariam developers did we have to 
        // do this the bruteforce way.
        setTimeout(submitDailyActivityBonus, 500);
        setTimeout(submitDailyActivityBonus, 1000);
        setTimeout(submitDailyActivityBonus, 2000);
        setTimeout(submitDailyActivityBonus, 5000);
      } else {
        IkaTools.View.registerIkariamAjaxResponseCallback(
            IkaTools.Utils.forEachIkariamAjaxResponseFunction(
                function findDailyBonusWindow(index, name, value) {
                  if (name == IkaTools.Constants.IkariamAjaxResponseType.ADD_WINDOW &&
                      value[0] == 'dailyActivityBonus') {
                    submitDailyActivityBonus();
                  }
                }));
      }
    }
    
    var addedStyles = '';
    
    if (hideAds.isEnabled()) {
      addedStyles += '.ad_banner { display: none; } ';
    }
    if (hideFacebook.isEnabled()) {
      addedStyles += '#facebook_button * { display: none !important; } ';
    }
    if (hideFriendsBar.isEnabled()) {
      addedStyles += '#js_viewFriends { display: none; } ';
    }
    if (hideChat.isEnabled()) {
      addedStyles += '#js_viewChat { display: none; } ';
    }
    
    addedStyles += initQuickGoodsButtons();
    
    initBuildingDemolitionHandler();
    
    if (showCityOwners.isEnabled() && IkaTools.View.viewIsIsland()) {
      function doLabelCities(data) {
        for (var i = 0; i < 17; i++) {
          var cityData = data.cities[i];
          if (cityData.type != 'buildplace') {
            $('#js_cityLocation' + i + 'TitleText').append(' (' + cityData.ownerName + ')');
          }
        }
      }

      addedStyles += '#island .city .scroll_img .center { overflow: hidden; width: 175px; } ' +
                     '#island .city .scroll_img .after { left: 175px; } ';
        
      IkaTools.View.registerIkariamAjaxResponseCallback(
          function labelCityOwners(response) {
            IkaTools.Utils.iterateIkariamAjaxResponse(response, function(index, name, data) {
              if (name == IkaTools.Constants.IkariamAjaxResponseType.UPDATE_BACKGROUND_DATA) {
                doLabelCities(data);
              } else if (name == IkaTools.Constants.IkariamAjaxResponseType.UPDATE_GLOBAL_DATA) {
                doLabelCities(data['backgroundData'] || data[11]);
              }
            });
          }, true);
    }

    if (preventAccidentalColonyDestruction.isEnabled()) {
      IkaTools.View.registerIkariamAjaxResponseCallback(
          function preventAccidentalColonyDestruction(response) {
            IkaTools.Utils.iterateIkariamAjaxResponse(response, function(index, name, data) {
              if (name == IkaTools.Constants.IkariamAjaxResponseType.CHANGE_VIEW) {
                if (data[0] == IkaTools.Constants.View.ABOLISH_CITY) {
                  var cityId = parseInt($('#abolishCity input[name=cityId]').val());
                  var city = IkaTools.EmpireData.getCity(cityId);
                  var palace = city.getBuildingByType(IkaTools.Constants.Buildings.PALACE);
                  var governorsResidence = city.getBuildingByType(
                      IkaTools.Constants.Buildings.GOVERNORS_RESIDENCE);
                  if (palace || governorsResidence) {
                    unsafeWindow.ikariam.TemplateView.destroyTemplateView();
                    alert(localizer.localize('tweaks', 'destroy_non_mobile_colony_prompt'));
                  }
                }
              }
            });
          }, true);
    }

    if (initializeColonizationMissionsForPirateRaiding.isEnabled()) {
      IkaTools.View.registerIkariamAjaxResponseCallback(
          function initializeColonizationMissionsForPirateRaiding(response) {
            IkaTools.Utils.iterateIkariamAjaxResponse(response, function(index, name, data) {
              if (name == IkaTools.Constants.IkariamAjaxResponseType.CHANGE_VIEW) {
                if (data[0] == IkaTools.Constants.View.COLONIZE) {
                  var woodInput = $('#textfield_wood');
                  var marbleInput = $('#textfield_marble');
                  var civData = IkaTools.EmpireData.getCivilizationData();
        
                  var multiplier = 1.0;
                  multiplier -= civData.hasResearched(
                      IkaTools.Constants.Research.Economy.PULLEY) ? .02 : 0;
                  multiplier -= civData.hasResearched(
                      IkaTools.Constants.Research.Economy.GEOMETRY) ? .04 : 0;
                  multiplier -= civData.hasResearched(
                      IkaTools.Constants.Research.Economy.SPIRIT_LEVEL) ? .08 : 0;

                  woodInput.val(Math.ceil(multiplier * 
                      IkaTools.Constants.BuildingData[IkaTools.Constants.Buildings.PIRATE_FORTRESS].wood[0]) - 250);
                  marbleInput.val(Math.ceil(multiplier * 
                      IkaTools.Constants.BuildingData[IkaTools.Constants.Buildings.PIRATE_FORTRESS].marble[0]));

                  // Have to give time for Ikariam javascript that processes the click
                  // to be registered.
                  setTimeout(function() {$('#slider_capacity_min').get(0).click();}, 0);
                }
              }
            });
          }, true);
    }
    
    GM_addStyle(addedStyles);
  }
  
  function initAlerts() {
    function showDesktopNotification(icon, title, text, audio) {
      if (window.webkitNotifications && 
          window.webkitNotifications.checkPermission() == 0) {
        if (audio) {
          var audioNode = $('<audio autoplay="autoplay" loop="loop"><source src="http://soundjax.com/reddo/67560%5Ealarma.mp3" type="audio/mp3" />');
          $('body').append(audioNode);
        }
        var notification = window.webkitNotifications.createNotification(icon, title, text);
        notification.onclick = IkaTools.Logging.debuggable(
            'Imperarator.buildingCompletionAlert.desktopAlertClicked',
            function buildingDesktopAlertClicked() {
              notification.cancel();
              window.focus();
            });
        notification.onclose = IkaTools.Logging.debuggable(
            'Imperator.buildingCompletionAlert.desktopAlertClosed',
            function buildingDesktopAlertClosed() {
              if (audio) {
                audioNode.remove();
              }
            });
        notification.show();
      }
    }
    
    if (buildingCompletionAlert_Desktop.isEnabled()) {
      IkaTools.EmpireData.registerBuildingsChangedHandler(
          function alertBuildingCompletion(changes) {
            $.each(changes, function forEachBuildingChange(index, change) {
              if (change.type == IkaTools.Constants.BuildingEventType.UPGRADE_COMPLETE) {
                showDesktopNotification(
                    'http://' + IkaTools.View.getDomain() + '/' + 
                        IkaTools.Constants.BuildingData[change.building.getType()].icon,
                    localizer.localize('alerts','building_upgrade_complete'),
                    localizer.localize('alerts','building_upgrade_complete_text').format2(
                        { 
                          building: localizer.localize('buildings', change.building.getType()),
                          city: change.city.getName(),
                          level: IkaTools.Intl.formatInteger(change.building.getLevel())
                        }));
              }
            });
          });
    }
    
    var missionAlerts = {
      'transport:loading': transportMissionLoaded_Desktop.isEnabled(),
      'transport:en_route': transportMissionArrived_Desktop.isEnabled(),
      'transport:returning': transportMissionReturned_Desktop.isEnabled(),
      'deployarmy:loading': deployArmyLoaded_Desktop.isEnabled(),
      'deployarmy:en_route': deployArmyArrived_Desktop.isEnabled(),
      'deployarmy:returning': deployArmyReturned_Desktop.isEnabled(),
      'deploynavy:loading': false,
      'deploynavy:en_route': deployNavyArrived_Desktop.isEnabled(),
      'deploynavy:returning': deployNavyReturned_Desktop.isEnabled(),
      'plunder:loading': pillageLoaded_Desktop.isEnabled(),
      'plunder:en_route': pillageArrived_Desktop.isEnabled(),
      'plunder:returning': pillageReturned_Desktop.isEnabled(),
    }
    
    IkaTools.EmpireData.registerMovementsChangedHandler(function alertMissions(changes) {
      $.each(changes, function forEachMissionChange(index, change) {
        if (change.type == IkaTools.Constants.Movements.EventType.STAGE_CHANGED || 
            change.type == IkaTools.Constants.Movements.EventType.COMPLETED) {
          var mission = change.movement.getMission();
          var stage = change.previousStage;
          var cityName = IkaTools.Intl.localizer.localize('formatting','unknown');
          if (stage == IkaTools.Constants.Movements.Stage.EN_ROUTE) {
            var city = change.movement.getTargetCity();
            if (city) {
              cityName = city.getName();
            }
          } else {
            var city = change.movement.getOriginCity();
            if (city) {
              cityName = city.getName();
            }
          }
          if (missionAlerts[mission + ':' + stage]) {
            showDesktopNotification(
              'http://' + IkaTools.View.getDomain() + '/' + 
                  IkaTools.Constants.Movements.MissionData[mission].icon,
              localizer.localize('alerts','mission_update'),
              localizer.localize('alerts', stage).format2({
                type: localizer.localize('alerts', mission),
                city: cityName,
              }));
          }
        }
      });
    });

/*    var underAttack = $('#advMilitary a').eq(0).hasClass('normalalert');
    console.log("Under attack at start: ", underAttack, $('#advMilitary a').eq(0));
    var lastMovementUpdateTime = 0;
    var parsedIgnoredHostileMissions = JSON.parse(ignoredHostileMissions.getValue());
    
    IkaTools.View.registerIkariamAjaxResponseCallback(
      function enhancedMilitaryAdvisor(response) {
        IkaTools.Utils.iterateIkariamAjaxResponse(response, function(index, name, data) {
          if (name == IkaTools.Constants.IkariamAjaxResponseType.UPDATE_GLOBAL_DATA) {
            //console.log('DATA:::::', data['headerData']['advisors']['military']);
            if (data.headerData.advisors.military.cssclass.indexOf('normalalert') >= 0) {
              //console.log('Under attack');
              if (!underAttack) {
                showDesktopNotification('http://' + document.domain + '/skin/layout/advisors/general_alert.png', 
                    'Under attack', 'New attack detected', true);
                underAttack = true;
              } else {
                function onMovementUpdate(response) {
                  var movements = IkaTools.EmpireData.getCivilizationData().getMovements();
                  var foundUnignoredHostile = false;

                  $.each(movements, function(index, movement) {
                    //console.log('Movement:', movement, parsedIgnoredHostileMissions.indexOf(movement.getId()));
                    if (movement.isHostile() && parsedIgnoredHostileMissions.indexOf(movement.getId()) < 0) {
                      foundUnignoredHostile = true;
                    }
                  });
                  if (foundUnignoredHostile) {
                    showDesktopNotification('http://' + document.domain + '/skin/layout/advisors/general_alert.png', 
                        'Under attack 2', 'New attack detected 2', true);
                  } else {
                    //console.log('Only normal attacks');
                    var advMilitaryNode = $('#advMilitary a').eq(0);
                    advMilitaryNode.removeClass('normalalert');
                    advMilitaryNode.addClass('probablysafealert');
                  }
                }
                
                IkaTools.EmpireData.updateMovements(onMovementUpdate);
              }
            } else {
              underAttack = false;
            }
          }
        });
      }, true);*/
    GM_addStyle('#advisors #advMilitary a.probablysafealert { background-image: url(http://www.clker.com/cliparts/3/7/6/d/1256186461796715642question-mark-icon.svg); background-size: 90px 90px; background-repeat:no-repeat;}');
  }
  
  function configureLocalization() {
    var language = localizedLanguage.getValue();
    if (!language) {
      var hostParts = document.location.host.split('\.');
      language = hostParts[hostParts.length - 1];
      if (language == "com" && hostParts.length == 4) {
        //for example: http://s1.en.ikariam.com
        language = hostParts[1];
      }
          
      if ((language == 'com') || (language == 'org') || (language == 'net')) {
        language = 'tr';
      }
      if ((language == 've') || (language == 'mx') || (language == 'ar') ||
          (language == 'co') || (language == 'cl')) {
        language = 'es';
      }
    }
    
    if (language) {
      localizer.setPreferredLanguage(language);
      IkaTools.Intl.localizer.setPreferredLanguage(language);
    }
  }

  function initPirating() {
  }
  
  function init() {
    configureLocalization();
    
    IkaTools.Logging.setAndSaveOptionsFromPageAnchor();
    
    addStyles();
    
    overviewTablesReady = overviewTables();
    
    $(document).ready(function() {
      var readyAction = IkaTools.Logging.debuggable(
        {label: "Imperator.documentReady", group: true, alwaysTime: true, swallowException: true}, 
        function imperatorDocumentReady() {
          registerLoggingEventHandlers();
          initTweaks();
          initAlerts();
          initPirating();
          IkaTools.initialize();
          overviewTablesReady();
          addSettingsLink();
        });

      if (IkaTools.Utils.isChrome()) {
        // In Chrome sometimes we randomly execute before the ikariam "on-ready" scripts
        // which won't work because the stuff IkaTools.init needs will not be in the 
        // javascript objects.  Move this setup to the end of the line.
        setTimeout(readyAction, 500);
      } else {
        readyAction();
      }
    });
  }
  
  return {
    init: init,
  }
}();

IkaTools.Logging.debuggable( {label: "Imperator.init", group: true, alwaysTime: true, swallowException: true}, 
                            Imperator.init)();

//IkaTools.EmpireData.resetData();
unsafeWindow.IkaTools = IkaTools;
/*unsafeWindow.realConsole = console;
$(document).ready(function() {
  //unsafeWindow.console = console;
});
//unsafeWindow.$ = $;*/