GSJ TOP

try to take over the world!

目前為 2025-03-25 提交的版本,檢視 最新版本

// ==UserScript==
// @name         GSJ TOP
// @namespace    http://tampermonkey.net/
// @version      3.41
// @description  try to take over the world!
// @author       Donald Kaczyński
// @include      https://*.the-west.*/game.php*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=the-west.pl
// @grant        none
// ==/UserScript==
(function (fn) {
    setTimeout(function() {
        var script = document.createElement('script');
        script.setAttribute('type', 'application/javascript');
        script.textContent = '(' + fn + ')();';
        document.body.appendChild(script);
        document.body.removeChild(script);
    }, 5000); // 5000 ms = 5 sekund
})(function () {
  // Inicjalizacja głównego obiektu GSJTOP
  GSJTOP = {
    version: '1.15',
    name: 'GSJ TOP',
    author: 'DK',
    minGame: '3.01',
    maxGame: Game.version.toString(),
    toLoad: 0,
    loaded: 0,
    xMax: 181,
    yMax: 79,
    blockMaxLength: 300,
    dataLoaded: false,
    silverJobBbColor: '#708090',
    goldJobBbColor: '#AB9930',
    refreshInterval: null,
    preferences: {
      showSilver: localStorage.getItem('GSJTOP_showSilver') !== 'false',
      showGold: localStorage.getItem('GSJTOP_showGold') !== 'false',
      enabled: localStorage.getItem('GSJTOP_enabled') !== 'false',
      hideCenterJobs: localStorage.getItem('GSJTOP_hideCenterJobs') !== 'false',
      showTooltips: localStorage.getItem('GSJTOP_showTooltips') !== 'false',
        hideFilters: localStorage.getItem('GSJTOP_hideFilters') === 'true', // Poprawione porównanie
      currentPage: 0,
      jobsPerPage: parseInt(localStorage.getItem('GSJTOP_jobsPerPage')) || 8
    },
    hiddenImageOpacity: 0.35,
    shownImageOpacity: 1,
    bestJobTime: 0,
    position: {
      top: 0,
      right: 0
    },
    langs: {
      pl: {
        language: 'Polish (polski)',
        ApiGui: 'Ten skrypt automatycznie wyszukuje złote i srebrne prace na mapie.',
        title: 'Złote i srebrne prace',
        loading: 'Ładowanie... To zajmie moment',
        next: '→',
        prev: '←',
        enableScript: 'Włącz skrypt'
      }
    },
    updateLang: function () {
      var lg = GSJTOP.langs;
      GSJTOP.lang = lg[localStorage.getItem('scriptsLang')] ? localStorage.getItem('scriptsLang') : lg[Game.locale.substr(0, 2)] ? Game.locale.substr(0, 2) : 'en';
      GSJTOPlang = lg[GSJTOP.lang];
    }
  };
          GSJTOP.updateLang();

  // Funkcja tworząca przełączniki (checkboxy) w interfejsie
GSJTOP.createToggleCheckbox = function() {
    console.log('Initial hideFilters state:', {
        fromPreferences: this.preferences.hideFilters,
        fromLocalStorage: localStorage.getItem('GSJTOP_hideFilters'),
        parsedLocalStorage: localStorage.getItem('GSJTOP_hideFilters') === 'true'
    });

    var container = $('<div/>', {
        id: 'gj-toggle',
        css: {
            position: 'static',
            display: 'inline-block',
            float: 'right',
            marginRight: '-30px',
            zIndex: 10002,
            backgroundColor: 'rgba(255, 255, 255, 0.0)',
            padding: '5px',
            borderRadius: '3px'
        }
    });

 // Główny checkbox włączający skrypt
    var checkbox = $('<input/>', {
        type: 'checkbox',
        id: 'gj-checkbox',
        checked: this.preferences.enabled
    });

    // Checkbox do ukrywania filtrów - poprawiona inicjalizacja
    var hideFiltersCheckbox = $('<input/>', {
        type: 'checkbox',
        id: 'gj-hide-filters',
        checked: localStorage.getItem('GSJTOP_hideFilters') === 'true', // Bezpośrednie sprawdzenie localStorage
        css: {
            marginLeft: '5px'
        }
    });


    console.log('Checkbox initial state:', hideFiltersCheckbox.prop('checked'));

    checkbox.on('change', function() {
        GSJTOP.preferences.enabled = this.checked;
        localStorage.setItem('GSJTOP_enabled', this.checked.toString());
        console.log('Main checkbox changed:', {
            checked: this.checked,
            savedValue: localStorage.getItem('GSJTOP_enabled')
        });
        if (this.checked) {
            GSJTOP.init();
        } else {
            GSJTOP.closeWindow();
        }
    });

    hideFiltersCheckbox.on('change', function() {
        GSJTOP.preferences.hideFilters = this.checked;
        localStorage.setItem('GSJTOP_hideFilters', this.checked.toString());

        console.log('Hide filters checkbox changed:', {
            checked: this.checked,
            savedToPreferences: GSJTOP.preferences.hideFilters,
            savedToLocalStorage: localStorage.getItem('GSJTOP_hideFilters')
        });

        GSJTOP.refreshWindow();
    });

    container.append(checkbox, hideFiltersCheckbox);
    $('#ui_topbar').append(container);

    // Log końcowy - sprawdzenie stanu po inicjalizacji
    console.log('Final state after initialization:', {
        hideFiltersPreferences: this.preferences.hideFilters,
        hideFiltersLocalStorage: localStorage.getItem('GSJTOP_hideFilters'),
        checkboxChecked: hideFiltersCheckbox.prop('checked')
    });
};
  // Funkcja pobierająca dane o pracy
  GSJTOP.getJobData = function(job, isSilver) {
    try {
        var jobData = JobList.getJobById(job.jobId);
        if (!jobData) return null;

        var jobModelData = JobsModel.Jobs.find(j => j.id === parseInt(job.jobId));
        if (!jobModelData) return null;

        var xp = jobModelData.basis.short.experience;
        var money = jobModelData.basis.short.money;
        var motivation = Math.round(jobModelData.jobmotivation * 100);

        if (isSilver) {
            xp = Math.ceil(xp * 1.5);
            money = Math.ceil(money * 1.5);
        }
        else if (job.gold) {
            xp = Math.ceil(xp * 2);
            money = Math.ceil(money * 2);
        }

        return {
            experience: xp,
            money: money,
            motivation: motivation,
            distance: job.distance
        };
    } catch (e) {
        console.log('Error in getJobData:', e);
        return {
            experience: 0,
            money: 0,
            motivation: 0,
            distance: job.distance
        };
    }
  };
          // Funkcja zamykająca okno
  GSJTOP.closeWindow = function() {
    if (this.refreshInterval) {
        clearTimeout(this.refreshInterval);
        this.refreshInterval = null;
    }
    $('#goldJobs-bar').remove();
  };

  // Funkcja do zarządzania automatycznym odświeżaniem
  GSJTOP.startAutoRefresh = function() {
    if (this.refreshInterval) {
        clearTimeout(this.refreshInterval);
    }

    const getRandomDelay = () => Math.floor(Math.random() * (20000 - 7000 + 1) + 7000);

    const scheduleNextRefresh = () => {
        if (!this.preferences.enabled) return;

        this.refreshWindow();
        const nextDelay = getRandomDelay();
        this.refreshInterval = setTimeout(scheduleNextRefresh, nextDelay);
    };

    scheduleNextRefresh();
  };

  // Funkcja obliczająca odległość
  GSJTOP.calculateDistance = function (jobX, jobY) {
    if (!Character || !Character.position) return 0;

    var to = {
        x: parseInt(jobX),
        y: parseInt(jobY)
    };

    return GameMap.calcWayTime(Character.position, to);
  };

  GSJTOP.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 () {
        GSJTOP.loaded++;
        if (GSJTOP.loaded == GSJTOP.toLoad) {
          onLoad();
        }
      });
    }
  };
