Doublexp doubleskill.png Double Exp & Skill: Matar monstros rende o dobro de pontos de experiência. O progresso de skills é duas vezes mais rápido! Doublexp doubleskill.png
Bone Overlord.gif The Roost of the Graveborn Quest Spoiler!
Domine Graveborn: todos os bosses e mecânicas ilustradas!
Saiba mais ➔
Winter Tree.png Winter Update 2025
Acompanhe tudo sobre o Winter Update 2025!
Saiba mais ➔
Stag.gif The Order of the Stag Quest Spoiler!
Conheça Isle of Ada: sua quest, missões secundárias e todos os bosses!
Saiba mais ➔

Tibia Wiki:Charm Simulator/codigo: mudanças entre as edições

De Tibia Wiki - A Enciclopédia do Tibia
Ir para navegação Ir para pesquisar
Linha 841: Linha 841:


     var loadCharms = async () => {
     var loadCharms = async () => {
         let baseURL = 'https://mypper.com/tibia/v1/tibiawiki';
         let baseURL = '';
         $('.loading label').text('Buscando Charms e Runes para Você, Aventureiro!... Os Deuses nos abençoarão com o conhecimento divino!');
         $('.loading label').text('Buscando Charms e Runes para Você, Aventureiro!... Os Deuses nos abençoarão com o conhecimento divino!');
         await Promise.all([requestCharmsData(baseURL, 'Charms', 'charms')]).then((result) => {
         await Promise.all([requestCharmsData(baseURL, 'Charms', 'charms')]).then((result) => {

Edição das 04h34min de 25 de novembro de 2024

<div class="main_div_charms">
    <div class="loading">
        <img src="https://www.tibiawiki.com.br/images/c/ce/The_Epic_Wisdom.gif" /><br />
        <label>Loading...</label>
        <span>@TibiaWiki</span>
    </div>
    <div class="left_panel">
        <tw-title class="white bottom-divisor h55 margin-bottom-15">Charms Simulation</tw-title>
        <tw-input>
            <label for="charm-points" class="white">Charm Points:</label>
            <input id="input-charm-points" name="charm-points" type="number" min="0" value="100" oninput="setMajorCharmPoints(this.value)"/>
        </tw-input>
        <tw-checkbox class="bottom-divisor margin-10 padding-top-15">
            <input id="checkbox-promotion" type="checkbox" name="is-promotion" checked onchange="setPromotionMinorCharms(this)">
            <label for="is-promotion" class="white">Promotion?</label>
        </tw-checkbox>
        <tw-info-panel class="white margin-top-25 margin-bottom-10 margin-left-10 margin-right-10">
            <tw-info class="margin-top-10 ta-left">
                Major Charm Points: </br> <span id="major-charms-label" style="font-weight: normal;">/</span> <i><img src="https://www.tibiawiki.com.br/images/b/b2/Icon_Major_Charm_Points.png"></i>
            </tw-info>
            <tw-info class="margin-top-10 ta-left">
                Minor Charm Points: </br> <span id="minor-charms-label" style="font-weight: normal;">/</span> <i><img src="https://www.tibiawiki.com.br/images/6/65/Icon_Minor_Charm_Points.png"></i>
            </tw-info>
        </tw-info-panel>
        <tw-title class="white top-divisor h55 margin-top-25">Resetar todos os Charms</tw-title>
        <tw-input>
            <label for="level-input" class="white">Level:</label>
            <input id="input-level" name="level-input" type="number" min="1" value="8" oninput="resetAllCharmsCalc(this)"/>
        </tw-input>
        <tw-info-panel class="white margin-top-5 margin-bottom-10 margin-left-10 margin-right-10">
            <tw-info class="ta-left">
                Resetar Runas: <i><img style="width: 10px; object-fit: none;" src="https://www.tibiawiki.com.br/images/d/d6/Gold_Coin_1.png?20241122160426"></i> <span id="reset-all-charms-value" style="font-weight: normal;"></span>
            </tw-info>
            <tw-info class="padding-top-10 ta-left">
                Remover Criatura: <i><img style="width: 10px; object-fit: none;" src="https://www.tibiawiki.com.br/images/d/d6/Gold_Coin_1.png?20241122160426"></i> <span id="remove-creature-price" class="white" style="font-weight: normal;"></span>
            </tw-info>
            <tw-checkbox class="margin-top-10">
                <input id="checkbox-charm-expansion" type="checkbox" name="is-charm-expansion" checked onchange="resetAllCharmsCalc(document.getElementById('input-level'))">
                <label for="is-charm-expansion" title="is-charm-expansion" class="font-14">Charm Expansion?</label>
            </tw-checkbox>
            <button id="btn-reset" class="margin-top-15" onclick="resetAllRunes()">resetar todas as runas</button>
        </tw-info-panel>
    </div>
    <div class="right_panel">
        <tw-title class="bottom-divisor h55 margin-bottom-15">Charms Runes Info</tw-title>        
        <tw-info-panel class="side-by-side margin-bottom-10 margin-left-10 margin-right-10 margin-top-10">
            <tw-info-panel style="width: 62px;" style="overflow: auto;">
                <tw-img-slot id="selected-charm-rune-img-slot" class="rune-level">
                    <img id="selected-charm-rune-img" src="https://www.tibiawiki.com.br/images/3/35/Trans.gif" alt="charm image">
                </tw-img-slot>
                <tw-info class="margin-top-5 ta-center cl-tw-red">
                    Nivel:
                </tw-info>
                <tw-info id="selected-charm-rune-level" class="margin-top-5 ta-center">
                    -
                </tw-info>
                <tw-info class="margin-top-5 ta-center cl-tw-red">
                    Bonus:
                </tw-info>
                <tw-info id="selected-charm-rune-attribute" class="margin-top-5 ta-center">
                </tw-info>
            </tw-info-panel>
            <tw-info-panel class="margin-bottom-10 margin-left-10 margin-right-10" style="overflow: auto; height: 276px;">
                <tw-info class="cl-tw-red ta-left">
                    Charm Rune: <span id="selected-charm-rune-name" class="black" style="font-weight: normal;"></span>
                </tw-info>
                <tw-info class="margin-top-10 margin-bottom-10 cl-tw-red ta-left">
                    Descrição: <span id="selected-charm-rune-description" class="black" style="font-weight: normal;"></span>
                </tw-info>
                <tw-info class="margin-top-5 cl-tw-red ta-left">
                    Efeito: <span id="selected-charm-rune-effect" class="black" style="font-weight: normal;"></span>
                </tw-info>
                <tw-info class="margin-top-5 cl-tw-red ta-left">
                    Desbloquear: <span id="selected-charm-rune-unlock" class="black" style="font-weight: normal;"></span>
                </tw-info>
                <tw-info class="margin-top-5 cl-tw-red ta-left">
                    Nível 2: <span id="selected-charm-rune-nivel-two" class="black" style="font-weight: normal;"></span>
                </tw-info>
                <tw-info class="margin-top-5 cl-tw-red ta-left">
                    Nível 3: <span id="selected-charm-rune-nivel-three" class="black" style="font-weight: normal;"></span>
                </tw-info>
                <tw-info class="margin-top-5 cl-tw-red ta-left">
                    Pontos Necessário: <span id="selected-charm-rune-unlock-all" class="black" style="font-weight: normal;"></span>
                </tw-info>
                <button id="btn-unlock" class="margin-top-15 btn btn-red" onclick="unlockRunes()">desbloquear runa</button>
            </tw-info-panel>
        </tw-info-panel>
        <tw-tabs-panel style="height: calc(100% - 403.5px);">
            <tw-tabs>
                <tw-tab id="tab-index-0" class="td-2 unselected white" onclick="selecTab(this)">
                    Major Charms
                </tw-tab>
                <tw-tab id="tab-index-1" class="td-2 unselected white" onclick="selecTab(this)">
                    Minor Charms
                </tw-tab>
            </tw-tabs>
            <tw-panel>
                <table>
                    <tbody id="runes-table">
                    </tbody>
                </table>
            </tw-panel>
        </tw-tabs-panel>
    </div>
</div>
    .main_div_charms {
        display: flex;
        width: 700px;
        height: 700px;
        border-radius: 5px;
        border: 1px black solid;
        font-family: Verdana, Arial, Times New Roman, sans-serif;
    }
    .left_panel {
        background-color: #c7451d;
        width: 250px;
        height: 100%;
        border-top-left-radius: 5px;
        border-bottom-left-radius: 5px;
    }
    .right_panel {
        background-color: white;
        width: calc(100% - 250px);
        height: 100%;
        border-top-right-radius: 5px;
        border-bottom-right-radius: 5px;
    }
    tw-title {
        align-content: center;
        margin-left: 10px;
        margin-right: 10px;
        width: calc(100% - 20px);
        display: block;
        text-align: center;
        font-weight: bold;
        font-size: 16px;
    }

    tw-title.subtitle {
        align-content: center;
        margin-left: 10px;
        margin-right: 10px;
        width: calc(100% - 20px);
        display: block;
        text-align: center;
        font-weight: bold;
        font-size: 14px;
    }

    tw-title.white {
        color: white;
    }
    tw-title.h40 {
        height: 40px;
    }
    tw-title.h55 {
        height: 55px;
    }
    tw-input {
        width: calc(100% - 10px);
        display: block;
        height: 70px;
        align-content: center;
    }
    tw-input label {
        display: flex;
        width: calc(100% - 10px);
        height: 35px;
        font-weight: bold;
    }
    tw-input input {
        border-radius: 5px;
        border: 1px;
        width: calc(100% - 20px);
        font-weight: bold;
        height: 32px;
        text-align: center;
    }
    tw-checkbox {
        width: calc(100% - 20px);
        display: inline-flex;
        align-items: center;
    }
    tw-checkbox input {
        height: 20px;
        width: 20px;
    }
    tw-checkbox label {
        font-weight: bold;
    }
    tw-info-panel {
        width: calc(100% - 20px);
        display: block;
    }

    tw-info-panel.side-by-side {
        display: flex;
    }
    tw-info-panel.align-center {
        align-items: center;
    }
    tw-info-panel tw-info {
        width: 100%;
        font-weight: bold;
        display: block;
        font-size: 13.5px;
    }
    tw-info {
        display: block;
    }
    tw-img-slot {
        align-content: center;
        text-align: center;
        padding: 5px;
        display: inline-block;
        width: 45px;
        height: 52px;
    }
    tw-img-slot.rune-level {
    }
    tw-img-slot.unlocked_one {
        border: none;
        background: url(https://www.tibiawiki.com.br/images/e/ee/Charm_Overhaul_-_Bronze.png?20241124115705);
        background-repeat: no-repeat;
        background-size: contain;
    }
    tw-img-slot.unlocked_two {
        border: none;
        background: url(https://www.tibiawiki.com.br/images/8/8e/Charm_Overhaul_-_Silver.png);
        background-repeat: no-repeat;
        background-size: contain;
    }
    tw-img-slot.unlocked_three {
        border: none;
        background: url(https://www.tibiawiki.com.br/images/7/70/Charm_Overhaul_-_Gold.png);
        background-repeat: no-repeat;
        background-size: contain;
    }
    tw-img-slot img {
        width: 80%;
        height: 80%;
    }
    tw-tabs-panel {
        display: block;
        width: 100%;
    }
    tw-tabs-panel tw-tabs {
        display: flex;
        border-top: 1px solid black;
        border-bottom: 1px solid black;
        width: 100%;
        height: 32px;
    }

    tw-tabs-panel tw-tabs tw-tab {
        align-content: center;
        text-align: center;
        border-left: 1px solid black;
        border-right: 1px solid black;
        font-weight: bold;
    }
    tw-tabs-panel tw-tabs tw-tab.td-2 {
        width: 50%;
    }
    tw-tabs-panel tw-tabs tw-tab.unselected {
        background-color: #c7451d;
    }
    tw-tabs-panel tw-tabs tw-tab.selected {
        background-color: #7c2f29;
    }
    tw-tabs-panel tw-panel {
        display: block;
        overflow: auto;
        width: 100%;
        height: 100%;
    }
    tw-table-cell {
        display: table-cell;
        align-content: center;
        text-align: center;
        width: 104px;
        height: 116px;
    }

    tw-table-cell tw-cell-bg {
        display: block;
        width: 90px;
        height: 90px;
        margin-left: 5px;
        margin-top: 1px;
        border: 1px solid black;
        border-radius: 5px;
    }

    @supports (-webkit-appearance: none) {
        tw-table-cell tw-cell-bg {
            display: block;
            width: 90px;
            height: 90px;
            margin-left: 6px;
            margin-top: 0px;
            border: 1px solid black;
            border-radius: 5px;
        }
    }
    tw-table-cell tw-cell-bg.selected {
        border-radius: 0px;
        background-color: #c7451d;
    }

    tw-table-cell.selected {
        background-color: #c7451d;
    }
    tw-table-cell.unlocked_one {
        border: none;
        background: url(https://www.tibiawiki.com.br/images/e/ee/Charm_Overhaul_-_Bronze.png?20241124115705);
        background-repeat: no-repeat;
        background-size: cover;
    }
    tw-table-cell.unlocked_two {
        border: none;
        background: url(https://www.tibiawiki.com.br/images/8/8e/Charm_Overhaul_-_Silver.png);
        background-repeat: no-repeat;
        background-size: cover;
    }
    tw-table-cell.unlocked_three {
        border: none;
        background: url(https://www.tibiawiki.com.br/images/7/70/Charm_Overhaul_-_Gold.png);
        background-repeat: no-repeat;
        background-size: cover;
    }

    #btn-reset {
        width: 100%;
        height: 32px;
        font-weight: bold;
        border-radius: 5px;
        border: none;
        background: linear-gradient(180deg, rgba(215,215,215,1) 0%, rgba(221,221,221,1) 35%, rgba(240,240,240,1) 100%);
    }
    #btn-reset:hover {
        background: linear-gradient(180deg, rgba(240,240,240,1) 0%, rgba(221,221,221,1) 35%, rgba(215,215,215,1) 100%);
    }
    #btn-reset:active {
        background: silver;
    }
    .btn {
        width: 100%;
        height: 32px;
        font-weight: bold;
        border-radius: 5px;
        border: none;
    }
    .btn-red {
        background: linear-gradient(180deg, rgba(199,69,29,1) 0%, rgba(177,43,2,1) 35%, rgba(199,69,29,1) 100%);
        color: white;
    }
    .btn-red:hover {
        background: rgb(199,69,29);
    }
    .btn-red:active {
        background: #7c2f29;
    }
    .btn-disabled {
        background-color: lightgray;
        color: gray;
    }

    .fz-11 {
        font-size: 11px;
    }
    .fz-13 {
        font-size: 13px;
    }
    .top-divisor {
        border-top: 1px solid black;
    }
    .bottom-divisor {
        border-bottom: 1px solid black;
    }
    .white {
        color: white;
    }
    .margin-10 {
        margin: 10px;
    }
    .margin-top-5 {
        margin-top: 5px;
    }
    .margin-top-10 {
        margin-top: 10px;
    }
    .margin-top-15 {
        margin-top: 15px;
    }
    .margin-top-25 {
        margin-top: 25px;
    }
    .margin-bottom-10 {
        margin-bottom: 10px;
    }
    .margin-bottom-15 {
        margin-bottom: 15px;
    }
    .margin-left-10 {
        margin-left: 10px;
    }
    .margin-right-10 {
        margin-right: 10px;
    }
    .font-14 {
        font-size: 14px;
    }
    .padding-top-10 {
        padding-top: 10px;
    }
    .padding-top-15 {
        padding-bottom: 15px;
    }
    .cl-tw-red {
        color: #c7451d;
    }
    .black {
        color: black;
    }
    .ta-center {
        text-align: center;
    }
    .ta-left {
        text-align: left;
    }
    .loading {
        z-index: 9999;
        background-color: rgba(255, 255, 255, 0.98);
        display: inline-block;
        border-radius: 3px;
        position: absolute;
        height: 700px;
        width: 700px;
        align-content: center;
        text-align: center;
        top: auto;
        left: auto;
    }
    
    .loading>label {
        position: relative;
        bottom: 0px;
        text-align: center;     
        font-size: math;
        background: transparent;
    }
    .loading > span {
        text-align: center;
        align-content: center;
        background-color: #c7451d;
        height: 32px;
        width: 100%;
        position: absolute;
        bottom: 0px;
        left: 0px;
        text-align: center;     
        font-size: math;
        border-bottom-left-radius: 3px;
        border-bottom-right-radius: 3px;
    }
var charms;

    var setPromotionMinorCharms = (checkbox) => {
        charmPoints.minor_charms.max += (checkbox.checked) ? 100 : -100;
        updateLabelCharmPoints("minor_charms");
        saveUnlockedRunes();
    }
    var setMajorCharmPoints = (points) => {
        charmPoints.major_charms.max = Number(points);
        updateLabelCharmPoints("major_charms");
        enableUnlockButton();
    }

    var setUsedMajorCharmPoints = () => {
        document.getElementById('major-charms-label').innerText = ((charmPoints.major_charms.used - charmPoints.major_charms.max) * -1) + '/' + charmPoints.major_charms.max;
    }

    var setMinorCharmPoints = (points) => {
        charmPoints.minor_charms.max = Number(points);
        updateLabelCharmPoints("minor_charms");
        enableUnlockButton();
    }

    var setUsedMinorCharmPoints = () => {
        document.getElementById('minor-charms-label').innerText = ((charmPoints.minor_charms.used - charmPoints.minor_charms.max) * -1) + '/' + charmPoints.minor_charms.max;
    }

    var updateLabelCharmPoints = (classe) => {
        let used = charmPoints[classe].used;
        if (((used - charmPoints[classe].max) * -1) < 0) {
            resetAllRunes("removedPoints", classe);
        } else {
            (classe === 'major_charms') ? setUsedMajorCharmPoints() : setUsedMinorCharmPoints();
        }
    }

    var resetAllCharmsCalc = (input) => {
        let level = input.value;
        let value = (level <= 100) ? 100000 : ((level - 100) * 11000) + 100000;
        document.getElementById("reset-all-charms-value").innerText = ((document.getElementById('checkbox-charm-expansion').checked) ? (value - (value * 0.25)) : value).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
        setRemoveCreaturePrice();
        saveUnlockedRunes();
    }

    var populateTable = () => {
        let charmRunes = charms[selectedCharmsClass];
        let body = document.getElementById("runes-table");
        body.innerHTML = "";

        let index = 0;
        let tr = createLine();
        charmRunes.forEach(rune => {
            tr.append(createCell(rune));
            index++;
            if (tr.children.length === 4 || rune.name === charmRunes[charmRunes.length - 1].name) {
                body.append(tr);
                tr = createLine();
            }
        });
    }

    var createLine = () => {
        return document.createElement('tr')
    }
    var createCell = (rune) => {
        let td = document.createElement('td');
        let twTableCell = document.createElement('tw-table-cell');
        let twCellBg = document.createElement('tw-cell-bg');
        if (rune.selected) {
            twCellBg.classList.add('selected')
        }
        if (rune.unlocked != null) {
            let level = "";
            if (rune.unlocked === 1) {
                level = "one";
            }
            if (rune.unlocked === 2) {
                level = "two";
            }
            if (rune.unlocked === 3) {
                level = "three";
            }
            twTableCell.classList.add('unlocked_' + level);
        }

        let twImageSlot = document.createElement('tw-img-slot');
        let img = document.createElement('img');
        img.src = rune.image;

        let twInfo = document.createElement('tw-info');
        twInfo.classList.add('fz-11');
        twInfo.innerText = rune.name;

        twImageSlot.append(img);
        twCellBg.append(twImageSlot);
        twCellBg.append(twInfo);
        twTableCell.append(twCellBg);
        twTableCell.setAttribute('name', rune.name);

        td.append(twTableCell);
        td.onclick = () => {
            selectRune(twTableCell, rune);
        };

        return td;
    }

    var cleanSelectedCharmRune = () => {
        let cell = document.getElementsByName(selectedRuneCharm[selectedCharmsClass].name);
        if (cell.length === 1) {
            selectedRuneCharm[selectedCharmsClass].selected = false;
            cell[0].children[0].classList.remove('selected');
        }
    }

    var selectRune = (cell, rune, isTabSelected) => {
        if (selectedRuneCharm[selectedCharmsClass] != null && selectedRuneCharm[selectedCharmsClass].name === rune.name && !isTabSelected) {
            cell.children[0].classList.remove('selected');
            rune.selected = false;
            selectedRuneCharm[selectedCharmsClass] = null;
            disableUnlockButton();
        } else {
            if (selectedRuneCharm[selectedCharmsClass] != null) {
                cleanSelectedCharmRune();
            }
            cell.children[0].classList.add('selected');
            rune.selected = true;
            selectedRuneCharm[selectedCharmsClass] = rune;
            enableUnlockButton();
        }
        setSelectedCharmRuneData(selectedRuneCharm[selectedCharmsClass]);
    }

    var setSelectedCharmRuneData = (rune) => {
        if (rune == null) {
            cleanSelectedCharmRuneData();
        } else {
            document.getElementById('selected-charm-rune-img').src = rune.image;
            document.getElementById('selected-charm-rune-name').innerHTML = rune.name;
            document.getElementById('selected-charm-rune-description').innerHTML = rune.description;
            document.getElementById('selected-charm-rune-effect').innerHTML = rune.effect;
            document.getElementById('selected-charm-rune-unlock').innerHTML = rune.points.level_one + ' charm points';
            document.getElementById('selected-charm-rune-nivel-two').innerHTML = rune.points.level_two + ' charm points';
            document.getElementById('selected-charm-rune-nivel-three').innerHTML = rune.points.level_three + ' charm points';
            document.getElementById('selected-charm-rune-unlock-all').innerHTML = (Number(rune.points.level_one.replace(',', '')) + Number(rune.points.level_two.replace(',', '')) + Number(rune.points.level_three.replace(',', ''))).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + ' charm points';
        }
        setSelectedRuneLevelImageBorder();
    }

    var setSelectedRuneLevelImageBorder = () => {
        let slot = document.getElementById('selected-charm-rune-img-slot')
        slot.classList.remove('unlocked_one');
        slot.classList.remove('unlocked_two');
        slot.classList.remove('unlocked_three');
        document.getElementById('selected-charm-rune-attribute').innerHTML = "";
        document.getElementById('selected-charm-rune-level').innerHTML = "-";
        let rune = selectedRuneCharm[selectedCharmsClass];
        if (rune != null && rune.unlocked != null) {
            document.getElementById('selected-charm-rune-level').innerHTML = rune.unlocked;
            let classe = "unlocked_one";
            let attrib = "level_one";
            if (rune.unlocked === 2) {
                classe = "unlocked_two";
                attrib = "level_two";
            }
            if (rune.unlocked === 3) {
                classe = "unlocked_three";
                attrib = "level_three";
            }
            slot.classList.add(classe);
            document.getElementById('selected-charm-rune-attribute').innerHTML = rune.percents[attrib] + "%";
        }
    }

    var setRemoveCreaturePrice = () => {
        let price = Number(document.getElementById("input-level").value) * 100;
        let value = (document.getElementById('checkbox-charm-expansion').checked) ? (price - (price * 0.25)) : price;

        document.getElementById('remove-creature-price').innerHTML = (value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, "."));
    }

    var cleanSelectedCharmRuneData = () => {
        document.getElementById('selected-charm-rune-img').src = "https://www.tibiawiki.com.br/images/3/35/Trans.gif";
        document.getElementById('selected-charm-rune-name').innerHTML = "";
        document.getElementById('selected-charm-rune-description').innerHTML = "";
        document.getElementById('selected-charm-rune-effect').innerHTML = "";
        document.getElementById('selected-charm-rune-unlock').innerHTML = "";
        document.getElementById('selected-charm-rune-nivel-two').innerHTML = "";
        document.getElementById('selected-charm-rune-nivel-three').innerHTML = "";
        document.getElementById('selected-charm-rune-unlock-all').innerHTML = "";
        document.getElementById('selected-charm-rune-attribute').innerHTML = "";
    }

    var selecTab = (tab) => {
        if (tab.id === selectedTab) {
            return
        }
        selectedTab = tab.id;
        let index = Number(tab.id.replace('tab-index-', ''));
        tab.classList.remove('unselected');
        tab.classList.add('selected');

        let id = 'tab-index-' + ((index === 0) ? 1 : 0).toString();
        document.getElementById(id).classList.remove('selected');
        document.getElementById(id).classList.add('unselected');

        selectedCharmsClass = Object.keys(charms)[index];
        populateTable();

        if (selectedRuneCharm[selectedCharmsClass] == null) {
            cleanSelectedCharmRuneData();
            disableUnlockButton();
            return
        }
        let cell = document.getElementsByName(selectedRuneCharm[selectedCharmsClass].name);
        if (cell.length === 1) {
            selectRune(cell[0], selectedRuneCharm[selectedCharmsClass], true);
        }
    }

    var unlockRunes = () => {
        let rune = selectedRuneCharm[selectedCharmsClass];
        if (rune.unlocked == null) {
            charmPoints[selectedCharmsClass].used += Number(rune.points.level_one.replace(',', ''));
            rune.unlocked = 1;
            if (selectedCharmsClass === 'major_charms') {
                setMinorCharmPoints(charmPoints["minor_charms"].max + 50);
            }
        } else {
            charmPoints[selectedCharmsClass].used += Number(rune.points[(rune.unlocked === 1) ? "level_two": "level_three"].replace(',', ''))
            if (selectedCharmsClass === 'major_charms') {
                setMinorCharmPoints(charmPoints["minor_charms"].max + ((rune.unlocked === 1) ? 100 : 200));
            }
            rune.unlocked = (rune.unlocked === 3) ? rune.unlocked : (rune.unlocked + 1);
        }
        updateLabelCharmPoints(selectedCharmsClass);

        (rune.unlocked === 3) ? disableUnlockButton() : enableUnlockButton();

        let cell = document.getElementsByName(selectedRuneCharm[selectedCharmsClass].name);
        if (cell.length === 1) {
            cell[0].classList.remove('unlocked_one');
            cell[0].classList.remove('unlocked_two');
            cell[0].classList.remove('unlocked_three');

            let level = "one";
            if (rune.unlocked === 2) {
                level = "two";
            }
            if (rune.unlocked === 3) {
                level = "three";
            }
            cell[0].classList.add('unlocked_' + level);
        } 
        setSelectedRuneLevelImageBorder();
        saveUnlockedRunes();
    }



    var disableUnlockButton = (withoutPoints) => {
        let button = document.getElementById('btn-unlock');
        button.disabled = true;
        button.classList.remove('btn-red');
        button.classList.add('btn-disabled');
        if (withoutPoints) {
            button.innerHTML = "sem pontos o suficiente"
        } else {
            button.innerHTML = (selectedRuneCharm[selectedCharmsClass] == null) ? "selecione uma runa" : "runa nível máximo";
        }
    }

    var enableUnlockButton = () => {
        let rune = selectedRuneCharm[selectedCharmsClass];
        if (rune == null) {
            return
        }
        let max = charmPoints[selectedCharmsClass].max;
        let used = charmPoints[selectedCharmsClass].used;
        
        let level = "";
        if (rune.unlocked == null) {
            level = "level_one";
        }
        if (rune.unlocked != null && rune.unlocked === 1) {
            level = "level_two";
        }
        if (rune.unlocked != null && rune.unlocked === 2) {
            level = "level_three";
        }
        let rPoints = rune.points[level];
        let points = (rPoints != null) ? Number(rPoints.replace(',', '')) : 0;
        if (points > max || points > (max - used)) {
            disableUnlockButton(true);
            return
        }

        let button = document.getElementById('btn-unlock');
        button.disabled = false;
        button.classList.add('btn-red');
        button.classList.remove('btn-disabled');

        if (rune.unlocked === 3) {
            disableUnlockButton();
            return
        }
        let title = "desbloquear runa - " + rune.points.level_one;
        if (rune != null && rune.unlocked != null && rune.unlocked === 1) {
            title = "desbloquear nível 2 - " + rune.points.level_two;
        }
        if (rune != null && rune.unlocked != null && rune.unlocked === 2) {
            title = "desbloquear nível 3 - " + rune.points.level_three;
        }
        button.innerHTML = title + ' <img src="' + charmsIcons[selectedCharmsClass] + '">';
    }

    var resetAllRunes = (action, classe) => {
        if (action === "removedPoints" ) {
            (classe === 'major_charms') ? resetAllMajorRunes() : resetAllMinorRunes();
        } else {
            resetAllMajorRunes();
        }
        saveUnlockedRunes();
    }

    var resetAllMinorRunes = () => {
        charms.minor_charms.forEach(rune => {
            rune.unlocked = null;
        });
        populateTable();
        setSelectedRuneLevelImageBorder();

        charmPoints.minor_charms.used = 0;

        if (selectedCharmsClass === 'minor_charms') {
            let cell = document.getElementsByName(selectedRuneCharm[selectedCharmsClass].name);
            if (cell.length === 1) {
                selectRune(cell[0], selectedRuneCharm[selectedCharmsClass], true);
            }
        }
        setUsedMinorCharmPoints();
    }

    var resetAllMajorRunes = () => {
        Object.keys(charms).forEach(key => {
            
            charms[key].forEach(rune => {
                rune.unlocked = null;
            });
        });
        populateTable();
        setSelectedRuneLevelImageBorder();

        charmPoints.major_charms.max = 0
        charmPoints.major_charms.used = 0;
        charmPoints.minor_charms.max = 0;
        charmPoints.minor_charms.used = 0;
        setMajorCharmPoints(document.getElementById('input-charm-points').value);
        setPromotionMinorCharms(document.getElementById('checkbox-promotion'));

        let sRuneCharm = selectedRuneCharm[selectedCharmsClass];
        if (sRuneCharm != null) {
            let cell = document.getElementsByName(sRuneCharm.name);
            if (cell.length === 1) {
                selectRune(cell[0], selectedRuneCharm[selectedCharmsClass], true);
            }
        }
    }


    var loadCharms = async () => {
        let baseURL = '';
        $('.loading label').text('Buscando Charms e Runes para Você, Aventureiro!... Os Deuses nos abençoarão com o conhecimento divino!');
        await Promise.all([requestCharmsData(baseURL, 'Charms', 'charms')]).then((result) => {
            console.log('Charms Carregados!! Os deuses nos abençoaram!');

            let savedRunes = getSavedUnlockedRunes();
            if (savedRunes != null) {
                charmPoints = savedRunes.charm_points;
                document.getElementById('input-charm-points').value = charmPoints.major_charms.max;
                setMajorCharmPoints(charmPoints.major_charms.max);
                setMinorCharmPoints(charmPoints.minor_charms.max);
                setUsedMajorCharmPoints();
                setUsedMinorCharmPoints();

                // Level
                document.getElementById('input-level').value = savedRunes.level ?? 8;

                // Promotion
                document.getElementById('checkbox-promotion').checked = savedRunes.promotion;

                // Charm Expansion
                document.getElementById('checkbox-charm-expansion').checked = savedRunes.charm_expansion;

                updateUnlockedRunesOnStart(savedRunes.major_charms, 'major_charms');
                updateUnlockedRunesOnStart(savedRunes.minor_charms, 'minor_charms')
                
                
            } else {
                setMajorCharmPoints(100);
                setPromotionMinorCharms(document.getElementById('checkbox-promotion'));
            }
            resetAllCharmsCalc(document.getElementById('input-level'));
            cleanSelectedCharmRuneData();
            selecTab(document.getElementById('tab-index-0'));
            $('.loading')[0].style.display = 'none';
        });
    }

    var updateUnlockedRunesOnStart = (runes, classCharm) => {
        if (runes.length > 0) {
            runes.forEach(rune => {
                let fRune = charms[classCharm].find(charm => charm.name === rune.name);
                if (fRune != null) {
                    fRune['unlocked'] = rune.unlocked;
                }
            });
        }    
    }

    var requestCharmsData = async (baseURL, path, varName) => {
        return new Promise((resolve, reject) => {
            $.ajax({
                contentType: 'text/plain; charset=utf-8',
                url: baseURL.concat('/index.php?title=Tibia_Wiki:').concat(path).concat('/json&action=raw'),
                type: 'GET',
                success: function (data) {
                    callback(data.replace(/<pre id="[^"]*">/gi, '').replace(/<\/pre>/gi, ''), varName);
                    resolve('Loaded: ' + varName);
                },
                error: function (error) {
                    console.error(error);
                    callback(null, varName);
                }
            });
        });
    }
   
    var callback = (codigo, varName) => {
        if (codigo == null) {
            showErrorMessage();
        } else {
            try {
                let objJson = JSON.parse(codigo);
                if (objJson != null) {
                    window[varName] = objJson;
                } else {
                    showErrorMessage();
                }
            } catch (err) {
                console.error(err);
                showErrorMessage();
            }
        }
    }

    var showErrorMessage = () => {
        $('.loading label').text('Conseguimos invocar a furia dos deuses e não fomos abençoados com sua sabedoria e benevolência, Aventureiro! Redima-se carregando a página novamente!');
    }

    var selectedRuneCharm = {
        major_charms: null,
        minor_charms: null
    };
    var charmPoints = {
        major_charms: {
            used: 0,
            max: 0
        },
        minor_charms: {
            used: 0,
            max: 0
        }
    }
    var charmsIcons = {
        major_charms: "https://www.tibiawiki.com.br/images/b/b2/Icon_Major_Charm_Points.png",
        minor_charms: "https://www.tibiawiki.com.br/images/6/65/Icon_Minor_Charm_Points.png"
    }
    var selectedCharmsClass;
    var selectedTab;


    /* Remember Unlocked Runes s*/
    const savedUnlockedRunesKey = "tw-unlocked-runes";
    var saveUnlockedRunes = () => {
        let majorRunes = charms.major_charms.filter(rune => rune.unlocked != null);
        let minorRunes = charms.minor_charms.filter(rune => rune.unlocked != null);
        let data = JSON.stringify({ 
            "major_charms": majorRunes, 
            "minor_charms": minorRunes,
            "charm_points": charmPoints,
            "level": document.getElementById('input-level').value,
            "promotion": document.getElementById('checkbox-promotion').checked,
            "charm_expansion": document.getElementById('checkbox-charm-expansion').checked
        });
        localStorage.setItem(savedUnlockedRunesKey, data);
    }

    var getSavedUnlockedRunes = () => {
        const data = localStorage.getItem(savedUnlockedRunesKey);
        if (data != null && data.length > 0) {
            let runes = JSON.parse(data);
            return runes;
        }
        return null;
    }

    var deleteSavedUnlockedRunes = () => {
        localStorage.removeItem(savedUnlockedRunesKey);
    }

    $(document).ready(function () {
        loadCharms();

        /* Fix Browsers*/
        const style = document.createElement('style');

        /* Fix cells on Opera */
        if (navigator.userAgent.includes('OPR') || navigator.userAgent.includes('Opera')) {
            style.innerHTML = `tw-table-cell tw-cell-bg { display: block; width: 90px; height: 90px; margin-left: 6px; margin-top: 0px; border: 1px solid black; border-radius: 5px; }`;
        }
        /* Fix cells on Firefox */
        if (navigator.userAgent.includes('Firefox')) {
            style.innerHTML = `tw-table-cell tw-cell-bg { display: block; width: 90px; height: 90px; margin-left: 6px; margin-top: 13px; border: 1px solid black; border-radius: 5px; }`;
        }
        /* Fix cells on Chrome */
        if (navigator.userAgent.includes('Chrome') && !navigator.userAgent.includes('OPR')) {
            style.innerHTML = `tw-table-cell tw-cell-bg { display: block; width: 90px; height: 90px; margin-left: 6px; margin-top: 0px; border: 1px solid black; border-radius: 5px; }`;
        }
        /* Fix cells on Safari */
        if (navigator.userAgent.includes('Safari') && !navigator.userAgent.includes('OPR') && !navigator.userAgent.includes('Chrome') && !navigator.userAgent.includes('Firefox')) {
            style.innerHTML = `tw-tabs-panel tw-tabs tw-tab { padding-top: 5px; align-content: center; text-align: center; border-left: 1px solid black; border-right: 1px solid black; font-weight: bold; }
            tw-img-slot img { margin-top: 5px; width: 80%; height: 80%; }
            tw-table-cell tw-cell-bg { display: block; width: 90px; height: 90px; margin-left: 6px; border: 1px solid black; border-radius: 5px; margin-top: 13px;}`;
        }
        document.head.appendChild(style);
    });