Greasy Fork

Greasy Fork is available in English.

TW Gold Jobs Finder (More Languages)

Shows a list of all silver and gold jobs!

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name TW Gold Jobs Finder (More Languages)
// @namespace TomRobert
// @author Macabre2077 (updated by Tom Robert)
// @description Shows a list of all silver and gold jobs!
// @include https://*.the-west.*/game.php*
// @version 1.15
// @grant none
// ==/UserScript==
// translation: Did97(Russian), tw81(Italian), Jakovlev(Hungarian), realfan2002(Romanian), Vebuus/Bartosz86(Polish), Ilja Iljic(Czech), pepe100(Spanish), Tom Robert(German & French), Elly Siranno(Portuguese), ruud99(Dutch), Kigka(Greek)
(function (fn) {
  var script = document.createElement('script');
  script.setAttribute('type', 'application/javascript');
  script.textContent = '(' + fn + ')();';
  document.body.appendChild(script);
  document.body.removeChild(script);
})(function () {
  GJ = {
    version: '1.15',
    name: 'Gold Jobs Finder',
    author: 'Macabre2077 (updated by Tom Robert)',
    minGame: '2.05',
    maxGame: Game.version.toString(),
    website: '//greasyfork.org/scripts/7226',
    updateUrl: '//tomrobert.safe-ws.de/sUp.js',
    toLoad: 0,
    loaded: 0,
    xMax: 181,
    yMax: 79,
    blockMaxLength: 300,
    dataLoaded: false,
    silverJobBbColor: '#708090',
    goldJobBbColor: '#AB9930',
    preferences: {
      jobName: '',
      showSilver: true,
      showGold: true,
      sortByName: 0,
      sortByDistance: 1
    },
    hiddenImageOpacity: 0.35,
    shownImageOpacity: 1,
    bestJobTime: 0,
    langs: {
      en: {
        language: 'English',
        ApiGui: 'This script adds a button on the right side, where you can load all the silver and gold jobs.<br>So they can be easily found on the map.',
        save: 'Save',
        saveMessage: 'Successfully saved',
        chooseLang: 'Choose language',
        contact: 'Contact',
        jobName: 'Job name',
        distanceTime: 'Travel time',
        showJob: 'Show',
        title: 'Gold And Silver Jobs',
        loading: 'Loading...',
        exportButtonTitle: 'Export',
        generatedByBb: 'Generated by',
        goback: 'Go back',
        bbCode: 'BB code',
        enqueue: 'Enqueue',
        openWindowTitle: 'Open window',
        refreshTitle: 'Refresh',
        feedbackTitle: 'Send feedback',
        feedbackWindowTitle: 'Feedback',
        feedbackDescription: 'If you have encountered any bugs or have ideas how to improve this script, describe them.. in English, German or French please..',
      },
      ru: {
        language: 'Russian (русский)',
        ApiGui: 'Этот скрипт добавляет кнопку справа, с помощью которой Вы можете посмотреть все серебрянные и золотые работы.<br>Это поможет найти их на карте.',
        save: 'Экономить',
        saveMessage: 'Сохранить успешно',
        chooseLang: 'Сменить язык',
        contact: 'Контакты',
        jobName: 'Работа',
        distanceTime: 'Расстояние',
        showJob: 'Показать',
        title: 'Золотые и серебряные работы',
        loading: 'Загрузка...',
        exportButtonTitle: 'Экспорт',
        generatedByBb: 'Получено с помощью',
        goback: 'Назад',
        bbCode: 'BB-код',
        enqueue: 'Начать',
        openWindowTitle: 'Открыть окно',
        refreshTitle: 'Обновить данные',
        feedbackTitle: 'Обратная связь',
        feedbackWindowTitle: 'Обратная связь',
        feedbackDescription: 'Если Вы нашли баг, или у Вас есть идеи по улучшению скрипта, свяжитесь со мной',
      },
      it: {
        language: 'Italian (italiano)',
        ApiGui: 'This script adds a button on the right side, where you can load all the silver and gold jobs.<br>So they can be easily found on the map.',
        save: 'Save',
        saveMessage: 'Salva con successo',
        chooseLang: 'Cambia lingua',
        contact: 'Contatto',
        jobName: 'Nome lavoro',
        distanceTime: 'Tempo di viaggio',
        showJob: 'Mostra',
        title: 'Lavoro Oro e Argento',
        loading: 'Caricamento in corso ... Ci vorrà un po \'',
        exportButtonTitle: 'Esportazione',
        generatedByBb: 'Generato da',
        goback: 'Di ritorno',
        bbCode: 'BB code',
        enqueue: 'Inizia',
        openWindowTitle: 'Aperto',
        refreshTitle: 'Aggiornare dati',
        feedbackTitle: 'Invia feedback',
        feedbackWindowTitle: 'Feedback',
        feedbackDescription: 'Se avete riscontrato qualche bug o avete idee su come migliorare questo script, vi prego di descriverle .. in inglese, tedesco o francese per favore.',
      },
      hu: {
        language: 'Hungarian (magyar)',
        ApiGui: 'This script adds a button on the right side, where you can load all the silver and gold jobs.<br>So they can be easily found on the map.',
        save: 'Save',
        saveMessage: 'Successfully saved',
        chooseLang: 'Choose language',
        contact: 'Érintkezés',
        jobName: 'Munka neve',
        distanceTime: 'Menetidő',
        showJob: 'Mutatás',
        title: 'Arany és ezüst munkák',
        loading: 'Kis türelmet, töltés alatt...',
        exportButtonTitle: 'Export',
        generatedByBb: 'által létrehozva[/i]',
        goback: 'Vissza',
        bbCode: 'BB kód',
        enqueue: 'Kezdés',
        openWindowTitle: 'Megnyitás',
        refreshTitle: 'Frissítés',
        feedbackTitle: 'Visszajelzés küldése',
        feedbackWindowTitle: 'Visszajelzés',
        feedbackDescription: 'Ha találkoztál hibákkal (bug), vagy javaslatod lenne a szkript bővítéséhez írd le őket. Értek angolul, németül és franciául.',
      },
      ro: {
        language: 'Romanian (român)',
        ApiGui: 'This script adds a button on the right side, where you can load all the silver and gold jobs.<br>So they can be easily found on the map.',
        save: 'Save',
        saveMessage: 'Successfully saved',
        chooseLang: 'Choose language',
        contact: 'Contact',
        jobName: 'Denumirea muncii',
        distanceTime: 'Distanţa',
        showJob: 'Arată',
        title: 'Munci aurii şi argintii',
        loading: 'Se încarcă... Poate dura ceva timp!',
        exportButtonTitle: 'Export',
        generatedByBb: 'Generat cu',
        goback: 'Înapoi',
        bbCode: 'BB code',
        enqueue: 'Start',
        openWindowTitle: 'Deschide',
        refreshTitle: 'Reîmprospăta',
        feedbackTitle: 'Trimite feedback',
        feedbackWindowTitle: 'Feedback',
        feedbackDescription: 'If you have encountered any bugs or have ideas how to improve this script, describe them.. in English, German or French please..',
      },
      pl: {
        language: 'Polish (polski)',
        ApiGui: 'This script adds a button on the right side, where you can load all the silver and gold jobs.<br>So they can be easily found on the map.',
        save: 'Zapisz',
        saveMessage: 'Zapisz powodzeniem',
        chooseLang: 'Wybierz język',
        contact: 'Kontakt',
        jobName: 'Nazwa pracy',
        distanceTime: 'Dystans',
        showJob: 'Pokaż',
        title: 'Złote i srebrne prace',
        loading: 'Ładowanie... To zajmie moment',
        exportButtonTitle: 'Eksport',
        generatedByBb: 'Stworzone przez',
        goback: 'Cofnij',
        bbCode: 'BB code',
        enqueue: 'Startuj',
        openWindowTitle: 'Otwórz',
        refreshTitle: 'Odświeżanie danych',
        feedbackTitle: 'Wystawienie opinii',
        feedbackWindowTitle: 'Opinie',
        feedbackDescription: 'Jeżeli znalazłeś błąd, lub masz pomysł jak można udoskonalić skrypt - napisz do mnie. Proszę o kontakt w języku angielskim, niemieckim bądź francuskim.',
      },
      cs: {
        language: 'Czech (čeština)',
        ApiGui: 'This script adds a button on the right side, where you can load all the silver and gold jobs.<br>So they can be easily found on the map.',
        save: 'Save',
        saveMessage: 'Successfully saved',
        chooseLang: 'Choose language',
        contact: 'Kontakt',
        jobName: 'Práce',
        distanceTime: 'Vzdálenost',
        showJob: 'Ukaž',
        title: 'Zlaté a stříbrné práce',
        loading: 'Nahrávám...',
        exportButtonTitle: 'Export',
        generatedByBb: 'Generated by',
        goback: 'Zpět',
        bbCode: 'BB code',
        enqueue: 'Zadat',
        openWindowTitle: 'Otevřít okno',
        refreshTitle: 'Obnovit',
        feedbackTitle: 'Pošli zpětnou vazbu',
        feedbackWindowTitle: 'Feedback',
        feedbackDescription: 'Pokud jste nalezli bug nebo máte nápad na zlepšení skriptu, napište je..v angličtině, němčině nebo francouzštině prosím..',
      },
      es: {
        language: 'Spanish (español)',
        ApiGui: 'This script adds a button on the right side, where you can load all the silver and gold jobs.<br>So they can be easily found on the map.',
        save: 'Guardar',
        saveMessage: 'Guardar correctamente',
        chooseLang: 'Elige idioma',
        contact: 'Contacto',
        jobName: 'Nombre Trabajo',
        distanceTime: 'Tiempo viaje',
        showJob: 'Mostrar',
        title: 'Trabajos con Bonus Oro y Plata',
        loading: 'Cargando...',
        exportButtonTitle: 'Exportación',
        generatedByBb: 'Generado por',
        goback: 'De regreso',
        bbCode: 'BB code',
        enqueue: 'Poner en cola',
        openWindowTitle: 'Abrir ventana',
        refreshTitle: 'Refrescar',
        feedbackTitle: 'Enviar comentarios',
        feedbackWindowTitle: 'Comentarios',
        feedbackDescription: 'Si ha encontrado algún error o tiene ideas de cómo mejorar este script, descríbalos.. por favor en inglés, alemán o francés..',
      },
      de: {
        language: 'German (Deutsch)',
        ApiGui: 'Das Script fügt am rechten Rand einen Button hinzu, wo man alle Gold- und Silber-Arbeiten laden kann.<br>So findet man sie ganz einfach auf der Karte.',
        save: 'Speichern',
        saveMessage: 'Speichern erfolgreich',
        chooseLang: 'Sprache ändern',
        contact: 'Kontakt',
        jobName: 'Arbeit',
        distanceTime: 'Distanz',
        showJob: 'Zeigen',
        title: 'Gold und Silber Arbeiten',
        loading: 'Laden...',
        exportButtonTitle: 'Exportieren',
        generatedByBb: 'Gefunden mit',
        goback: 'Zurück',
        bbCode: 'BB Code',
        enqueue: 'Einstellen',
        openWindowTitle: 'Fenster öffnen',
        refreshTitle: 'Aktualisieren',
        feedbackTitle: 'Feedback',
        feedbackWindowTitle: 'Feedback',
        feedbackDescription: 'Falls du auf Fehler gestossen bist oder Ideen hast, wie man das Script verbessern könnte, kannst du mich kontaktieren.',
      },
      fr: {
        language: 'French (français)',
        ApiGui: 'Avec ce script, tu peux voir une liste de tous les travaux argentés et dorés.<br>Comme ça il est très facile de trouve les travaux de bonus sur le Mini-map.',
        save: 'Sauver',
        saveMessage: 'Enregistré avec succès',
        chooseLang: 'Choisissez la langue',
        contact: 'Contact',
        jobName: 'Travail',
        distanceTime: 'Distance',
        showJob: 'Montre',
        title: 'Travaux argentés et dorés',
        loading: 'Chargement en cours...',
        exportButtonTitle: 'Exportation',
        generatedByBb: 'Trouvé avec',
        goback: 'De retour',
        bbCode: 'BB code',
        enqueue: 'Commencer',
        openWindowTitle: 'Ouvrir la fenêtre',
        refreshTitle: 'Rafraîchir',
        feedbackTitle: 'Contact',
        feedbackWindowTitle: 'Contact',
        feedbackDescription: 'Si tu as trouvé un bug ou si tu as des idées pour améliorer le script, contactez-moi.',
      },
      pt: {
        language: 'Portuguese (português)',
        ApiGui: 'Este Script faz uma busca automãtica e em tempo real de todos os Trabalhos com Bônus Ouro ou Prata em todo o Mundo.',
        save: 'Salvar',
        saveMessage: 'Economize com sucesso',
        chooseLang: 'Escolhe idioma',
        contact: 'Contato com Autor',
        jobName: 'Nome do Job',
        distanceTime: 'Distância',
        showJob: 'Show',
        title: 'Gold And Silver Jobs',
        loading: 'Procurando Jobs Ouro/Prata',
        exportButtonTitle: 'Exportar',
        generatedByBb: 'Generated by',
        goback: 'Go back',
        bbCode: 'BB code',
        enqueue: 'Iniciar Job',
        openWindowTitle: 'Procurar Jobs',
        refreshTitle: 'Atualizar Lista',
        feedbackTitle: 'Suporte',
        feedbackWindowTitle: 'Feedback',
        feedbackDescription: 'Aqui vc encontra os meios de comunicação com o supporte do Script, pode reportar um erro, fazer uma crítica ou dar sugestões',
      },
      nl: {
        language: 'Dutch (Nederlands)',
        ApiGui: 'Dit script voegt een knop aan de rechterkant toe in het scherm. Deze button laadt alle zilveren en gouden werkzaamheden.<br>Zodat ze gemakkelijk gevonden kunnen worden op de kaart.',
        save: 'Besparen',
        saveMessage: 'Sparen succes',
        chooseLang: 'Kies een taal',
        contact: 'Contact',
        jobName: 'Werkzaamheid',
        distanceTime: 'Afstand',
        showJob: 'Toon',
        title: 'Gouden en zilveren arbeiden',
        loading: 'Laden...',
        exportButtonTitle: 'Exporteren',
        generatedByBb: 'Gemaakt door',
        goback: 'Terug',
        bbCode: 'BB code',
        enqueue: 'Starten',
        openWindowTitle: 'Scherm openen',
        refreshTitle: 'Herladen',
        feedbackTitle: 'Feedback',
        feedbackWindowTitle: 'Feedback',
        feedbackDescription: 'Als je bugs tegenkomt of ideeën hebt om dit script te verbeteren, omschrijf ze in Engels, Duits of Frans aub.',
      },
      el: {
        language: 'Greek (ελληνικά)',
        ApiGui: 'This script adds a button on the right side, where you can load all the silver and gold jobs.<br>So they can be easily found on the map.',
        save: 'Save',
        saveMessage: 'Successfully saved',
        chooseLang: 'Choose language',
        contact: 'Contact',
        jobName: 'Όνομα Δουλειάς',
        distanceTime: 'Απόσταση',
        showJob: 'Εμφάνιση',
        title: 'Χρυσές και Ασημένιες δουλειές',
        loading: 'Φόρτωση...',
        exportButtonTitle: 'Share',
        generatedByBb: 'Generated by',
        goback: 'Go back',
        bbCode: 'BB κώδικας',
        enqueue: 'Περπατήστε',
        openWindowTitle: 'Άνοιγμα παραθύρου',
        refreshTitle: 'Refresh',
        feedbackTitle: 'Στείλτε  feedback',
        feedbackWindowTitle: 'Feedback',
        feedbackDescription: 'Αν έχετε αντιμετωπίσει τυχόν σφάλματα ή έχετε ιδέες για τη βελτίωση αυτού του script, ενημερώστε με..'
      },
    },
    updateLang: function () {
      var lg = GJ.langs;
      GJ.lang = lg[localStorage.getItem('scriptsLang')] ? localStorage.getItem('scriptsLang') : lg[Game.locale.substr(0, 2)] ? Game.locale.substr(0, 2) : 'en';
      GJlang = lg[GJ.lang];
    },
  };
  GJ.updateLang();
  GJ.parseWholeMap = function (tiles, onLoad) {
    this.loaded = 0;
    var x,
    y;
    var arr = [];
    var currentBlock = 0;
    var currentBlockLength = 0;
    for (x in tiles) {
      for (y in tiles[x]) {
        if (isNaN(x) || isNaN(y)) {
          continue;
        }
        if (currentBlockLength === 0) {
          arr[currentBlock] = [
          ];
        }
        arr[currentBlock].push([parseInt(x),
            parseInt(y)]);
        if (++currentBlockLength == this.blockMaxLength) {
          currentBlock++;
          currentBlockLength = 0;
        }
      }
    }
    var i,
    to = arr.length;
    this.toLoad = to;
    for (i = 0; i < to; i++) {
      GameMap.Data.Loader.load(arr[i], function () {
        GJ.loaded++;
        if (GJ.loaded == GJ.toLoad) {
          onLoad();
        }
      });
    }
  };
  GJ.getJobIcon = function (jobId, x, y, shortname, gold) {
    var t = gold ? 'gold' : 'silver';
    return '<div class="job" style="left: 0; top: 0; position: relative;"><div  onclick="javascript:GameMap.JobHandler.openJob(' + jobId + ',{x:' + x + ',y:' + y + '})" class="featured ' + t + '"></div>' + this.getGotoIcon(x, y) + '<img src="images/jobs/' + shortname + '.png" class="job_icon"></div>';
  };
  GJ.getGotoIcon = function (x, y) {
    return '<div class="centermap" onclick="javascript:GameMap.center(' + x + ',' + y + ');"style="position: absolute;background-image: url(\'images/map/icons/instantwork.png\');width: 20px;height: 20px;top: 0;right: 3px;cursor: pointer;"></div>';
  };
  GJ.getBestJobTime = function () {
    var list = JobList.getDurations();
    var maxTime = 0;
    for (var name in list) {
      if (list[name].requirement <= Character.level && list[name].duration > maxTime) {
        maxTime = list[name].duration;
      }
    }
    GJ.bestJobTime = maxTime;
  };
  GJ.getEnqueueButton = function (jobId, x, y) {
    var job = JobList.getJobById(jobId);
    var canDo = job.canDo();
    if (GJ.bestJobTime === 0) {
      GJ.getBestJobTime();
    }
    var duration = GJ.bestJobTime;
    var b = this.gui.makeButton(GJlang.enqueue, function () {
      TaskQueue.add(new TaskJob(jobId, x, y, duration));
    });
    b.setWidth(100);
    if (!canDo)
      b.disable();
    return b.getMainDiv();
  };
  GJ.addColumnsCss = function () {
    $('.goldenJobs .jobIcon').css('width', '60px');
    $('.goldenJobs .jobName').css('width', '140px');
    $('.goldenJobs .startJob').css('width', '100px');
    $('.goldenJobs .distanceTime').css('width', '60px');
    $('.goldenJobs .row').css('height', '56px');
    $('.goldenJobs .row').css('background', 'none');
    $('.goldenJobs .row_head .jobName').css('width', '135px');
    $('.goldenJobs .row_head .distanceTime').css('width', '95px');
    $('.goldenJobs .row_head .startJob').css('width', '0px');
    $('.goldenJobs .tfoot .jobIcon').css('width', '100%');
    $('.goldenJobs .tfoot').css('height', '35px');
    $('.goldenJobs').find('.tw2gui_scrollpane').css('height', '280px');
  };
  GJ.calculateDistance = function (jobX, jobY) {
    var to = {
      x: jobX,
      y: jobY
    };
    return GameMap.calcWayTime(Character.position, to);
  };
  GJ.addEventListener = function (event, callback) {
    if (EventHandler.hasOwnProperty('add')) {
      EventHandler.add(event, callback);
    } else {
      EventHandler.listen(event, callback);
    }
  };
  GJ.openWindow = function () {
    var content = $('<div class=\'goldwindow\'/>');
    var table = this.makeJobsTable(this.preferences.jobName, this.preferences.showSilver, this.preferences.showGold, this.preferences.sortByName, this.preferences.sortByDistance);
    var win = wman.open('goldenJobs').setResizeable(true).setMinSize(450, 475).setSize(450, 475).setMiniTitle(GJlang.title);
    content.append(table.getMainDiv());
    win.appendToContentPane(content);
    this.addColumnsCss();
    this.addFilterEvent();
    this.addHeaderEvents();
    this.addEventListener('position_change', GJ.refreshWindow);
  };
  GJ.buildFooter = function (chosenJobName) {
    var footer = $('<div class="goldjobs_table_foot" style="margin-top: 3px"><span id="gj_job_search" style="position: relative; top: 0px;"></span><span id="gj_share" style="position: absolute;top: 3px;right: 7px;"></span></div>');
    var exportButton = this.gui.makeButton(GJlang.exportButtonTitle, function () {
      var jobName = $('#gj_job_search_textfield').val();
      var jobs = GJ.jobsDataToString(jobName);
      GJ.showExportWindow(jobs, false);
    }).setWidth(100);
    var textfield = this.gui.makeTextfield('gj_job_search_textfield').setSize(18).setWidth(137);
    var clearImage = $('<img/>', {
      src: 'images/chat/servicegrade_traitor.png',
      click: function () {
        $('#gj_job_search_textfield').val('').trigger('change');
      },
      css: {
        filter: 'grayscale(100%)',
        '-webkit-filter': 'grayscale(100%)',
        '-moz-filter': 'grayscale(100%)',
        '-o-filter': 'grayscale(100%)',
        position: 'absolute',
        top: '-1px',
        left: '130px'
      }
    });
    $('#gj_job_search', footer).append(textfield.getMainDiv());
    $('#gj_share', footer).append(exportButton.getMainDiv());
    $('#gj_job_search span.tw2gui_textfield span', footer).append('<span class=\'placeholder\' style=\'font-weight: lighter;color: #333;position: absolute;left: 12px; top: 1px;\'>' + GJlang.jobName + '</span>');
    var placeholder = $('#gj_job_search .placeholder', footer);
    placeholder.after(clearImage);
    placeholder.click(function () {
      $('#gj_job_search_textfield', footer).trigger('focus');
    });
    $('#gj_job_search_textfield', footer).on('focus', function () {
      placeholder.hide();
    });
    $('#gj_job_search_textfield', footer).on('focusout', function () {
      if ($('#gj_job_search_textfield').val() == '') {
        placeholder.show();
      }
    });
    if (chosenJobName) {
      $('#gj_job_search_textfield', footer).val(chosenJobName).trigger('focus');
    }
    return footer;
  };
  GJ.getJobIconHeaderCell = function (showGold, showSilver) {
    var hiddenImageOpacity = this.hiddenImageOpacity;
    var shownImageOpacity = this.shownImageOpacity;
    return '<img src="images/jobs/featured/goldjob.png" style="width: 15px; opacity: ' + (showGold ? shownImageOpacity : hiddenImageOpacity) + '; " onclick="javascript:GJ.onJobIconFilterClick(&quot;gold&quot;, $(this))">+\t\t\t\t<img src="images/jobs/featured/silverjob.png" style="width: 15px; opacity: ' + (showSilver ? shownImageOpacity : hiddenImageOpacity) + '; " onclick="javascript:GJ.onJobIconFilterClick(&quot;silver&quot;, $(this))">';
  };
  GJ.onJobIconFilterClick = function (type, element) {
    var hiddenImageOpacity = this.hiddenImageOpacity;
    var shownImageOpacity = this.shownImageOpacity;
    var disabled = ($(element).css('opacity') != shownImageOpacity);
    if (type == 'gold') {
      this.preferences.showGold = disabled;
    } else {
      this.preferences.showSilver = disabled;
    }
    $(element).css('opacity', (disabled ? hiddenImageOpacity : shownImageOpacity));
    this.refreshWindow();
  };
  GJ.getAllTiles = function (callback) {
    Ajax.get('map', 'get_minimap', {}, function (r) {
      if (r.error) {
        console.log(r.error);
        return;
      }
      var result = [];
      var jobGroups = r.job_groups,
      i,
      j;
      for (i in jobGroups) {
        for (j in jobGroups[i]) {
          var coords = jobGroups[i][j];
          var xTile = Math.floor(coords[0] / GameMap.tileSize);
          var yTile = Math.floor(coords[1] / GameMap.tileSize);
          if (!result.hasOwnProperty(xTile)) {
            result[xTile] = {};
          }
          result[xTile][yTile] = 1;
        }
      }
      GJ.tilesWithJobs = result;
      callback();
    });
  };
  GJ.getFilteredData = function (chosenJobName, showSilver, showGold, sortByName, sortByDistance) {
    chosenJobName = chosenJobName.toLowerCase();
    var jobs = GameMap.JobHandler.Featured;
    var k,
    jobId,
    job,
    j;
    var result = [];
    for (k in jobs) {
      var jobPlace = jobs[k];
      for (jobId in jobPlace) {
        job = JobList.getJobById(jobId);
        j = jobPlace[jobId];
        if ((j.silver && !showSilver) || (j.gold && !showGold)) {
          continue;
        }
        if (chosenJobName !== '' && job.name.toLowerCase().indexOf(chosenJobName) < 0) {
          continue;
        }
        result.push({
          jobId: jobId,
          x: j.x,
          y: j.y,
          name: job.name,
          shortname: job.shortname,
          gold: j.gold,
          distance: this.calculateDistance(j.x, j.y)
        });
      }
    }
    var nameSortFunctionReversed = function (o1, o2) {
      var t1 = o1.name.toUpperCase();
      var t2 = o2.name.toUpperCase();
      return (t1 > t2) ?  - 1 : (t1 < t2) ? 1 : 0;
    };
    var distanceSortFunctionReversed = function (o1, o2) {
      var t1 = parseInt(o1.distance);
      var t2 = parseInt(o2.distance);
      return (t1 > t2) ?  - 1 : (t1 < t2) ? 1 : 0;
    };
    var nameSortFunction = function (o1, o2) {
      var t1 = o1.name.toUpperCase();
      var t2 = o2.name.toUpperCase();
      return (t1 < t2) ?  - 1 : (t1 > t2) ? 1 : 0;
    };
    var distanceSortFunction = function (o1, o2) {
      var t1 = o1.distance;
      var t2 = o2.distance;
      return (t1 < t2) ?  - 1 : (t1 > t2) ? 1 : 0;
    };
    if (sortByName !== 0) {
      if (sortByName == 1) {
        result.sort(nameSortFunction);
      } else {
        result.sort(nameSortFunctionReversed);
      }
    } else if (sortByDistance !== 0) {
      if (sortByDistance == 1) {
        result.sort(distanceSortFunction);
      } else {
        result.sort(distanceSortFunctionReversed);
      }
    }
    return result;
  };
  GJ.makeJobsTable = function (chosenJobName, showSilver, showGold, sortByName, sortByDistance) {
    chosenJobName = chosenJobName || '';
    var arrow_desc = '&nbsp;<img src="images/window/jobs/sortarrow_desc.png"/>',
    arrow_asc = '&nbsp;<img src="images/window/jobs/sortarrow_asc.png"/>',
    footer = this.buildFooter(chosenJobName),
    table = this.gui.makeTable(),
    data = this.getFilteredData(chosenJobName, showSilver, showGold, sortByName, sortByDistance);
    table.addColumn('jobIcon', 'jobIcon').addColumn('jobName', 'jobName').addColumn('distanceTime', 'distanceTime').addColumn('startJob', 'startJob').appendToCell('head', 'jobIcon', this.getJobIconHeaderCell(showGold, showSilver)).appendToCell('head', 'jobName', GJlang.jobName + (sortByName == 1 ? arrow_asc : sortByName ==  - 1 ? arrow_desc : '')).appendToCell('head', 'distanceTime', GJlang.distanceTime + (sortByDistance == 1 ? arrow_asc : sortByDistance ==  - 1 ? arrow_desc : '')).appendToCell('head', 'startJob', '');
    $.each(data, function (k, j) {
      table.appendRow().appendToCell( - 1, 'jobIcon', GJ.getJobIcon(j.jobId, j.x, j.y, j.shortname, j.gold)).appendToCell( - 1, 'jobName', j.name).appendToCell( - 1, 'distanceTime', j.distance.formatDuration()).appendToCell( - 1, 'startJob', GJ.getEnqueueButton(j.jobId, j.x, j.y));
    });
    table.appendToFooter('jobIcon', footer);
    return table;
  };
  GJ.refreshWindow = function () {
    GJ.preferences.jobName = $('#gj_job_search_textfield').val();
    var newTable = GJ.makeJobsTable(GJ.preferences.jobName, GJ.preferences.showSilver, GJ.preferences.showGold, GJ.preferences.sortByName, GJ.preferences.sortByDistance);
    $('.goldenJobs .fancytable').remove();
    $('.goldwindow').prepend(newTable.getMainDiv());
    GJ.addColumnsCss();
    GJ.addFilterEvent();
    GJ.addHeaderEvents();
    $('#gj_job_search_textfield').trigger('focus');
  };
  GJ.addFilterEvent = function () {
    var f = function () {
      if (GJ.filterTimeout !== undefined) {
        clearTimeout(GJ.filterTimeout);
      }
      GJ.filterTimeout = setTimeout(function () {
        GJ.refreshWindow();
      }, 500);
    };
    $('#gj_job_search_textfield').on('change', f).on('keypress', f);
  };
  GJ.addHeaderEvents = function () {
    $('.goldenJobs .row_head .jobName').click(function () {
      GJ.preferences.sortByName = GJ.preferences.sortByName == 1 ?  - 1 : 1;
      GJ.preferences.sortByDistance = 0;
      GJ.refreshWindow();
    });
    $('.goldenJobs .row_head .distanceTime').click(function () {
      GJ.preferences.sortByName = 0;
      GJ.preferences.sortByDistance = GJ.preferences.sortByDistance == 1 ?  - 1 : 1;
      GJ.refreshWindow();
    });
  };
  GJ.getMessageDialog = function (text, type, title) {
    title = title || '';
    if (type == 'warning') {
      type = west.gui.Dialog.SYS_WARNING;
    }
    if (type == 'question') {
      type = west.gui.Dialog.SYS_QUESTION;
    }
    return new west.gui.Dialog(text, title, type);
  };
  GJ.getSelectBox = function () {
    var onLoad = function () {
      GJ.openWindow();
      GJ.dataLoaded = true;
    };
    var listener = function (k) {
      switch (k) {
      case 'feedback':
        GJ.openFeedbackWindow();
        break;
      case 'open':
        if (!GJ.hasOwnProperty('tilesWithJobs')) {
          new UserMessage(GJlang.loading, UserMessage.TYPE_HINT).show();
          GJ.getAllTiles(function () {
            GJ.parseWholeMap(GJ.tilesWithJobs, onLoad);
          });
        } else {
          onLoad();
        }
        break;
      case 'refresh':
        new UserMessage(GJlang.loading, UserMessage.TYPE_HINT).show();
        if (!GJ.hasOwnProperty('tilesWithJobs')) {
          GJ.getAllTiles(function () {
            GJ.parseWholeMap(GJ.tilesWithJobs, onLoad);
          });
        } else {
          GJ.parseWholeMap(GJ.tilesWithJobs, onLoad);
        }
        break;
      }
    };
    this.selectBox = new west.gui.Selectbox().setWidth(150).addListener(listener).addItem('open', GJlang.openWindowTitle).addItem('refresh', GJlang.refreshTitle).addItem('feedback', GJlang.feedbackTitle);
  };
  GJ.toggleSelectbox = function () {
    var pos = $('div#GoldJobsmenu').offset();
    pos = {
      clientX: pos.left,
      clientY: pos.top
    };
    GJ.selectBox.show(pos);
  };
  GJ.init = function () {
    var menuimage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAZCAIAAAD8NuoTAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwQAADsEBuJFr7QAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAABzlJREFUSEutll1sFFUUx++jWROzMRuNIJMBC2wExjIhLcJYAT+2ZIo4gEF2BeRjKS7imorIhIBKYRUSN+r60fiVTaOJphvf3Fe7r+0j6cu+NH1qeOhDQ/pAgsbfuWfYTHh28+/0zMee+7v/c+6dNZeP95dffurD0si+4Nl9/c7hHfk3drvHXtxydmTj0b0bxg5tP7mvPxpy39y55vWhVUd3Ocd2rjlX2HJ4cN2g+9j6VY/0rXl08Nmntq19fN/W1f9jKvPJoa2/XT2RdzJWuZQyvpNDGudzctfJZVA64DrBd5+evrp/vaYKvKyVm1I29FykceDKXc/NonTAdQJNZU7v2ejnEoIgn6jwIEBClssUfKcel6sl/mcC1YMnCz5y/vrsIKlCNyEoBokqDwIkZG62EnqdqUazxv9sUfXgyUqIPFKZ00d35TKmJyeHxIDED0tcLUcz7Yk7c+3p9kTBz0Mm5qlbTvLYxA9jpHKzpifPRWJA4oclbjbipYXZe8sLiwuzlTCATMxTt7zkMVKZa9eOCYEA6UgMI3Aa405rIr4z14IJzc+0MCw9DVXGmA+KPqmEQIB0JIYROI1xpzs7dW+5CxNaWepiWHoaqqxNZS4eH4DAeqNWWaCcKQT5yXo8Nz2JAPrnzjRwE/Wqn3eYgz5jlcnb0+tHBkgFgfVGrbJArqkUg9udqeXF2wigf+8tAjfbaYaBxxz0GatsYE9JZd7fv06s0nkbCajReLVkq9aaRzOidqseFYKcnYC2VJTPlPxcRGMRBM7v1yJSiVU6byMBNWo3a7Zq3RW0JFroduJK0bUT0JaKg2wtdGMai6DokcpcP78zcIyfM7aROZpWvXp3npLZws205qYnpNPzsvqk3wUiVxaBlSjyM7+O7SZV0TOha2wjczTdTvP+CiWzhVvqLi/OSqcHsvqk3wXCbYjAShSHWVKZ6+++LrP3M0yaqderBYDuJp1EGUuFwAeKPktMsg7BgUMSyLdEN08NkEpmH2aZNFPvNCsA3U86iTLWKsUQKPosMck6BAcOSSDfEpHKfH4hsv0kYtTp1jg0kNHpEJWiYHqyTkHxS/cF6HtSdwNx2nwzuotUtp9EjLrYbUMDGZ0OUS0uLt7uUFD80n0B+p7U3aI4LanM1TM7ANKuwhtMAqIcyXKjau1JKFuUEkpBcYwqoZGZJHC/XY5IBZB2Fd5gEhCNWJYbVVu4DWWXUkIpKJ5RJTQykwSOVObWqe2Y5DumHPkz7frEeJmNSpc9oHTVvF2JWBiXC0BI1UQACR+B9Fbe/Hn9AKkwKfRMIw6XFjqz7QYblS57QOmqFbsSsXCqUQFCqiYCSPgIpLcCSWV+eW+Yfkfj5UI1kkrp4gdUIHwxDLfAmm7VmYB1SCRkFov2L+XNT1eHSUW/o3aj0oylUrr4ARWIUAzDLbAWux0mYB0SCZnFov1rgaQyF4c3UAIg9JgGkvH8TLUUaLehifGSAvUEECK4+c5LpKIEQOgxDSTjhdlmrajdhmbbNQXqCSBEQCozWnABkr5J97LtYu0hTnWjp8nYWqtRXoCsT4LlJ8GZ7Q6pAJK+Sfey7WLtIU51o6fJ2FqbcSBA1ifBCpOAVObLKwcY2w5vS2MbBcm2FMgV6ssGwe4lntnedzIZ3jZ+Rh4rcNcRuBvnQ1Ixth3elsY2CpJtqShXqC8bBLuXeGZ738tmeduEWXmswl1P4EjF314FSmRNonZiVc7WyPrBUtAliW2lqGCMvAdl/RqTt/rx8gFSKVAiaxK1E6tcWyPrB0tBlyS21eIKqSCT9WtMYEUqUy30yUuNdw5HruasB9YwQVQyOXX0R8Td+WlKGbGvws1qtWTosxP9pJKXGu8cjkZQxANrmCAqmZx6+iPi/soipYzZV+FmtVoyRCpz88wuzcvsOYIFnyBmhImB1Qw0Xo4EixfAfJvfXlpKFV8cHXmOVJqX2XMECz5BzAoTA6sZqN2IBYsXwMoCv720lCq+SCrz7dgwtdCKaFF6lOlRucWvRXZ8u4e15mZavAP0OsQE42+9QCpqoRXRovQo06Nyi1+L7Ph2D+suL3V5B+h1iAlIZS6dDBVImdQYDXwbaKwBu78UcaZVl13X0Yf1ux8f7COVAimTGqNBaAONNWD3lyIudTuy63r6sH6XVGbHlqe1t3QMxmaMnnkE6Q91i8vy8k7OU59o2xOk0t7SMRibMXrmEaQ/1G2qIS/v5Dz1IZX5+cKwnjxE8NBHq5l+hli5mQwr8/D2vl6qhwge+mg1088QKzeTYWWSyvzx/vOTF49wT8dAPcM0xhkGVgN6dhJwXW9x/OLcK+U9fb1UOgbqGaYxzpCkaNWzk4DreoujpjKfHhr87u2hSyPr39i56r3XBs+ODAwPuMGm1f4zj+3Z/OSBYP3x/qcvDPVVh9de2bvu1pH+r0Y3ff/Olvop7/uxV28c3vDRoc3ty7v//nz/15WB/y1VZeA/g0nPNEKwlVwAAAAASUVORK5CYII=';
    this.getSelectBox();
    var div = $('<div class="ui_menucontainer" />');
    var link = $('<div id="GoldJobsmenu" class="menulink" onclick="GJ.toggleSelectbox();" title="' + GJ.name + '" />').css('background-image', 'url(' + menuimage + ')').css('background-position', '0px 0px').on('mouseenter', function () {
      $(this).css('background-position', '-25px 0px');
    }).on('mouseleave', function () {
      $(this).css('background-position', '0px 0px');
    });
    $('#ui_menubar').append((div).append(link).append('<div class="menucontainer_bottom" />'));
  };
  GJ.jobsDataToString = function (chosenJobName) {
    chosenJobName = chosenJobName.toLowerCase();
    var str = '';
    var jobs = GameMap.JobHandler.Featured;
    var k,
    jobId,
    job,
    t,
    j;
    for (k in jobs) {
      var jobPlace = jobs[k];
      for (jobId in jobPlace) {
        job = JobList.getJobById(jobId);
        if (chosenJobName !== '' && job.name.toLowerCase().indexOf(chosenJobName) < 0)
          continue;
        j = jobPlace[jobId];
        t = j.gold ? 'gold' : 'silver';
        str += job.name + '; ' + t + '; ' + j.x + '-' + j.y + '; ' + jobId + '\n';
      }
    }
    return str;
  };
  GJ.jobsDataToBbString = function (chosenJobName) {
    chosenJobName = chosenJobName.toLowerCase();
    var str = '';
    var jobs = GameMap.JobHandler.Featured;
    var k,
    jobId,
    job,
    color,
    j,
    l,
    c = [];
    for (k in jobs) {
      var jobPlace = jobs[k];
      for (jobId in jobPlace) {
        job = JobList.getJobById(jobId);
        if (chosenJobName !== '' && job.name.toLowerCase().indexOf(chosenJobName) < 0)
          continue;
        j = jobPlace[jobId];
        color = j.gold ? GJ.goldJobBbColor : GJ.silverJobBbColor;
        c.push('[b][color=' + color + ']' + job.name + '[/color][/b] (' + j.x + ';' + j.y + ')\n');
      }
    }
    c.sort(function (a, b) {
      a = a.replace(new RegExp(GJ.goldJobBbColor, 'g'), '');
      a = a.replace(new RegExp(GJ.silverJobBbColor, 'g'), '');
      b = b.replace(new RegExp(GJ.goldJobBbColor, 'g'), '');
      b = b.replace(new RegExp(GJ.silverJobBbColor, 'g'), '');
      return (a == b) ? 0 : (a > b) ? 1 :  - 1;
    });
    for (l = 0; l < c.length; l++)
      str += c[l];
    return str;
  };
  GJ.showExportWindow = function (jobs, isBb) {
    var textarea = '<textarea style="height: 100px; width: 400px; background-color: transparent; border-width: 0px;" onclick="$(this).trigger(\'select\')">' + jobs + '</textarea>';
    var md = GJ.getMessageDialog(GJlang.exportButtonTitle, '', textarea);
    var jobName = $('#gj_job_search_textfield').val();
    if (isBb) {
      md.addButton(GJlang.goback, function () {
        var jobs = GJ.jobsDataToString(jobName);
        GJ.showExportWindow(jobs, false);
      });
    } else {
      md.addButton(GJlang.bbCode, function () {
        var jobs = GJ.jobsDataToBbString(jobName);
        GJ.showExportWindow(jobs + '[i]' + GJlang.generatedByBb + ' [url=' + GJ.website + ']TW Gold Jobs Finder[/url][/i]', true);
      });
    }
    md.addButton('ok').show();
  };
  GJ.openFeedbackWindow = function () {
    var langBox = new west.gui.Combobox();
    for (var j in GJ.langs)
      langBox.addItem(j, GJ.langs[j].language);
    langBox.select(GJ.lang);
    var saveBtn = new west.gui.Button(GJlang.save, function () {
      localStorage.setItem('scriptsLang', langBox.getValue());
      GJ.updateLang();
      new UserMessage(GJlang.saveMessage, 'success').show();
    });
    var fms = [['de', 'deutsches Forum'], ['net', 'English forum'], ['pl', 'forum polski'], ['es', 'foro español'], ['ru', 'Русский форум'], ['fr', 'forum français'], ['it', 'forum italiano'], ['net', 'beta forum', 'beta.']],
    add = '<b>' + GJlang.contact + ':</b><ul style="margin-left:15px;"><li>Send a message to <a target=\'_blank\' href="//www.the-west.de/?ref=west_invite_linkrl&player_id=647936&world_id=13&hash=7dda">Tom Robert on German world Arizona</a></li>' +
      '<li>Contact me on <a target=\'_blank\' href="' + GJ.website + '">Greasy Fork</a></li>' +
      '<li>Message me on one of these The West Forum:<br>';
    for (var l of fms)
      add += '/ <a target=\'_blank\' href="//forum.the-west.' + l[0] + '/index.php?conversations/add&to=Tom Robert">' + l[1] + '</a> ' + (l[0] == 'es' ? '<br>' : '');
    add += '/<br>I will get an e-mail when you sent me the message <img src="images/chat/emoticons/smile.png"></li></ul>';
    content = $('<div id="feedback_window_div">' + GJlang.chooseLang + ': </div>');
    content.append(langBox.getMainDiv(), saveBtn.getMainDiv(), '<br><br>' + GJlang.ApiGui + '<br><br><i>' + GJ.name + ' v' + GJ.version + '</i><br><br><br>' + GJlang.feedbackDescription + '<br><br>', add);
    win = wman.open('goldenJobsFeedback', 'GoldJobs ' + GJlang.feedbackWindowTitle, 'noreload').setSize(700, 430).setMiniTitle(GJ.name + ' - ' + GJlang.feedbackWindowTitle);
    win.appendToContentPane(content);
  };
  GJ.addNotification = function (title, jobId, jobX, jobY) {
    var n = new OnGoingEntry();
    n.init('', function () {
      GameMap.JobHandler.openJob(jobId, {
        x: jobX,
        y: jobY
      });
    }, 1);
    n.setTooltip('<b>' + title + '</b>', true);
    WestUi.NotiBar.add(n);
    var icon = JobList.getJobById(jobId).shortname;
    $(n.getMainDiv()).find('.image').css({
      'background-image': 'url(images/jobs/' + icon + '.png)',
      'background-position': '-11px -9px'
    });
  };
  GJ.gui = {};
  GJ.gui.init = function () {
    GJ.gui.makeButton = function (caption, callback) {
      return new west.gui.Button(caption, callback);
    };
    GJ.gui.makeTextfield = function (id) {
      return new west.gui.Textfield(id);
    };
    GJ.gui.makeTable = function () {
      return new west.gui.Table();
    };
  };
  (GJ.Updater = function () {
    if (!window.scriptRequest) {
      scriptRequest = true;
      $.getScript(GJ.updateUrl);
    }
    var intVal = setInterval(function () {
      if (window.scriptUp) {
        scriptUp.c('GJ', GJ.version, GJ.name, '', GJ.website, GJ.lang);
        clearInterval(intVal);
      }
    }, 2000);
  })();
  $(document).ready(function () {
    try {
      GJ.gui.init();
      GJ.init();
    } catch (e) {
      console.log(e.stack);
    }
  });
});