GSJTOP.getJobIcon = function (jobId, x, y, shortname, gold, jobData) {
    var t = gold ? 'gold' : 'silver';
    var tooltipHtml = this.preferences.showTooltips ?
        '<div class="job-info" style="' +
        'position: absolute; ' +
        'top: 65px; ' +
        'width: 63px; ' +
        'background: #FDF7E5; ' +
        'border: 1px solid #B89B6D; ' +
        'padding: 0; ' +
        'box-shadow: 2px 2px 3px rgba(0,0,0,0.2); ' +
        'z-index: 10003;">' +

        // XP z tooltipem - powiększone cyfry
        '<div style="display: flex; justify-content: space-between; align-items: center; height: 18px; padding: 0 3px; background: #F5ECD4;" title="DOŚWIADCZENIE">' +
        '<div style="width: 14px; height: 14px; background: url(\'https://westpl.innogamescdn.com/images/window/job/bigicon_xp.png\') no-repeat center; background-size: contain;"></div>' +
        '<div style="color: #5C4219; font-size: 13px; font-weight: bold; text-align: right; min-width: 35px;">' + jobData.experience + '</div>' +
        '</div>' +

        // Pieniądze z tooltipem - powiększone cyfry
        '<div style="display: flex; justify-content: space-between; align-items: center; height: 18px; padding: 0 3px;" title="DOLARY">' +
        '<div style="width: 14px; height: 14px; background: url(\'https://westpl.innogamescdn.com/images/window/job/bigicon_money.png\') no-repeat center; background-size: contain;"></div>' +
        '<div style="color: #5C4219; font-size: 13px; font-weight: bold; text-align: right; min-width: 35px;">' + jobData.money + '</div>' +
        '</div>' +

        // Motywacja z tooltipem - powiększone cyfry
        '<div style="display: flex; justify-content: space-between; align-items: center; height: 18px; padding: 0 3px; background: #F5ECD4;" title="MOTYWACJA W PRACY">' +
        '<div style="color: #5C4219; font-size: 13px; font-weight: bold; width: 100%; text-align: center;">' + jobData.motivation + '%</div>' +
        '</div>' +

        // Czas z tooltipem - powiększone cyfry
        '<div style="display: flex; justify-content: space-between; align-items: center; height: 18px; padding: 0 3px;" title="CZAS DOTARCIA">' +
        '<div style="color: #5C4219; font-size: 13px; font-weight: bold; width: 100%; text-align: center;">' + GSJTOP.formatTime(jobData.distance) + '</div>' +
        '</div>' +
        '</div>' : '';

    return '<div class="job-wrapper" style="position: relative; display: inline-flex; flex-direction: column; align-items: center; margin: -1px; width: 65px; height: 65px; z-index: 10000;">' +
           '<div class="job" style="position: relative; width: 65px; height: 65px;">' +
           '<img src="images/jobs/' + shortname + '.png" class="job_icon" style="width: 65px; height: 65px; position: relative; z-index: 10000;">' +
           '<div onclick="javascript:GameMap.JobHandler.openJob(' + jobId + ',{x:' + x + ',y:' + y + '})" ' +
           'class="featured ' + t + '" style="position: absolute; top: -5px; left: -5px; z-index: 10001; width: 75px; height: 75px; background-size: contain;"></div>' +
           this.getGotoIcon(x, y) +
           '</div>' +
           tooltipHtml +
           '</div>';
};
          GSJTOP.formatTime = function(seconds) {
    seconds = Math.round(seconds);
    var hours = Math.floor(seconds / 3600);
    var minutes = Math.floor((seconds % 3600) / 60);
    var secs = seconds % 60;

    return String(hours).padStart(2, '0') + ':' +
           String(minutes).padStart(2, '0') + ':' +
           String(secs).padStart(2, '0');
  };

  GSJTOP.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: 25px; height: 25px; top: -2px; right: -2px; cursor: pointer; z-index: 10002; background-size: contain;"></div>';
  };

