Greasy Fork is available in English.

TW Friends

Gestione amici per gli eventi The West

Versione datata 15/09/2017. Vedi la nuova versione l'ultima versione.

// ==UserScript==
// @name               TW Friends
// @name:el            TW Friends
// @name:es            TW Friends
// @name:fr            TW Friends
// @name:it            TW Friends
// @name:pl            TW Friends
// @name:pt-PT         TW Friends
// @name:tr            TW Friends
// @version            0.30
// @license            LGPLv3
// @description        Friend Management for The West Events
// @description:el     Διαχείριση Φίλων για τις Εκδηλώσεις του The West
// @description:es     Gestión de Amigos para Eventos de The West
// @description:fr     Gestion des Amis pour les Evénements de The West
// @description:it     Gestione amici per gli eventi The West
// @description:pl     Menadżer zarządzania Przyjaciółmi podczas eventów The West
// @description:pt-PT  Gestão de amigos para eventos no The West
// @description:tr     The West Etkinlikleri İçin Arkadaş Yöneticisi
// @author             hiroaki
// @translation        pepe100 (es_ES)
// @translation        Jackssson (it_IT)
// @translation        jccwest (pt_PT)
// @translation        Bartosz86 (pl_PL)
// @translation        Oğuzhan Ünal (tr_TR)
// @include            http*://*.the-west.*/game.php*
// @include            http*://*.tw.innogames.*/game.php*
// @grant              none
// @namespace          https://greasyfork.org/users/3197
// @icon               https://cdn.rawgit.com/TWFriends/scripts/master/friends.png
// ==/UserScript==