GSJTOP.createNavigationButtons = function() {
    var wrapperStyle = {
        'width': '30px',
        'height': '60px',
        'display': 'flex',
        'justify-content': 'center',
        'align-items': 'center',
        'cursor': 'pointer',
        'margin-top': '35px',
        'z-index': 10001
    };

    var buttonStyle = {
        'width': '25px',
        'height': '44px',
        'background-image': 'url(\'https://westit.innogamescdn.com/images/window/trader/arrows.png\')',
        'color': 'white',
        'padding': '0px',
        'display': 'block',
        'background-size': 'cover',
        'text-align': 'center'
    };

    var prevWrapper = $('<div/>', {
        css: Object.assign({}, wrapperStyle, {
            'margin-right': '0px',
            'position': 'relative',
            'top': '-15px'
        })
    });

    var nextWrapper = $('<div/>', {
        css: Object.assign({}, wrapperStyle, {
            'margin-left': '0px',
            'position': 'relative',
            'top': '-15px'
        })
    });

    var prevButton = $('<div/>', {
        css: Object.assign({}, buttonStyle, {
            'background-position': 'top left'
        })
    });

    var nextButton = $('<div/>', {
        css: Object.assign({}, buttonStyle, {
            'background-position': 'top right'
        })
    });

    prevWrapper.append(prevButton).click(function() {
        if (GSJTOP.preferences.currentPage > 0) {
            GSJTOP.preferences.currentPage--;
            GSJTOP.refreshWindow();
        }
    });

    nextWrapper.append(nextButton).click(function() {
        var totalJobs = GSJTOP.getFilteredData(GSJTOP.preferences.showSilver, GSJTOP.preferences.showGold).length;
        var maxPages = Math.ceil(totalJobs / GSJTOP.preferences.jobsPerPage);
        if (GSJTOP.preferences.currentPage < maxPages - 1) {
            GSJTOP.preferences.currentPage++;
            GSJTOP.refreshWindow();
        }
    });

    return {
        prev: prevWrapper,
        next: nextWrapper
    };
};
    GSJTOP.createJobsContainer = function (showSilver, showGold) {
    var container = $('<div/>', {
        class: 'jobs-container',
        css: {
            'display': 'flex',
            'flex-direction': 'column',
            'justify-content': 'flex-start',
            'align-items': 'center',
            'gap': '10px',
            'height': '120px',
            'overflow': 'visible',
            'background': 'rgba(255, 255, 255, 0.0)',
            'padding': '0 15px',
            'position': 'relative',
            'width': 'auto',
            'z-index': 10000,
            'min-height': '120px'
        }
    });

    var jobsWrapper = $('<div/>', {
        css: {
            'display': 'flex',
            'justify-content': 'center',
            'align-items': 'center',
            'gap': '10px',
            'width': 'auto',
            'margin-bottom': '5px',
            'margin-top': '25px',
            'min-height': '65px',
            'flex-wrap': 'nowrap',
            'position': 'relative'
        }
    });

    var filterContainer = $('<div/>', {
        css: {
            'display': this.preferences.hideFilters ? 'flex' : 'none',
            'justify-content': 'center',
            'align-items': 'center',
            'gap': '10px',
            'margin-top': this.preferences.showTooltips ? '80px' : '10px',
            'background-color': 'rgba(255, 255, 255, 0.7)',
            'padding': '5px 10px',
            'border': '1px solid rgba(0, 0, 0, 0.2)',
            'border-radius': '5px',
            'box-shadow': '0 1px 3px rgba(0, 0, 0, 0.1)',
            'position': 'absolute',
            'top': this.preferences.showTooltips ? '85px' : '85px'
        }
    });

    // Dodajemy select do wyboru ilości prac
    var jobsPerPageSelect = $('<select/>', {
        css: {
            'padding': '2px',
            'margin-left': '5px',
            'border-radius': '3px',
            'border': '1px solid rgba(0, 0, 0, 0.2)',
            'background-color': 'white',
            'cursor': 'pointer'
        },
        change: function() {
            GSJTOP.preferences.jobsPerPage = parseInt($(this).val());
            localStorage.setItem('GSJTOP_jobsPerPage', GSJTOP.preferences.jobsPerPage);
            GSJTOP.preferences.currentPage = 0;
            GSJTOP.refreshWindow();
        }
    });

[4, 6, 8, 10].forEach(function(num) {
    jobsPerPageSelect.append($('<option/>', {
        value: num,
        text: num + (num === 1 ? ' praca' : num < 5 ? ' prace' : ' prac'),
        selected: GSJTOP.preferences.jobsPerPage === num
    }));
});

var tooltipsButton = $('<div/>', {
    id: 'gj-tooltips',
    css: {
        'width': '24px',
        'height': '24px',
        'background-color': GSJTOP.preferences.showTooltips ? '#4CAF50' : '#cccccc',
        'border-radius': '3px',
        'cursor': 'pointer',
        'transition': 'all 0.3s ease',
        'border': '1px solid rgba(0, 0, 0, 0.2)',
        'box-shadow': '0 1px 3px rgba(0, 0, 0, 0.1)',
        'margin-right': '1px'
    }
}).hover(
    function() {
        $(this).css({
            'transform': 'scale(1.1)',
            'box-shadow': '0 2px 5px rgba(0, 0, 0, 0.2)'
        });
    },
    function() {
        $(this).css({
            'transform': 'scale(1)',
            'box-shadow': '0 1px 3px rgba(0, 0, 0, 0.1)'
        });
    }
).click(function() {
    GSJTOP.preferences.showTooltips = !GSJTOP.preferences.showTooltips;
    localStorage.setItem('GSJTOP_showTooltips', GSJTOP.preferences.showTooltips);
    $(this).css('background-color', GSJTOP.preferences.showTooltips ? '#4CAF50' : '#cccccc');
    // Usunięto zmianę margin-top
    GSJTOP.refreshWindow();
});

var centerJobsFilter = $('<div/>', {
    css: {
        'width': '24px',
        'height': '24px',
        'cursor': 'pointer',
        'margin-right': '1px',
        'background-color': this.preferences.hideCenterJobs ? '#ff4444' : '#cccccc',
        'border-radius': '3px',
        'border': '1px solid rgba(0, 0, 0, 0.2)',
        'transition': 'all 0.3s ease',
        'box-shadow': '0 1px 3px rgba(0, 0, 0, 0.1)'
    }
}).hover( // Dodano efekt hover
    function() {
        $(this).css({
            'transform': 'scale(1.1)',
            'box-shadow': '0 2px 5px rgba(0, 0, 0, 0.2)'
        });
    },
    function() {
        $(this).css({
            'transform': 'scale(1)',
            'box-shadow': '0 1px 3px rgba(0, 0, 0, 0.1)'
        });
    }
).click(function() {
    var isCurrentlyActive = $(this).css('background-color') === 'rgb(255, 68, 68)';
    GSJTOP.preferences.hideCenterJobs = !isCurrentlyActive;
    localStorage.setItem('GSJTOP_hideCenterJobs', GSJTOP.preferences.hideCenterJobs);
    $(this).css({
        'background-color': isCurrentlyActive ? '#cccccc' : '#ff4444'
    });
    GSJTOP.preferences.currentPage = 0;
    GSJTOP.refreshWindow();
});

    var goldFilter = $('<img/>', {
        src: 'images/jobs/featured/goldjob.png',
        css: {
            'width': '24px',
            'height': '24px',
            'opacity': showGold ? this.shownImageOpacity : this.hiddenImageOpacity,
            'cursor': 'pointer',
            'border': showGold ? '1px solid rgba(171, 153, 48, 0.5)' : 'none',
            'border-radius': '3px'
        },
        click: function() {
            GSJTOP.onJobIconFilterClick('gold', $(this));
        }
    });

    var silverFilter = $('<img/>', {
        src: 'images/jobs/featured/silverjob.png',
        css: {
            'width': '24px',
            'height': '24px',
            'opacity': showSilver ? this.shownImageOpacity : this.hiddenImageOpacity,
            'cursor': 'pointer',
            'border': showSilver ? '1px solid rgba(112, 128, 144, 0.5)' : 'none',
            'border-radius': '3px'
        },
        click: function() {
            GSJTOP.onJobIconFilterClick('silver', $(this));
        }
    });

    filterContainer.append(tooltipsButton, centerJobsFilter, silverFilter, goldFilter, jobsPerPageSelect);

    var data = this.getFilteredData(showSilver, showGold);
    var start = this.preferences.currentPage * this.preferences.jobsPerPage;
    var pageJobs = data.slice(start, start + this.preferences.jobsPerPage);

    pageJobs.forEach(function(job) {
        var jobData = GSJTOP.getJobData(job, job.silver);
        if (jobData) {
            jobsWrapper.append(GSJTOP.getJobIcon(job.jobId, job.x, job.y, job.shortname, job.gold, jobData));
        }
    });

    container.append(jobsWrapper, filterContainer);
    return container;
};

GSJTOP.onJobIconFilterClick = function (type, element) {
    var hiddenImageOpacity = this.hiddenImageOpacity;
    var shownImageOpacity = this.shownImageOpacity;

    var isCurrentlyActive = ($(element).css('opacity') == shownImageOpacity);
    var otherFilterActive = (type === 'gold') ? this.preferences.showSilver : this.preferences.showGold;

    if (isCurrentlyActive && !otherFilterActive) {
        return;
    }

    if (type === 'gold') {
        this.preferences.showGold = !isCurrentlyActive;
        localStorage.setItem('GSJTOP_showGold', this.preferences.showGold);
        $(element).css({
            'opacity': isCurrentlyActive ? hiddenImageOpacity : shownImageOpacity,
            'border': isCurrentlyActive ? 'none' : '1px solid rgba(171, 153, 48, 0.5)'
        });
    } else {
        this.preferences.showSilver = !isCurrentlyActive;
        localStorage.setItem('GSJTOP_showSilver', this.preferences.showSilver);
        $(element).css({
            'opacity': isCurrentlyActive ? hiddenImageOpacity : shownImageOpacity,
            'border': isCurrentlyActive ? 'none' : '1px solid rgba(112, 128, 144, 0.5)'
        });
    }

    this.preferences.currentPage = 0;
    this.refreshWindow();
};
    GSJTOP.openWindow = function () {
    if (!this.preferences.enabled) return;

    $('#goldJobs-bar').remove();

    var bar = $('<div/>', {
        id: 'goldJobs-bar',
        css: {
            'position': 'fixed',
            'background': 'rgba(255, 255, 255, 0.0)',
            'border': 'none',
            'padding': '0px',
            'z-index': 10000,
            'display': 'flex',
            'flex-direction': 'row',
            'align-items': 'center',
            'justify-content': 'center',
            'width': '100%',
            'height': '130px',
            'left': '0',
            'right': '0',
            'top': '20px',
            'margin': '0 auto',
            'pointer-events': 'none'
        }
    });

    var contentWrapper = $('<div/>', {
        css: {
            'display': 'flex',
            'justify-content': 'center',
            'align-items': 'center',
            'width': 'auto',
            'margin': '0 auto',
            'pointer-events': 'auto',
            'position': 'relative'
        }
    });

var navigation = this.createNavigationButtons();
    var jobsContainer = this.createJobsContainer(this.preferences.showSilver, this.preferences.showGold);

    contentWrapper.append(navigation.prev, jobsContainer, navigation.next);
    bar.append(contentWrapper);
    $('#ui_topbar').append(bar);

    $(document).on('position_change', GSJTOP.refreshWindow);
};