function hiroFriendsScript(fn) {
	var script = document.createElement('script');
	script.setAttribute("type", "application/javascript");
	script.textContent = '(' + fn + ')();';
	document.body.appendChild(script);
	document.body.removeChild(script);
}
hiroFriendsScript(function() {
	var VERSION = 0.30;
	var URL_INSTALL = "https://greasyfork.org/scripts/2992-tw-friends";
	var URL_CODE = "https://greasyfork.org/scripts/2992-tw-friends/code/TW%20Friends.user.js";
	var URL_VERSION = "https://raw.githack.com/TWFriends/scripts/master/version.js";
	var scriptName = "TW Friends";
	var scriptAuthor = "hiroaki";
	var scriptCredits = '<span style="display: inline-block; vertical-align: middle;">Bartosz86 ??, Jackssson ??, jccwest ??, pepe100 ??, Oğuzhan Ünal ??,<br />noolas, Pnevma</span>';
	var refreshMs = 2 * 60 * 1e3;	// 2 minutes
	var refreshWof = 20 * 60 * 1e3;	// 20 minutes
	var enableLog = true;
	var enableInv = true;
	var enableVersionCheck = true;
	HiroFriends = {
		api: TheWestApi.register('HiroFriends', scriptName, '2.04', Game.version.toString(), scriptAuthor, URL_INSTALL),
		version: VERSION,
		latestVersion: undefined,
		storageItem: "HiroFriends.version",
		cdnBase: '',
		eventCurrencyImage : '',
		eventName : '',
		eventInfo : {},
		eventEndStamp : 0,
		friends : {},
		interval: false,
		locale: 'en_US',
		pendingInvitations: 0,
		wallet: 0,
		wofId: undefined,
		wofStatus: {},
		wofTimeout: undefined,
		messages: {
			el_GR: {
				description: '<h1>Διαχείριση Φίλων για τις Εκδηλώσεις του The West</h1><p style="margin: 8pt;">Μην κλικάρετε πολύ γρήγορα, για να αποφύγετε ένα σερί κακής τύχης :)</p><p style="margin: 8pt;">Υποστηριζόμενες Εκδηλώσεις:</p><ul style="list-style: disc outside; margin-left: 16pt; padding-left: 16pt;"><li>Άγιος Βαλεντίνος</li><li>Πάσχα</li><li>Οκτόμπερφεστ</li><li>Ημέρα Ανεξαρτησίας</li><li>Ημέρα των Νεκρών</li></ul><p style="margin: 8pt;"><a target="_blank" href="https://forum.the-west.gr/showthread.php?t=8029">Συζήτηση στο Φόρουμ</a> | <a target="_blank" href="https://greasyfork.org/scripts/2992-tw-friends/feedback">Feedback</a>: Αναφορά Bugs, Ιδέες, Μεταφράσεις.</p><p style="margin: 8pt;"><b>Ευχαριστίες</b>: '+scriptCredits+'</p>',
				version: 'έκδοση',
				version_checkFailed: 'Ο αυτόματος έλεγχος για ενημερώσεις απέτυχε',
				version_checkManual: 'Μη αυτόματος έλεγχος',
				version_ok: 'Έχεις ήδη την τελευταία έκδοση',
				version_upgrade: 'Μια νέα έκδοση είναι διαθέσιμη. Θες να την εγκαταστήσεις;',
				refresh: 'Ανανέωση',
				timeLeft: 'Χρόνος που υπολείπεται μέχρι το τέλος της εκδήλωσης',
				serverTime: 'ώρα διακομιστή',
				availFriends: 'Αριθμός Φιλων στους οποίους μπορείς να στείλεις τώρα',
				totalFriends: 'Αριθμός Φίλων',
				pendingInvitation: 'Μία εκκρεμής πρόσκληση',
				pendingInvitations: 'εκκρεμείς πρoσκλήσεις',
				noFriends: 'Δεν έχεις φίλους',
				name: 'Όνομα',
				received: 'Έλαβες',
				frequency: 'Συχνότητα',
				removeFriend: 'Αφαίρεση φίλου',
				removeConfirm: 'Θέλεις πραγματικά να διαγράψεις αυτόν τον παίχτη από τη λίστα;',
				removeSuccess: 'Ο φίλος αφαιρέθηκε από τη λίστα.',
				removeFailed: 'Ο φίλος δεν μπόρεσε να αφαιρεθεί',
				exporter: 'Εξαγωγή',
				everything: 'Όλα',
				stats: 'Στατιστικά',
				since: 'από',
				collected: 'Έχεις συλλέξει',
				friends: 'Φίλοι',
				jobs: 'Εργασίες',
				fortBattles: 'Μάχες Οχυρών',
				adventures: 'Περιπέτειες',
				duels: 'Μονομαχίες',
				npcDuels: 'Μονομαχίες με NPC',
				construction: 'Χτίσιμο',
				quests: 'Αποστολές',
				itemUse: 'Χρήση Αντικειμένων',
				other: 'Άλλα',
				used: 'Έχεις χρησιμοποιήσει',
				timerReset: 'Μηδενισμός χρονομέτρου',
				bribe: 'Δωροδοκίες',
				inventory: 'Αποθέματα',
				wofCat: [ 'Συνηθισμένα', 'Ασυνήθιστα', 'Σπάνια', 'Πολύ Σπάνια' ],
				wofState: {
					Octoberfest: [ 'Περιμένεις να σερβιριστεί το επόμενο πιάτο', 'Δεν διαθέτεις αρκετά πρέτσελ', 'Διαθέτεις αρκετά πρέτσελ για να φας', 'Διαθέτεις αρκετά πρέτσελ για να φας και να δωροδοκήσεις!' ]
				},
				nextYear: 'Του χρόνου',
				theEnd: 'Τετέλεσται',
			},
			en_US: {
				description: '<h1>Friend Management for The West Events</h1><p style="margin: 8pt;">Don&#039;t click too fast, to avoid a streak of bad luck upon you :)</p><p style="margin: 8pt;">Supported Events:</p><ul style="list-style: disc outside; margin-left: 16pt; padding-left: 16pt;"><li>Valentine&#039;s Day</li><li>Easter</li><li>Independence Day</li><li>Oktoberfest</li><li>Day of the Dead</li></ul><p style="margin: 8pt;"><a target="_blank" href="https://greasyfork.org/scripts/2992-tw-friends/feedback">Feedback</a>: Bug Reports, Ideas, Translations (in English).</p><p style="margin: 8pt;"><b>Credits</b>: '+scriptCredits+'</p>',
				version: 'version',
				version_checkFailed: 'Unable to check for updates',
				version_checkManual: 'Check manually',
				version_ok: 'You already have the latest version',
				version_upgrade: 'A new version is available. Do you want to upgrade now?',
				refresh: 'Refresh',
				timeLeft: 'Time Left until the event ends',
				serverTime: 'server time',
				availFriends: 'Number of Friends you can send now',
				totalFriends: 'Number of Friends',
				pendingInvitation: 'One pending invitation',
				pendingInvitations: 'pending invitations',
				noFriends: 'No Friends',
				name: 'Name',
				received: 'Received',
				frequency: 'Frequency',
				removeFriend: 'Remove friend',
				removeConfirm: 'Do you really want to delete this player from the list?',
				removeSuccess: 'Friend removed from your list.',
				removeFailed: 'Friend could not be removed',
				exporter: 'Export',
				everything: 'Everything',
				stats: 'Stats',
				since: 'since',
				collected: 'Collected',
				friends: 'Friends',
				jobs: 'Jobs',
				fortBattles: 'Fort Battles',
				adventures: 'Adventures',
				duels: 'Duels',
				npcDuels: 'NPC Duels',
				construction: 'Construction',
				quests: 'Quests',
				itemUse: 'Item Use',
				other: 'Other',
				used: 'Used',
				timerReset: 'Reset Timers',
				bribe: 'Bribe',
				gameAction: 'Event game action',
				inventory: 'Inventory',
				wofCat: [ 'Common', 'Uncommon', 'Rare', 'Very Rare' ],
				wofState: {
					Octoberfest: [ 'Waiting for the next dish to be served', 'Not enough pretzels to pay for a serving', 'Enough pretzels to pay for a serving', 'Enough pretzels to pay for a serving and bribe the waiting staff' ]
				},
				nextYear: 'Next Year',
				theEnd: 'The End',
			},
			es_ES: {
				description: '<h1>Gestión de Amigos para Eventos de The West</h1><p style="margin: 8pt;">No haga clic demasiado rápido, para evitar una racha de mala suerte :)</p><p style="margin: 8pt;">Eventos soportados:</p><ul style="list-style: disc outside; margin-left: 16pt; padding-left: 16pt;"><li>Día de San Valentín</li><li>Pascua</li><li>Día de la Independencia</li><li>Oktoberfest</li><li>Día de los Muertos</li></ul><p style="margin: 8pt;"><a target="_blank" href="https://greasyfork.org/scripts/2992-tw-friends/feedback">Comentarios</a>: Bug Reports, Ideas, Translations (in English).</p><p style="margin: 8pt;"><b>Créditos</b>: '+scriptCredits+'</p>',
				version: 'versión',
				version_checkFailed: 'No se puede comprobar actualizaciones',
				version_checkManual: 'Compruebe manualmente',
				version_ok: 'Ya tienes la última versión',
				version_upgrade: 'Una nueva versión está disponible. ¿Quieres instalarla ahora?',
				refresh: 'Actualizar',
				timeLeft: 'Tiempo que queda hasta el final del evento',
				serverTime: 'hora del servidor',
				availFriends: 'Número de Amigos que se puede enviar ahora',
				totalFriends: 'Número de Amigos',
				pendingInvitation: 'Una invitación pendiente',
				pendingInvitations: 'invitaciones pendientes',
				noFriends: 'Sin Amigos',
				name: 'Nombre',
				received: 'Recibidos',
				frequency: 'Frecuencia',
				removeFriend: 'Remover amigo',
				removeConfirm: '¿Estas seguro que quieres eliminar a este jugador de tu lista?',
				removeSuccess: 'Amigo removido de tu lista',
				removeFailed: 'El amigo no ha podido ser eliminado',
				exporter: 'Exportar',
				everything: 'Todo',
				stats: 'Estadísticas',
				since: 'desde',
				collected: 'Conseguidos',
				friends: 'Amigos',
				jobs: 'Trabajos',
				fortBattles: 'Batallas de fuertes',
				adventures: 'Aventuras',
				duels: 'Duelos',
				npcDuels: 'Duelos NPC',
				construction: 'Ampliación',
				quests: 'Busquedas',
				itemUse: 'Objetos usados',
				other: 'Otros',
				used: 'Usados',
				timerReset: 'Reiniciar temporizadores',
				bribe: 'Soborno',
				inventory: 'Inventario',
				wofCat: [ 'Común', 'No común', 'Raro', 'Muy raro' ],
				wofState: {
					Octoberfest: [ 'Esperando para ser servido', 'No tienes suficientes pretzels', 'Tienes suficientes pretzels para pagar', 'Tienes suficientes pretzels para pagar y sobornar' ]
				},
				nextYear: 'El próximo año',
				theEnd: 'Final',
			},
			fr_FR: {
				description: '<h1>Gestion des Amis pour les Evénements de The West</h1><p style="margin: 8pt;">Ne cliquez pas trop vite, pour éviter une série de malchance sur vous :)</p><p style="margin: 8pt;">Evénements:</p><ul style="list-style: disc outside; margin-left: 16pt; padding-left: 16pt;"><li>Saint Valentin</li><li>Pâques</li><li>Jour De L&#039;Indépendance</li><li>Oktoberfest</li><li>Jour des Morts</li></ul><p style="margin: 8pt;"><a target="_blank" href="https://greasyfork.org/scripts/2992-tw-friends/feedback">Commentaires</a>: Bug Reports, Ideas, Translations (in English).</p><p style="margin: 8pt;"><b>Credits</b>: '+scriptCredits+'</p>',
				version: 'version',
				version_checkFailed: 'Impossible de vérifier les mises à jour',
				version_checkManual: 'Vérifier manuellement',
				version_ok: 'Tu as déjà la dernière version',
				version_upgrade: 'Une nouvelle version est disponible. Installer maintenant?',
				refresh: 'Rafraîchir',
				timeLeft: "Temps restant jusqu'à la fin de l'événement",
				serverTime: 'horaire du serveur',
				availFriends: 'Nombre des amis que tu peux envoyer maintenant',
				totalFriends: 'Nombre des Amis',
				pendingInvitation: 'Une invitation en attente',
				pendingInvitations: 'invitations en attentes',
				noFriends: "Pas d'Amis",
				name: 'Nom',
				received: 'Tu as reçu',
				frequency: 'Fréquence',
				removeFriend: "Supprimer l'ami(e)",
				removeConfirm: 'Veux-tu vraiment supprimer ce joueur de la liste?',
				removeSuccess: 'Ami supprimé de la liste',
				removeFailed: "L'ami n'a pas pu être supprimé",
				exporter: 'Exportation',
				everything: 'Tout',
				stats: 'Statistiques',
				since: 'à partir de',
				collected: 'Collectés',
				friends: 'Amis',
				jobs: 'Travaux',
				fortBattles: 'Batailles',
				adventures: 'Aventures',
				duels: 'Duels',
				npcDuels: 'Duels PNJ',
				construction: 'Agrandissement',
				quests: 'Quêtes',
				itemUse: 'Objets utilisés',
				other: 'Autres',
				used: 'Utilisés',
				timerReset: 'Se battre en duel',
				bribe: 'Soudoyer',
				inventory: 'Inventaire',
				wofCat: [ 'Commun', 'Non commun', 'Rare', 'Très rare' ],
				wofState: {
					Octoberfest: [ "En attendant d'être servi", "Tu n'as pas assez de Bretzels", 'Tu as assez de Bretzels pour payer', 'Tu as assez de Bretzels pour payer et soudoyer' ]
				},
				nextYear: "L'année prochaine",
				theEnd: 'La Fin',
			},
			it_IT: {
				description: '<h1>Gestione amici per gli eventi The West</h1><p style="margin: 8pt;">Non clickare tropo veloce, per non essere bloccato :)</p><p style="margin: 8pt;">Eventi supportati:</p><ul style="list-style: disc outside; margin-left: 16pt; padding-left: 16pt;"><li>Giorno San Valentino</li><li>Pasqua</li><li>Giorno dell&#039;Independenza</li><li>Oktoberfest</li><li>Il giorno dei morti</li></ul><p style="margin: 8pt;"><a target="_blank" href="https://greasyfork.org/scripts/2992-tw-friends/feedback">Feedback</a>: Bug Report, Ideee, Traduzioni (in English).</p><p style="margin: 8pt;"><b>Credits</b>: '+scriptCredits+'</p>',
				version: 'versione',
				version_checkFailed: 'Impossibile verificare gli aggiornamenti',
				version_checkManual: 'Controllare manualmente',
				version_ok: "Hai già l'ultima versione",
				version_upgrade: 'Nuova versione disponibile. Vuoi aggiornare adesso?',
				refresh: 'Aggiorna',
				timeLeft: 'Tempo rimanente fino alla fine dell&#039;evento',
				serverTime: 'server time',
				availFriends: 'Totale amici che puoi inviare adesso',
				totalFriends: 'Amici totale',
				pendingInvitation: 'Invito in attesa',
				pendingInvitations: 'inviti in attesa',
				noFriends: 'Non ci sono amici',
				name: 'Nome',
				received: 'Ricevuti',
				frequency: 'Freqvenza',
				removeFriend: 'Rimuovi amico',
				removeConfirm: 'Sei sicuro di voler cancellare l&#039;amico dalla lista?',
				removeSuccess: 'Amico rimosso dalla tua lista.',
				removeFailed: 'Impossibile rimuovere l&#039;amico',
				exporter: 'Esporta',
				everything: 'Tutto',
				stats: 'Statistiche',
				since: 'dal',
				collected: 'Collezionate',
				friends: 'Amici',
				jobs: 'Lavori',
				fortBattles: 'Battaglie forti',
				adventures: 'Avventure',
				duels: 'Duelli',
				npcDuels: 'Duelli con NPC',
				construction: 'Costruzione',
				quests: 'Missioni',
				itemUse: 'Oggetti usati',
				other: 'Altro',
				used: 'Usato',
				timerReset: 'Reseta Timer',
				bribe: 'Corruzione',
				gameAction: 'Event game action',
				inventory: 'Inventario',
				wofCat: [ 'Molto comune', 'Comune', 'Raro', 'Molto raro' ],
				wofState: {
					Octoberfest: [ 'In attesa di essere servita', 'Non hai abbastanza pretzel', 'Hai abbastanza pretzel per pagare', 'Hai abbastanza pretzel per pagare e corrompere' ]
				},
				nextYear: 'Anno prossimo',
				theEnd: 'Fine',
			},
			pl_PL: {
				description: '<h1>Menadżer zarządzania Przyjaciółmi podczas eventów The West</h1><p style="margin: 8pt;">Nie klikaj zbyt szybko, bo to będzie bardzo niemiłe dla Ciebie :)</p><p style="margin: 8pt;">Obsługiwane Eventy:</p><ul style="list-style: disc outside; margin-left: 16pt; padding-left: 16pt;"><li>Walentynki</li><li>Wielkanoc</li><li>Dzień Niepodległości</li><li>Oktoberfest</li><li>Dia de los Muertos</li></ul><p style="margin: 8pt;"><a target="_blank" href="https://forum.the-west.pl/showthread.php?t=60424">Forum</a> | <a target="_blank" href="https://greasyfork.org/scripts/2992-tw-friends/feedback">Opinie</a>: Zgłaszanie błędów, pomysłów, propozycji zmian (w języku angielskim).</p><p style="margin: 8pt;"><b>Uznanie dla</b>: '+scriptCredits+'</p>',
				version: 'wersja',
				version_checkFailed: 'Nie można sprawdzić aktualizacji',
				version_checkManual: 'Sprawdź ręcznie',
				version_ok: 'Masz już najnowszą wersję',
				version_upgrade: 'Dostępna jest nowa wersja. Czy chcesz dokonać aktualizacji?',
				refresh: 'Odśwież',
				timeLeft: 'Czas pozostały do zakończenia eventu',
				serverTime: 'czasu serwera',
				availFriends: 'Liczba przyjaciół do których można wysłać prezent',
				totalFriends: 'Łączna liczba przyjaciół',
				pendingInvitation: 'jedno oczekujące zaproszenie',
				pendingInvitations: 'oczekujących zaproszeń',
				noFriends: 'Brak przyjaciół',
				name: 'Nazwa gracza',
				received: 'Otrzymano',
				frequency: 'Częstotliwość',
				removeFriend: 'Usuń przyjaciela',
				removeConfirm: 'Czy na pewno chcesz usunąć tego gracza z listy przyjaciół?',
				removeSuccess: 'Przyjaciel usunięty z Twojej listy.',
				removeFailed: 'Nie można usunąć przyjaciela',
				exporter: 'Eksport',
				everything: 'Wszystko',
				stats: 'Statystyka',
				since: 'od',
				collected: 'Uzbierano',
				friends: 'Znajomi',
				jobs: 'Prace',
				fortBattles: 'Bitwy fortowe',
				adventures: 'Przygody',
				duels: 'Pojedynki',
				npcDuels: 'Pojedynki z NPC',
				construction: 'Rozbudowa',
				quests: 'Zadania',
				itemUse: 'Użycie przedmiotów',
				other: 'Inne',
				used: 'Użyto',
				timerReset: 'Zresetuj liczniki',
				bribe: 'Przekup',
				gameAction: 'Akcje podczas eventu',
				inventory: 'Ekwipunek',
				wofCat: [ 'Bardzo powszechny', 'Powszechny', 'Rzadki', 'Bardzo rzadki' ],
				nextYear: 'W przyszłym roku',
				theEnd: 'Koniec',
			},
			pt_PT: {
				description: '<h1>Gestão de amigos para eventos no The West</h1><p style="margin: 8pt;">não clique rápido demais, para evitar uma maré de azar :)</p><p style="margin: 8pt;">Eventos suportados:</p><ul style="list-style: disc outside; margin-left: 16pt; padding-left: 16pt;"><li>Dia dos namorados</li><li>Páscoa</li><li>Dia da independência</li><li>Oktoberfest</li><li>Dia de los Muertos</li></ul><p style="margin: 8pt;"><a target="_blank" href="https://greasyfork.org/scripts/2992-tw-friends/feedback">Comentários</a>: Bug Reports, Ideas, Translations (in English).</p><p style="margin: 8pt;"><b>Créditos</b>: '+scriptCredits+'</p>',
				version: 'versão',
				version_checkFailed: 'Não é possível verificar atualizações',
				version_checkManual: 'Verifique manualmente',
				version_ok: 'Você já possui a versão mais recente',
				version_upgrade: 'A nova versão está disponível. Atualize agora?',
				refresh: 'Actualizar',
				timeLeft: 'Tempo restante até ao final do evento',
				serverTime: 'hora do servidor',
				availFriends: 'Número de amigos a quem pode enviar agora',
				totalFriends: 'Número de Amigos',
				pendingInvitation: 'Um convite pendente',
				pendingInvitations: 'convites pendentes',
				noFriends: 'Sem Amigos',
				name: 'Nome',
				received: 'Recebidos',
				frequency: 'Freqüência',
				removeFriend: 'Remover amigo',
				removeConfirm: 'Queres mesmo remover amigo da lista ?',
				removeSuccess: 'Amigo removido da lista',
				removeFailed: 'Amigo não pode ser removido',
				exporter: 'Exportar',
				everything: 'Tudo',
				stats: 'Estatísticas',
				since: 'desde',
				collected: 'Recolhidos',
				friends: 'Amigos',
				jobs: 'Trabalhos',
				fortBattles: 'Batalhas de Forte',
				adventures: 'Aventuras MPI',
				duels: 'Duelos',
				npcDuels: 'Duelos NPC',
				construction: 'Construção',
				quests: 'Aventuras',
				itemUse: 'Itens usados',
				other: 'Outros',
				used: 'Usados',
				timerReset: 'Reiniciar temporizadores',
				bribe: 'Suborno',
				inventory: 'Inventário',
				wofCat: [ 'Comum', 'Fora do Comum', 'Raro', 'Muito Raro' ],
				nextYear: 'Próximo Ano',
				theEnd: 'Final',
			},
			tr_TR: {
				description: '<h1>The West Etkinlikleri İçin Arkadaş Yöneticisi</h1><p style="margin: 8pt;">Üzerinde kara bulutların dolaşmasını istemiyorsan çok hızlı tıklama :)</p><p style="margin: 8pt;">Desteklenen Etkinlikler:</p><ul style="list-style: disc outside; margin-left: 16pt; padding-left: 16pt;"><li>Sevgililer Günü</li><li>Paskalya</li><li>Bağımsızlık Günü</li><li>Ekim Festivali</li><li>Ölülerin Günü</li></ul><p style="margin: 8pt;"><a target="_blank" href="https://greasyfork.org/scripts/2992-tw-friends/feedback">Geri Bildirim</a>: Açık Raporları, Fikirler, Çeviriler (İngilizce).</p><p style="margin: 8pt;"><b>Yapımcılar</b>: '+scriptCredits+'</p>',
				version: 'versiyon',
				version_upgrade: 'Yeni versiyon mevcut. Şimdi yükseltmek istiyor musun?',
				refresh: 'Yenile',
				timeLeft: 'Etkinliğin bitmesine kalan süre',
				serverTime: 'sunucu süresi',
				availFriends: 'Şimdi gönderebileceğin arkadaş sayısı',
				totalFriends: 'Arkadaş Sayısı',
				pendingInvitation: 'Bir davetiye bekliyor',
				pendingInvitations: 'bekleyen davetiyeler',
				noFriends: 'Arkadaş Yok',
				name: 'İsim',
				received: 'Alınan',
				frequency: 'Sıklık',
				removeFriend: 'Arkadaşı Sil',
				removeConfirm: 'Bu oyuncuyu gerçekten listeden silmek istiyor musun?',
				removeSuccess: 'Arkadaşın listeden silindi.',
				removeFailed: 'Arkadaş silinemedi',
				exporter: 'Çıkar',
				everything: 'Her şey',
				stats: 'İstatistikler',
				since: 'başlangıç',
				collected: 'Toplanan',
				friends: 'Arkadaşlar',
				jobs: 'Çalışmalar',
				fortBattles: 'Kale Savaşları',
				adventures: 'Maceralar',
				duels: 'Düellolar',
				npcDuels: 'Haydut Düelloları',
				construction: 'Kurma',
				quests: 'Görevler',
				itemUse: 'Kullanılan Ürünler',
				other: 'Diğer',
				used: 'Kullanılan',
				timerReset: 'Zamanlayıcıyı Sıfırla',
				bribe: 'Rüşvet',
				gameAction: 'Etkinlik oyunu eylemi',
				inventory: 'Envanter',
				wofCat: [ 'Sıradan', 'Sıradan olmayan', 'Nadir', 'Çok nadir' ],
				nextYear: 'Gelecek Yıl',
				theEnd: 'Son',
			},
		},
		timeLeft : 0,
		total : 0,
		avail: 0,
		log: { firstLog: Date.now()/1e3, lastLog: 0, newLastLog: 0, friendLog: {}, entries: [], count_friends: 0, count_job: 0, count_duel: 0, count_npc: 0, count_fort: 0, count_mpi: 0, count_quest: 0, count_build: 0, count_item: 0, count_other: 0, count_reset: 0, count_bribe: 0, count_action: 0, times_reset: 0, times_bribe: 0, received: 0, used: 0 },
		spanCounter: $("<span />", { id: "hiro_friends_counter", style: "position: absolute; right: 5px; color: #f8c57c; font-size: 13pt; height: 25px; line-height: 25px; bottom: 0px" }),
		spanInvitations: null,
		divTombola: null,
		divFriendsAvail: null,
		imgFriendsAvail: null,
		/* Inno buildDateObject() function currently buggy */
		buildDateObject: function(timeStr, isServerTime) {
			var regEx, match, d = new Date(0), today = new Date();
			regEx = /^(?:(3[01]|[012]?[0-9]|\*)\.(?:(1[012]|0?[1-9]|\*)\.((?:19|20)?\d\d|\*)))?(?: ?(2[0-3]|[01]?\d|\*)\:([0-5]?\d|\*)(?:\:([0-5]?\d|\*))?)?$/;
			if(match = timeStr.match(regEx)) {
				d.setFullYear(match[3] !== undefined ? (match[3] == '*' ? today.getFullYear() : parseInt(match[3], 10)) : today.getFullYear());
				d.setMonth(match[2] !== undefined ? (match[2] == '*' ? today.getMonth() : parseInt(match[2], 10) - 1) : today.getMonth());
				d.setDate(match[1] !== undefined ? (match[1] == '*' ? today.getDate() : parseInt(match[1], 10)) : today.getDate());
				d.setHours(match[4] !== undefined ? (match[4] == '*' ? today.getHours() : match[4]) : 0);
				d.setMinutes(match[5] !== undefined ? (match[5] == '*' ? today.getMinutes() : match[5]) : 0);
				d.setSeconds(match[6] !== undefined ? (match[6] == '*' ? today.getSeconds() : match[6]) : 0);
				d.setMilliseconds(0);
			}
			if(isServerTime) d = new Date(d - Game.serverTimeDifference);
			return d;
		},
		buildTimeStamp: function (timeStr, isServerTime) {
			return this.buildDateObject(timeStr, isServerTime).getTime();
		},
		items: {
			Hearts: {
				2557000 : 1250,		/* Small Heart Bag - 1250 hearts */
				2558000 : 2500,		/* Large Heart Bag - 2500 hearts */
				2561000 : 100,		/* Love Apple - 100 hearts */
				2562000 : 500,		/* Sugar hearts - 500 hearts */
				2563000 : 650,		/* 650 hearts */
				2564000 : 1500,		/* 1500 hearts */
				2565000 : 3250,		/* 3250 hearts */
				2566000 : 9000,		/* 9000 hearts */
				2567000 : 16000,	/* 16000 hearts */
			},
			Easter: {
				2698000 : 2500,		/* Efficient Easter egg container - 2500 eggs */
				2590000 : 650,		/* 650 Eggs */
				2591000 : 1500,		/* 1500 Eggs */
				2592000 : 3250,		/* 3250 Eggs */
				2593000 : 9000,		/* 9000 Eggs */
				2594000 : 16000,	/* 16000 Eggs */
			},
			Independence: {
				2619000 : 650,
				2620000 : 1500,
				2621000 : 3250,
				2622000 : 9000,
				2623000 : 16000,
			},
			Octoberfest: {
				50691000 : 2500,	/* Bag of Pretzels */
				371000 : 650,
				973000 : 1500,
				974000 : 3250,
				975000 : 9000,
				976000 : 16000,
			},
			DayOfDead: {
				2665000 : 1250,		/* Flower pot - 1250 Cempasúchil flowers */
				2666000 : 2500,		/* Big Flower pot - 2500 Cempasúchil flowers */
				2675000 : 25,		/* Cempasúchil Case - 25 Cempasúchil flowers */
				2676000 : 650,
				2677000 : 1500,
				2678000 : 3250,
				2679000 : 9000,
				2680000 : 16000,
			}
		},
		eventItems: {
			divInventory: null,
			imgInventory: null,
			imgTitle: '',
			Inventory: [],
			Available: [],
			total: 0,
			coolDownComplete: false,
			check: function () {
				HiroFriends.eventItems.Inventory = [];
				HiroFriends.eventItems.Available = [];
				HiroFriends.eventItems.total = 0;
				HiroFriends.eventItems.coolDownComplete = false;
				if(undefined === HiroFriends.items[HiroFriends.eventName]) return false;
				var now = new ServerDate().getTime()/1e3, coolDown, invItem;
				$.each(HiroFriends.items[HiroFriends.eventName], function(itemId, amount) {
					invItem = Bag.getItemByItemId(itemId);
					if(invItem) {
						HiroFriends.eventItems.Inventory.push(invItem);
						coolDown = Bag.itemCooldown[itemId];
						if(!coolDown) {
							HiroFriends.eventItems.Available.push(invItem);
							HiroFriends.eventItems.total += invItem.count*amount;
						}
						else if(coolDown <= now) {
							HiroFriends.eventItems.coolDownComplete = true;
							HiroFriends.eventItems.Available.push(invItem);
							HiroFriends.eventItems.total += amount;
						}
					}
				});
				HiroFriends.eventItems.imgInventory.attr('src', HiroFriends.eventItems.coolDownComplete ? HiroFriends.cdnBase+'/images/icons/clock.png' : HiroFriends.eventCurrencyImage);
				HiroFriends.eventItems.imgInventory.attr('title', HiroFriends.eventItems.total ? HiroFriends.eventItems.total+' <img src="' + HiroFriends.eventCurrencyImage + '" alt="">' : '');
				return true;
			},
			display: function() {
				HiroFriends.eventItems.check();
				if(HiroFriends.eventItems.Inventory.length > 0) {
					if(!Bag.loaded) {
						EventHandler.listen('inventory_loaded', function () {
							Wear.open();
							Inventory.showSearchResult(HiroFriends.eventItems.Inventory);
							return EventHandler.ONE_TIME_EVENT;
						});
						Bag.loadItems();
					}
					else {
						Wear.open();
						Inventory.showSearchResult(HiroFriends.eventItems.Inventory);
					}
				}
				HiroFriends.eventItems.divInventory.hide();
			},
		},
		signalHandlers: function() {
			var signal = Game.sesData[HiroFriends.eventName].counter.key;
			EventHandler.listen(signal, function(data) {
				if (HiroFriends.wofId) {
					var newAmount = parseInt(data);
					if (newAmount < HiroFriends.wallet) HiroFriends.getWofStatus();
					else if (newAmount > HiroFriends.wallet) {
						HiroFriends.wallet = newAmount;
						HiroFriends.divTombola.fadeOut(400, function() { HiroFriends.displayWofStatus(); }).fadeIn(400);
					}
				}
			});
			if(enableInv) {
				EventHandler.listen(['inventory_changed', 'cooldown_changed'], function() {
					if(HiroFriends.eventItems.check() && HiroFriends.eventItems.Available.length > 0)
						HiroFriends.eventItems.divInventory.show(5000);
					else HiroFriends.eventItems.divInventory.hide();
				});
			}
		},
		display: function(sort) {
			var friend_time, server_time = Game.getServerTime();
			var maindiv = $('<div class="hiro_friends_maindiv" />');
			var friends = [];
			for(var key in this.friends) if(this.friends.hasOwnProperty(key)) friends.push({ id: key, name: this.friends[key].name, activation_time: this.friends[key].activation_time, recv: this.friends[key].recv });
			if(!friends.length) $('<h1 style="text-align: center; color: #990000; margin-bottom: 80px;">'+this.localeMsg('noFriends')+'</h1>').appendTo(maindiv);
			else {
				var hiroTable;
				switch(sort) {
					case "name" 	:	friends.sort(this.sortByName); break;
					case "name_desc":	friends.sort(this.sortByName).reverse(); break;
					case "recv" 	:	friends.sort(this.sortByRecv); break;
					case "recv_asc"	:	friends.sort(this.sortByRecv).reverse(); break;
					case "time_asc"	:	friends.sort(this.sortByTime).reverse(); break;
					case "time"	:
					default		:	sort = "time"; friends.sort(this.sortByTime);
				}
				var thName = $('<a style="cursor: pointer;"><img src="'+this.cdnBase+'/images/icons/user.png" alt="" />&nbsp;'+this.localeMsg('name')+'</a>').click(function(){ HiroFriends.display(sort == 'name' ? 'name_desc' : 'name'); return false; });
				var thAction = $('<a style="cursor: pointer;"><img src="'+this.cdnBase+'/images/icons/clock.png" alt="" />&nbsp;'+this.eventInfo.label+'</a>').click(function(){ HiroFriends.display(sort == 'time' ? 'time_asc' : 'time'); return false; });
				var thRecv = enableLog ? $('<a style="cursor: pointer;" title="'+this.localeMsg('since')+' '+new Date(this.log.firstLog*1e3).toDateTimeString()+'"><img src="'+this.cdnBase+'/images/icons/watch.png" alt="" />&nbsp;'+this.localeMsg('received')+'</a>').click(function(){ HiroFriends.display(sort == 'recv' ? 'recv_asc' : 'recv'); return false; }) : '';
				hiroTable = new west.gui.Table().appendTo(maindiv).addColumn("hf_idx").addColumn("hf_player").addColumn("hf_action").addColumn("hf_log").addColumn("hf_delete").appendToCell("head", "hf_idx", '&nbsp;').appendToCell("head", "hf_player", thName).appendToCell("head", "hf_action", thAction).appendToCell("head","hf_log",thRecv).appendToCell("head", "hf_delete", '&nbsp;');
				var idx = 1;
				var now = Date.now()/1e3;
				$.each(friends, function(key, val) {
					var actionCell, recvCell;
					friend_time = val.activation_time + HiroFriends.eventInfo.cooldown - server_time;
					if(friend_time > HiroFriends.timeLeft) actionCell = '('+HiroFriends.localeMsg('nextYear')+')';
					else if(friend_time > 0) actionCell = '('+friend_time.formatDurationBuffWay()+')';
					else {
						actionCell = $('<a style="cursor: pointer;">'+HiroFriends.eventInfo.label+'</a>').click({ id: val.id, ev: HiroFriends.eventName }, function(e) {
							$(this).parent().parent().remove();
							Ajax.remoteCall("friendsbar", "event", { player_id: val.id, event: HiroFriends.eventName }, function(response) {
								if(response.error) return MessageError(response.msg).show();
								MessageSuccess(response.msg).show();
								HiroFriends.friends[val.id].activation_time = Date.now()/1e3;
								if(HiroFriends.avail) -- HiroFriends.avail;
								HiroFriends.updateCounter();
								if(WestUi.FriendsBar.friendsBarUi !== null)
									WestUi.FriendsBar.friendsBarUi.friendsBar.eventActivations[val.id][HiroFriends.eventName] = response.activationTime;
							});
							return false;
						});
					}
					recvCell = '';
					if(enableLog) {
						if(val.recv) {
							var recv_list = '';
							HiroFriends.log.friendLog[val.id].dates.sort(function(a, b){ return new Date(a)-new Date(b); });
							if(HiroFriends.log.friendLog[val.id].total && HiroFriends.log.friendLog[val.id].dates.length > 1) {
								recv_list += '<p style=&quot;text-align: center; margin-bottom: 8px;&quot;>'+HiroFriends.localeMsg('frequency')+': <b>'+((now - HiroFriends.log.friendLog[val.id].dates[0]) / (HiroFriends.log.friendLog[val.id].dates.length-1)).formatDuration()+'</b></p>';
							}
							recv_list += '<ol style=&quot;list-style-type: decimal; padding: 0 0 0 20px;&quot;>';
							$.each(HiroFriends.log.friendLog[val.id].dates, function(dkey, dval) {
								recv_list += '<li style=&quot;display: list-item; white-space: nowrap;&quot;>' + new Date(dval * 1e3).toDateTimeStringNice() + '</li>';
							});
							recv_list += '<ol>';
							recvCell = '<span title="'+recv_list+'" style="cursor: help;">'+val.recv+'</span>';
						}
						else recvCell = val.recv;
					}
					hiroTable.appendRow(null, 'hiroFriendRow_'+val.id)
						.appendToCell(-1, "hf_idx", idx)
						.appendToCell(-1, "hf_player", '<a href="javascript:void(PlayerProfileWindow.open('+val.id+'));">' + val.name + '</a>')
						.appendToCell(-1, "hf_action", actionCell)
						.appendToCell(-1, "hf_log", recvCell)
						.appendToCell(-1, "hf_delete", '<a href="javascript:void(HiroFriends.removeFriend('+val.id+'));"><img style="width:16px; height: 16px;" title="'+HiroFriends.localeMsg('removeFriend')+'" src="'+HiroFriends.cdnBase+'/images/icons/delete.png" alt="delete" /></a>');
					++ idx;
				});
				hiroTable.appendToCell('foot', 'hf_idx', '<a target="_blank" href="'+URL_INSTALL+'"><img src="'+this.cdnBase+'/images/icons/link.png" alt=""></a>');
				hiroTable.appendToCell('foot', 'hf_player', '<a target="_blank" href="'+URL_INSTALL+'">'+scriptName+'</a> '+this.localeMsg('version')+' ' + this.version.toFixed(2));
				if('https://gr1.the-west.gr' == Game.gameURL || 'https://gr4.the-west.gr' == Game.gameURL || 'https://gr5.the-west.gr' == Game.gameURL) hiroTable.appendToCell('foot', 'hf_action', 'by <a href="javascript:void(PlayerProfileWindow.open(92184));">'+scriptAuthor+'</a>');
				else if('https://zz1.beta.the-west.net' == Game.gameURL) hiroTable.appendToCell('foot', 'hf_action', 'by <a href="javascript:void(PlayerProfileWindow.open(16866));">'+scriptAuthor+'</a>');
				else hiroTable.appendToCell('foot', 'hf_action', 'by '+scriptAuthor);
				if(this.pendingInvitations) hiroTable.appendToCell('foot', 'hf_delete', '<a href="javascript:void(FriendslistWindow.open(\'openrequests\'));"><img style="width:16px; height: 16px;" title="'+this.pendingInvitationsMsg()+'" src="'+this.cdnBase+'/images/icons/friends.png" alt="add" /></a>');
				if(enableLog) hiroTable.appendToCell('foot', 'hf_log', $('<a style="cursor: pointer;">'+HiroFriends.localeMsg('exporter')+'</a>').click(function() {
					HiroFriends.log.entries.sort(function(a,b) { return a.date - b.date; });
					var tsv_friends = "id\t"+HiroFriends.localeMsg('name')+"\t"+HiroFriends.localeMsg('received')+"\r\n";
					$.each(HiroFriends.log.friendLog, function(key,val) { tsv_friends += key+"\t"+val.name+"\t"+val.total+"\r\n"; });
					new west.gui.Dialog(HiroFriends.localeMsg('exporter'),'<b>'+HiroFriends.localeMsg('friends')+'</b> (<a download="TW Friends - '+HiroFriends.eventName+' - '+ Game.worldName+' - '+Character.name+' - '+HiroFriends.localeMsg('friends')+' - '+Date.now()+'.tsv" href="data:text/tab-separated-values,'+encodeURI(tsv_friends)+'">TSV</a>):<br /><textarea cols="60" rows="8" style="width: 100%; height: 100px;">' + JSON.stringify(HiroFriends.log.friendLog) + '</textarea><br /><b>'+HiroFriends.localeMsg('everything')+'</b>:<br /><textarea cols="60" rows="8" style="width: 100%; height: 100px;">' + JSON.stringify(HiroFriends.log.entries) + '</textarea>').setModal(true,true,{bg:HiroFriends.cdnBase+'/images/curtain_bg.png',opacity:0.7}).addButton("ok").show();
					return false;
				}) );
			}
			if(enableLog || this.eventItems.total) {
				var statsTable = '<table style="margin: auto; width: 96%;">';
				if(enableLog) statsTable += '<tr><th colspan="3" style="border-bottom: 1px dotted;">'+this.localeMsg('stats')+' ('+this.localeMsg('since')+' '+new Date(this.log.firstLog*1e3).toDateTimeString()+')</th></tr><tr style="vertical-align: top;"><td style="white-space: nowrap;">'+this.localeMsg('collected')+':</td><td style="color: #006600; font-weight: bold; text-align: right; padding-right: 8pt;">'+this.log.received+'</td><td> <span style="white-space: nowrap;">'+this.localeMsg('friends')+': <b>'+this.log.count_friends+'</b>,</span> <span style="white-space: nowrap;">'+this.localeMsg('jobs')+': <b>'+this.log.count_job+'</b>,</span> <span style="white-space: nowrap;">'+this.localeMsg('fortBattles')+': <b>'+this.log.count_fort+'</b>,</span> <span style="white-space: nowrap;">'+this.localeMsg('adventures')+': <b>'+this.log.count_mpi+'</b>,</span> <span style="white-space: nowrap;">'+this.localeMsg('duels')+': <b>'+this.log.count_duel+'</b>,</span> <span style="white-space: nowrap;">'+this.localeMsg('npcDuels')+': <b>'+this.log.count_npc+'</b>,</span> <span style="white-space: nowrap;">'+this.localeMsg('construction')+': <b>'+this.log.count_build+'</b>,</span> <span style="white-space: nowrap;">'+this.localeMsg('quests')+': <b>'+this.log.count_quest+'</b>,</span> <span style="white-space: nowrap;">'+this.localeMsg('itemUse')+': <b>'+this.log.count_item+'</b>,</span> <span style="white-space: nowrap;">'+this.localeMsg('other')+': <b>'+this.log.count_other+'</b></span></td></tr>'+(this.log.used?'<tr style="vertical-align: top;"><td style="white-space: nowrap;">'+this.localeMsg('used')+':</td><td style="color: #660000; font-weight: bold; text-align: right; padding-right: 8pt;">'+this.log.used+'</td><td>'+(this.log.count_reset?'<span style="white-space: nowrap;">'+this.localeMsg('timerReset')+': <b>'+this.log.count_reset+'</b> (#'+this.log.times_reset+'),</span> ' : '')+(this.log.count_action?'<span style="white-space: nowrap;">'+this.localeMsg('gameAction')+': <b>'+this.log.count_action+'</b>,</span> ' : '')+(this.log.count_bribe?'<span style="white-space: nowrap;">'+this.localeMsg('bribe')+': <b>'+this.log.count_bribe+'</b> (#'+this.log.times_bribe+')</span>' : '')+'</td></tr>' : '');
				if(this.eventItems.total) statsTable += '<tr><td style="white-space: nowrap;">'+this.localeMsg('inventory')+':</td><td style="text-align: right; padding-right: 8pt;"><a href="javascript:void(HiroFriends.eventItems.display());">'+this.eventItems.total+'</a></td><td>&nbsp;</td></tr>';
				statsTable += '</table>';
				$(statsTable).appendTo(maindiv);
			}
			var hiroPane = new west.gui.Scrollpane();
			hiroPane.appendContent(maindiv);
			var hiroWindow = wman.open("HiroFriends_"+this.eventName, null, "noreload").setMiniTitle(this.eventInfo.label).setTitle(this.eventInfo.label).appendToContentPane(hiroPane.getMainDiv());
		},
		eventManager: function(eventName) {
			if(undefined === Game.sesData[eventName] || undefined === Game.sesData[eventName].friendsbar) return false;
			this.eventName = eventName;
			this.eventInfo = Game.sesData[eventName].friendsbar;
			if(undefined === Game.sesData[this.eventName].meta.end) return false;
			this.eventEndStamp = (this.buildTimeStamp(Game.sesData[this.eventName].meta.end) - Game.serverTimeDifference) / 1e3;
			this.timeLeft = this.eventEndStamp - Game.getServerTime();
			if(this.timeLeft < 0) return false;
			this.cdnBase = (undefined === Game.cdnURL) ? "https://westzzs.innogamescdn.com" : Game.cdnURL;
			$.when(this.getLog()).done(function() {
				try { HiroFriends.wofId = west.wof.WofManager.wofs.octoberwof.getId(); } catch(e) { }
				HiroFriends.design();
			});
		},
		design: function() {
			if ('Octoberfest' == this.eventName) {
				this.divTombola = $("<div />", { id: "hiro_wof_container", style: "position: absolute; left: 2px; top: 4px; height: 16px;" });
				$("<div />", { id: "hiro_wof_1", class: "hasMousePopup", style: "display: inline-block; width: 13px; height: 16px; background: url('"+HiroFriends.cdnBase+"/images/tw2gui/iconset.png?14') no-repeat -64px -80px; opacity: 0.5;" }).appendTo(HiroFriends.divTombola);
				$("<div />", { id: "hiro_wof_2", class: "hasMousePopup", style: "display: inline-block; width: 13px; height: 16px;" }).appendTo(HiroFriends.divTombola);
				$("<div />", { id: "hiro_wof_3", class: "hasMousePopup", style: "display: inline-block; width: 13px; height: 16px;" }).appendTo(HiroFriends.divTombola);
				$("<div />", { id: "hiro_wof_4", class: "hasMousePopup", style: "display: inline-block; width: 13px; height: 16px;" }).appendTo(HiroFriends.divTombola);
			}
			else HiroFriends.divTombola = $("<span />", { id: "hiro_event_timeleft", style: "position: absolute; left: 5px; color: #d3d3d3; font-size: 11px; height: 25px; line-height: 25px; cursor: pointer", title: HiroFriends.localeMsg('timeLeft')+'<br />('+new Date(HiroFriends.buildTimeStamp(Game.sesData[HiroFriends.eventName].meta.end)).toDateTimeStringNice()+' '+HiroFriends.localeMsg('serverTime')+')' });
			var eventImage = HiroFriends.cdnBase + "/images/interface/friendsbar/events/" + HiroFriends.eventName + ".png";	// event based
			if(HiroFriends.eventName == 'Octoberfest') eventImage = HiroFriends.cdnBase + "/images/window/events/octoberfest/pretzels_icon.png";
			var divContainer = $("<div />", { id: "hiro_friends_container", style: "position: absolute; top: 32px; right: 50%; margin-right: 120px; z-index: 16; width: 180px; height: 36px; text-align: left; text-shadow: 1px 1px 1px #000; background: url('"+HiroFriends.cdnBase+"/images/interface/custom_unit_counter_sprite.png?2') no-repeat scroll 50% 0px transparent;" })
			var divCounter = $("<div />", { id: "hiro_friends", style: "background: url('"+HiroFriends.cdnBase+"/images/interface/custom_unit_counter_sprite.png?2') no-repeat scroll 0 -36px rgba(0, 0, 0, 0); height: 25px; left: 32px; line-height: 25px; padding: 0 5px; position: absolute; top: 3px; width: 105px; z-index: 1; text-shadow: 1px 1px 1px #000;" });
			var divRefresh = $("<div />", { style: "width: 24px; height: 24px; position: absolute; left: 8px; top: 3px; z-index: 3; padding: 4px 0px 0px 4px;" });
			var spanRefresh = $('<span />', { title: HiroFriends.localeMsg('refresh'), style: "display: inline-block; width: 20px; height: 20px; cursor: pointer; background: url('"+HiroFriends.cdnBase+"/images/tw2gui/window/window2_buttons.png?5') repeat scroll 0px -20px transparent;" });
			var spanSend = $("<span />", { style: "width: 26px; height: 26px; left: auto; position: absolute; right: 7px; top: 2px; z-index: 3;" });
			var imageSend = $("<img />", { src: eventImage, title: HiroFriends.eventInfo.label, style: "width: 26px; height: 26px; cursor: pointer" });
			if(HiroFriends.pendingInvitations) {
				HiroFriends.spanCounter.css("right", "20px");
				HiroFriends.spanInvitations = $("<span />", { id: "hiro_friends_invitations", title: HiroFriends.pendingInvitationsMsg(), style: "position: absolute; right: 0px; width: 19px; height: 25px; background-image: url('"+HiroFriends.cdnBase+"/images/interface/more.jpg'); background-repeat: no-repeat;" });
				HiroFriends.spanInvitations.hover(function() { $(this).css("background-position", "0px -25px"); }, function() { $(this).css("background-position", ""); });
				HiroFriends.spanInvitations.click(function() { $(this).hide(); HiroFriends.spanCounter.css("right", "5px"); FriendslistWindow.open('openrequests'); return false; });
				divCounter.append(HiroFriends.spanInvitations);
			}
			divContainer.append(divRefresh.append(spanRefresh), spanSend.append(imageSend), divCounter.append(HiroFriends.divTombola, HiroFriends.spanCounter)).appendTo("#user-interface");
			spanRefresh.hover(function() { $(this).css("background-position", ""); }, function() { $(this).css("background-position", "0px -20px"); });
			spanRefresh.click(function() {
				if ('Octoberfest' == HiroFriends.eventName) {
					HiroFriends.divTombola.slideUp(500, function() { if (HiroFriends.wofId) HiroFriends.getWofStatus(); }).slideDown(1500); 
				}
				HiroFriends.spanCounter.slideUp(500, function() { HiroFriends.fetch(); }).slideDown(1500);
				return false;
			});
			imageSend.click(function() { HiroFriends.open(); return false; });
			HiroFriends.eventCurrencyImage = "/images/icons/"+HiroFriends.eventName+".png";
			if(enableInv) {
				HiroFriends.eventItems.divInventory = $("<div />", { id: "hiro_friends_inventory_container", style: "position: absolute; top: 0px; right: 0px; z-index: 18; width: 20px; height: 18px;" }).hide().appendTo("#ui_bottombar .ui_bottombar_wrapper .button:first .dock-image");
				HiroFriends.eventItems.imgInventory = $('<img src="'+HiroFriends.eventCurrencyImage+'" alt="" title="">').click(function(e){ e.preventDefault(); HiroFriends.eventItems.display(); return false; }).appendTo(HiroFriends.eventItems.divInventory);
			}
			HiroFriends.divFriendsAvail = $("<div />", { id: "hiro_friends_bottombar_friends", style: "position: absolute; top: 0px; right: 0px; z-index: 18; width: 20px; height: 18px;" }).hide().appendTo("#ui_bottombar .ui_bottombar_wrapper .button:nth-child(3) .dock-image");
			HiroFriends.imgFriendsAvail = $('<img src="'+HiroFriends.eventCurrencyImage+'" alt="" title="'+scriptName+'">').click(function(e){ e.preventDefault(); HiroFriends.open(); return false; }).appendTo(HiroFriends.divFriendsAvail);
			if('Octoberfest' == HiroFriends.eventName) { HiroFriends.getWofId(); }
			else { HiroFriends.updateTimer(); }
			if(typeof(Storage) !== "undefined") {
				var previousVersion = (localStorage.getItem(HiroFriends.storageItem) === null) ? 0 : parseFloat(localStorage.getItem(HiroFriends.storageItem));
				localStorage.setItem(HiroFriends.storageItem, HiroFriends.version);
				// if(previousVersion && HiroFriends.version > previousVersion) var msg=new west.gui.Dialog("TW Friends", "Script upgraded to version "+HiroFriends.version, west.gui.Dialog.SYS_WARNING).addButton("OK").show();
			}
			$("<style>.hf_idx { width: 32px; text-align: right; padding-right: 8px; } .hf_player { width: 250px; } .hf_action { width: 200px; } .hf_log { width: 100px; text-align: right; padding-right: 8px; } .hf_delete { width: 40px; text-align: center; } div.tbody .hf_idx, div.tbody .hf_delete { background-image: url('"+HiroFriends.cdnBase+"/images/tw2gui/table/cell_shadow_y.png'); }</style>").appendTo("head");
			HiroFriends.fetch();
			HiroFriends.signalHandlers();
		},
		fetch: function() {
			if(this.interval !== false) clearInterval(this.interval);
			var event_times = {};
			var friends = {}, total = 0, avail = 0, recv = 0;
			var server_time = Game.getServerTime(), activation_time, friend_time;
			if(this.timeLeft < 0) {
				$("#hiro_friends_container").slideUp(5000);
				if(enableInv) HiroFriends.eventItems.divInventory.hide(5000);
				throw "Event is over";
			}
			if(enableInv) {
				if(HiroFriends.eventItems.check() && HiroFriends.eventItems.Available.length > 0)
					HiroFriends.eventItems.divInventory.show(5000);
				else HiroFriends.eventItems.divInventory.hide();
			}
			return $.post("/game.php?window=friendsbar&mode=search", { search_type: "friends" } , function(data) {
				$.each(data.eventActivations, function(key, val) {
					if(val.event_name == HiroFriends.eventName) event_times[val.friend_id] = val.activation_time;
				});
				$.each(data.players, function(key, val) {
					if(val.name !== Character.name) {
						activation_time = (event_times[val.player_id] !== undefined) ? event_times[val.player_id]: 0;
						if(undefined === HiroFriends.log.friendLog[val.player_id]) {
							recv = 0;
							HiroFriends.log.friendLog[val.player_id] = { name: val.name, total: 0, dates: [] };
						}
						else recv = HiroFriends.log.friendLog[val.player_id].total;
						friends[val.player_id] = { name: val.name, activation_time: activation_time, recv: recv };
						++ total;
						if(activation_time + HiroFriends.eventInfo.cooldown - server_time <= 0) ++ avail;
					}
				});
				HiroFriends.friends = friends;
				HiroFriends.avail = avail;
				HiroFriends.total = total;
				HiroFriends.updateCounter();
				if(HiroFriends.avail) {
					HiroFriends.imgFriendsAvail.attr('title', 'TW Friends: '+HiroFriends.avail+'/'+HiroFriends.total);
					HiroFriends.divFriendsAvail.show(5000);
				}
				else HiroFriends.divFriendsAvail.hide();
				HiroFriends.interval = setInterval(function() { HiroFriends.fetch(); }, refreshMs);
			});
		},
		displayWofStatus: function() {
			$.fn.hiro_wof_status = function(cat, wof_state) {
				var ar_title1 = HiroFriends.localeMsg('wofCat');
				var ar_title2 = HiroFriends.localeMsg('wofState');
				var ar_title3 = ar_title2[HiroFriends.eventName];
				switch(wof_state) {
					case 0	: $(this).css({ "background": "url('"+HiroFriends.cdnBase+"/images/tw2gui/iconset.png?14') no-repeat -98px 0", "opacity": "0.5" }); break;
					case 1	: $(this).css({ "background": "url('"+HiroFriends.cdnBase+"/images/tw2gui/iconset.png?14') no-repeat -82px -16px", "opacity": "1" }); break;
					case 2	: $(this).css({ "background": "url('"+HiroFriends.cdnBase+"/images/tw2gui/iconset.png?14') no-repeat -112px -16px", "opacity": "1" }); break;
					case 3	: $(this).css({ "background": "url('"+HiroFriends.cdnBase+"/images/tw2gui/iconset.png?14') no-repeat -98px -16px", "opacity": "1" }); break;
					default	: $(this).css({ "background": "url('"+HiroFriends.cdnBase+"/images/tw2gui/iconset.png?14') no-repeat -66px -80px", "opacity": "0.5" });
				}
				$(this).addMousePopup({
					'teaser' : '<b>' + ar_title1[cat] + '</b>',
					'content': '<div style="max-width: 250px;">' + ar_title3[wof_state] + '</div>'
				});
				return $(this);
			};
			$.fn.hiro_wof_insufficient = function(cat) { return $(this).hiro_wof_status(cat, 1); };
			$.fn.hiro_wof_working = function(cat) { return $(this).hiro_wof_status(cat, 0); };
			$.fn.hiro_wof_can_play = function(cat) { return $(this).hiro_wof_status(cat, 2); };
			$.fn.hiro_wof_can_bribe = function(cat) { return $(this).hiro_wof_status(cat, 3); };
			var data = HiroFriends.wofStatus;
			var cost_bribe = data.mode.cost.bribe * data.mode.conversion.ses;
			var cost_uncommon = data.prizes.enhancements[2] * data.mode.conversion.ses;
			var cost_rare = data.prizes.enhancements[1] * data.mode.conversion.ses;
			var cost_veryRare = data.prizes.enhancements[0] * data.mode.conversion.ses;
			var currencyAvailable = Character.ses_currency[HiroFriends.eventName.toLowerCase()];
			var state_common = undefined == data.mode ? undefined : data.mode.states[0];
			var state_uncommon = undefined == data.mode ? undefined : data.mode.states[25];
			var state_rare = undefined == data.mode ? undefined : data.mode.states[150];
			var state_veryRare = undefined == data.mode ? undefined : data.mode.states[800];
			if (undefined == state_common || !state_common.being_built) {
				if (currencyAvailable >= cost_bribe) $("#hiro_wof_1").hiro_wof_can_bribe(0);
				else $("#hiro_wof_1").hiro_wof_can_play(0);
			}
			else $("#hiro_wof_1").hiro_wof_working(0);
			if (undefined == state_uncommon || !state_uncommon.being_built) {
				if (currencyAvailable < cost_uncommon) $("#hiro_wof_2").hiro_wof_insufficient(1);
				else if (currencyAvailable < cost_uncommon + cost_bribe) $("#hiro_wof_2").hiro_wof_can_play(1);
				else $("#hiro_wof_2").hiro_wof_can_bribe(1);
			}
			else $("#hiro_wof_2").hiro_wof_working(1);
			if (undefined == state_rare || !state_rare.being_built) {
				if (currencyAvailable < cost_rare) $("#hiro_wof_3").hiro_wof_insufficient(2);
				else if (currencyAvailable < cost_rare + cost_bribe) $("#hiro_wof_3").hiro_wof_can_play(2);
				else $("#hiro_wof_3").hiro_wof_can_bribe(2);
			}
			else $("#hiro_wof_3").hiro_wof_working(2);
			if (undefined == state_veryRare || !state_veryRare.being_built) {
				if (currencyAvailable < cost_veryRare) $("#hiro_wof_4").hiro_wof_insufficient(3);
				else if (currencyAvailable < cost_veryRare + cost_bribe) $("#hiro_wof_4").hiro_wof_can_play(3);
				else $("#hiro_wof_4").hiro_wof_can_bribe(3);
			}
			else $("#hiro_wof_4").hiro_wof_working(3);
		},
		getWofId: function() {
			var wof_id = undefined;
			try { wof_id = west.wof.WofManager.wofs.octoberwof.getId(); } catch (e) { }
			if (wof_id) {
				HiroFriends.wofId = wof_id;
				HiroFriends.getWofStatus();
			}
			else setTimeout(function() { HiroFriends.getWofId(); }, 1e3);
		},
		getWofStatus: function() {
			clearTimeout(HiroFriends.wofTimeout);
			return $.ajax({ type: "POST", url: "/game.php?window=wheeloffortune&mode=init", data: { wofid: HiroFriends.wofId }, success: function(data) {
				HiroFriends.wofStatus = data;
				should_check_again = 86400*1e3;	/* 1 day */
				if (undefined !== data.mode && undefined !== data.mode.states) {
					now = Date.now()/1e3;
					$.each(data.mode.states, function(key, val) {
						if (val.being_built) should_check_again = Math.min((val.finish_date-now)*1e3, should_check_again);
					});
				}
				var will_check_again = Math.min(refreshWof, Math.max(1e3, should_check_again));
				HiroFriends.wallet = Character.ses_currency[HiroFriends.eventName.toLowerCase()];
				HiroFriends.displayWofStatus();
				HiroFriends.wofTimeout = setTimeout(function() { HiroFriends.getWofStatus(); }, will_check_again);
			} });
		},
		getLogPage: function(page, limit, deferred) {
			return $.ajax({ type: "POST", url: "/game.php?window=ses&mode=log", data: { ses_id: HiroFriends.eventName, page: page, limit: limit }, success: function(data) {
				var details;
				var hasNext = data.hasNext;
				var count = 0;
				var limit = data.limit;
				page = data.page + 1;
				$.each(data.entries, function(key, val) {
					count = parseInt(val.value);
					if(val.date < HiroFriends.log.firstLog) HiroFriends.log.firstLog = val.date;
					if(val.date <= HiroFriends.log.lastLog) {
						hasNext = false;
						return false;
					}
					HiroFriends.log.entries.push(val);
					if(val.date > HiroFriends.log.newLastLog) {
						HiroFriends.log.newLastLog = val.date;
					}
					switch(val.type) {
						case "friendDrop":
							if(null !== val.details) {
								details = JSON.parse(val.details);
								if(undefined !== HiroFriends.friends[details.player_id]) HiroFriends.friends[details.player_id].recv += count;
								if(undefined === HiroFriends.log.friendLog[details.player_id]) HiroFriends.log.friendLog[details.player_id] = { name: details.name, total: count, dates: [] };
								else HiroFriends.log.friendLog[details.player_id].total += count;
								HiroFriends.log.friendLog[details.player_id].dates.push(val.date);
							}
							HiroFriends.log.count_friends += count;
							HiroFriends.log.received += count;
							break;
						case "jobDrop":		HiroFriends.log.count_job += count; HiroFriends.log.received += count; break;
						case "buildDrop":	HiroFriends.log.count_build += count; HiroFriends.log.received += count; break;
						case "duelDrop":	HiroFriends.log.count_duel += count; HiroFriends.log.received += count; break;
						case "duelNPCDrop":	HiroFriends.log.count_npc += count; HiroFriends.log.received += count; break;
						case "battleDrop":	HiroFriends.log.count_fort += count; HiroFriends.log.received += count; break;
						case "adventureDrop":	HiroFriends.log.count_mpi += count; HiroFriends.log.received += count; break;
						case "questDrop":	HiroFriends.log.count_quest += count; HiroFriends.log.received += count; break;
						case "itemUse":		HiroFriends.log.count_item += count; HiroFriends.log.received += count; break;
						case "wofPay":
							HiroFriends.log.used += count;
							if(null !== val.details) {
								if(val.details == "timerreset") {
									HiroFriends.log.count_reset += count;
									++ HiroFriends.log.times_reset;
								}
								else if(val.details == "sneakyshot") {
									HiroFriends.log.count_bribe += count;
									++ HiroFriends.log.times_bribe;
								}
							}
							break;
						default:
							HiroFriends.log.count_other += count;
							HiroFriends.log.received += count;
					}
				});
				if (hasNext) return HiroFriends.getLogPage(page, limit, deferred);
				else {
					/* Done */
					HiroFriends.log.lastLog = HiroFriends.log.newLastLog;
					Chat.Request.Nop();
					deferred.resolve();
				}
			} });
		},
		getLog: function() {
			if(enableLog) {
				var deferred = new $.Deferred();
				var limit = 100;
				HiroFriends.log.newLastLog = HiroFriends.log.lastLog;
				this.getLogPage(1, limit, deferred);
				return deferred.promise();
			}
		},
		getPendingInvitations: function() {
			return $.post("/game.php?window=character&mode=get_open_requests", function(data) {
				var openReq = 0;
				$.each(data.open_friends, function(key, val) { if(val.inviter_id != Character.playerId) ++ openReq; });
				HiroFriends.pendingInvitations = openReq;
			});
		},
		localeMsg: function(msg) {
			if(undefined !== this.messages[this.locale][msg]) return this.messages[this.locale][msg];
			if(undefined !== this.messages['en_US'][msg]) return this.messages['en_US'][msg];
			return '';
		},
		open: function() {
			if(!WestUi.FriendsBar.hidden) WestUi.FriendsBar.toggle();
			$.when(this.getLog()).done(function() {
				HiroFriends.fetch().done(function() {
					HiroFriends.divFriendsAvail.hide();
					HiroFriends.getPendingInvitations().done(function() {
						HiroFriends.display('time');
					});
				});
			});
		},
		pendingInvitationsMsg: function() { return this.pendingInvitations == 1 ? this.localeMsg('pendingInvitation') : this.pendingInvitations+' '+this.localeMsg('pendingInvitations'); },
		removeFriend: function(charId) {
			new west.gui.Dialog(HiroFriends.localeMsg('removeFriend'), HiroFriends.localeMsg('removeConfirm')).setIcon(west.gui.Dialog.SYS_QUESTION).addButton("yes", function() {
				Ajax.remoteCall('character', 'cancel_friendship', { friend_id: charId }, function(json) {
					if(json["result"]) {
						new UserMessage(HiroFriends.localeMsg('removeSuccess'), UserMessage.TYPE_SUCCESS).show();
						$("div.hiroFriendRow_" + charId).remove();
						$("div.friendData_" + charId, FriendslistWindow.DOM).remove();
						delete(HiroFriends.friends[charId]);
						if(HiroFriends.avail) -- HiroFriends.avail;
						if(HiroFriends.total) -- HiroFriends.total;
						HiroFriends.updateCounter();
						Chat.Friendslist.removeFriend(charId);
					}
					else new UserMessage(HiroFriends.localeMsg('removeFailed'), UserMessage.TYPE_ERROR).show();
				})
			}).addButton("no").show();
		},
		sortByName: function(a, b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()); },
		sortByRecv: function(a, b) { return b.recv - a.recv; },
		sortByTime: function(a, b) { return a.activation_time - b.activation_time; },
		updateCounter: function() {
			this.spanCounter.html('<span title="'+this.localeMsg('availFriends')+'">'+this.avail+'</span> <span style="color: #d3d3d3; font-size: 11px;" title="'+this.localeMsg('totalFriends')+'">/ '+this.total+'</span>');
		},
		updateTimer: function() {
			this.timeLeft = this.eventEndStamp - Game.getServerTime();
			if(this.timeLeft <= 0) {
				this.divTombola.html(this.localeMsg('theEnd'));
				this.fetch();
				return;
			}
			this.divTombola.html(this.timeLeft.formatDurationBuffWay());
			var seconds = 0;
			if(this.timeLeft < 70) seconds = 1;
			else if(this.timeLeft < 3660) seconds = 10;
			else if(this.timeLeft < 86520) seconds = 60;
			else seconds = 120;
			setTimeout(function() { HiroFriends.updateTimer(); }, seconds * 1e3);
		},
		versionCheck: function(user_initiated = true) {
			try {
				$.getScript(URL_VERSION).done(function() {
					if(HiroFriends.latestVersion && HiroFriends.latestVersion > VERSION) {
						var upgradeDialog = new west.gui.Dialog(scriptName + ' ' + HiroFriends.localeMsg('version')+' ' + HiroFriends.latestVersion, HiroFriends.localeMsg('version_upgrade'), west.gui.Dialog.SYS_WARNING).addButton('ok', function() {
							try { upgradeDialog.hide(); location.href = URL_CODE; } catch(e) {}
						}).addButton('cancel').show();
					}
					else if (user_initiated) new west.gui.Dialog(scriptName + ' ' + HiroFriends.localeMsg('version')+' ' + HiroFriends.version.toFixed(2), HiroFriends.localeMsg('version_ok'), west.gui.Dialog.SYS_OK).addButton("ok").show();
				});
			}
			catch(e) {
				new west.gui.Dialog(scriptName, HiroFriends.localeMsg('version_checkFailed'), west.gui.Dialog.SYS_WARNING).addButton(HiroFriends.localeMsg('version_checkManual'), function() { window.open(URL_INSTALL, '_blank'); }).addButton("cancel").show();
			}
		},
		scriptInit: function(tries, maxTries) {
			var ev, eventName;
			if(tries >= maxTries) return false;
			if(Game && Game.loaded && Character.playerId) {
				this.locale = (undefined === Game.locale || undefined == this.messages[Game.locale]) ? "en_US" : Game.locale;
				this.api.setGui(this.localeMsg('description'));
				if (enableVersionCheck) this.versionCheck(false);
				for(eventName in Game.sesData) {
					if(!Game.sesData.hasOwnProperty(eventName)) continue;
					var ev = Game.sesData[eventName];
					if(!ev.friendsbar) continue;
					if('Hearts' == eventName || 'Easter' == eventName || 'Independence' == eventName || 'DayOfDead' == eventName || 'Octoberfest' == eventName) {
						this.getPendingInvitations().done(function() {
							HiroFriends.eventManager(eventName);
						});
						return false;
					}
				}
				return true;
			}
			++ tries;
			setTimeout(function() { HiroFriends.scriptInit(tries, maxTries); }, tries * 1e3);
		},
	}
	try { HiroFriends.scriptInit(0, 100); } catch(e) { }
});