GSJTOP.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;
            }
        }
        GSJTOP.tilesWithJobs = result;
        callback();
    });
};

GSJTOP.getFilteredData = function (showSilver, showGold) {
    var jobs = GameMap.JobHandler.Featured;
    var k, jobId, job, j;
    var result = [];

    try {
        for (k in jobs) {
            var jobPlace = jobs[k];
            for (jobId in jobPlace) {
                job = JobList.getJobById(jobId);
                if (!job) continue;

                if (this.preferences.hideCenterJobs && parseInt(jobId) < 131) {
                    continue;
                }

                j = jobPlace[jobId];
                if ((j.silver && !showSilver) || (j.gold && !showGold)) {
                    continue;
                }

                var distance = 0;
                try {
                    distance = this.calculateDistance(j.x, j.y);
                } catch (e) {
                    console.log('Error calculating distance:', e);
                }

                var motivation = 0;
                try {
                    var jobData = JobsModel.Jobs.find(jb => jb.id === parseInt(jobId));
                    if (jobData) {
                        motivation = Math.round(jobData.jobmotivation * 100);
                    }
                } catch (e) {
                    console.log('Error getting motivation:', e);
                }

                result.push({
                    jobId: jobId,
                    x: j.x,
                    y: j.y,
                    shortname: job.shortname,
                    gold: j.gold,
                    silver: j.silver,
                    distance: distance,
                    motivation: motivation
                });
            }
        }

        result.sort(function(a, b) {
            return a.distance - b.distance;
        });
    } catch (e) {
        console.log('Error in getFilteredData:', e);
    }

    return result;
};
    GSJTOP.refreshWindow = function () {
    if (!GSJTOP.preferences.enabled) {
        $('#goldJobs-bar').remove();
        return;
    }

    Ajax.get('work', 'index', {}, function(response) {
        if (response.error) {
            console.log('Error refreshing job data:', response.error);
            return;
        }

        JobsModel.initJobs(response.jobs);
        var newContainer = GSJTOP.createJobsContainer(GSJTOP.preferences.showSilver, GSJTOP.preferences.showGold);
        $('#goldJobs-bar .jobs-container').replaceWith(newContainer);
    });
};

GSJTOP.init = function () {
    if (!GSJTOP.preferences.enabled) return;

    var onLoad = function () {
        Ajax.get('work', 'index', {}, function(response) {
            if (response.error) {
                console.log('Error loading job data:', response.error);
                return;
            }

            JobsModel.initJobs(response.jobs);
            GSJTOP.preferences.currentPage = 0;
            GSJTOP.openWindow();
            GSJTOP.dataLoaded = true;
            GSJTOP.startAutoRefresh();
        });
    };

    if (!GSJTOP.hasOwnProperty('tilesWithJobs')) {
        new UserMessage(GSJTOPlang.loading, UserMessage.TYPE_HINT).show();
        GSJTOP.getAllTiles(function () {
            GSJTOP.parseWholeMap(GSJTOP.tilesWithJobs, onLoad);
        });
    } else {
        onLoad();
    }
};

GSJTOP.gui = {};
GSJTOP.gui.init = function () {};

// Inicjalizacja przy załadowaniu dokumentu
$(document).ready(function () {
    try {
        GSJTOP.gui.init();
        GSJTOP.createToggleCheckbox();
        if (GSJTOP.preferences.enabled) {
            GSJTOP.init();
        }
    } catch (e) {
        console.log(e.stack);
    }
});

}); // Zamknięcie głównej funkcji

// Skrypt usuwający element first-purchase
(function() {
    'use strict';
    function usuńFirstPurchase() {
        const element = document.querySelector('.first-purchase');
        if (element) {
            element.remove();
            console.log('Element first-purchase został usunięty');
        } else {
            console.log('Element first-purchase nie został znaleziony');
            clearInterval(intervalId);
        }
    }
    const intervalId = setInterval(usuńFirstPurchase, 1000);
})();