<commit_before>me.sellStates = { BUYING: 0, SELLSELECT: 1, SELLING: 2, READING: 3 };
me.sellTypes = {
    CROPS: "", CROPSIDX: 1, 
    EQUIPMENT: "!", EQUIPIDX: 2, 
    FIXTURES: "_", FIXIDX: 3
};
worldmap.shop = {
    details: null, cursorX: 0, cursorY: 0, 
    initx: 1, dx: 2, yPos: 7, cursorInitx: 0,
    sellingState: me.sellStates.BUYING, sellingType: me.sellTypes.CROPS, actualIdxs: [],
    maxSell: 12, sellOffset: 0, numArrows: 0, isUpgradeShop: false,
    bookReading: null, bookState: -1,
    layersToClear: ["characters", "menutext", "menuA"],
    availableIndexes: [], hasTalk: "", isQuestTalk: true, 
    sleepsyData: null, howManyData: null, 
    blinkIdx: -1, blinkState: 0, 
    setup: function(shopName) {
        this.details = stores[shopName];
        this.sellingState = me.sellStates.BUYING;
        this.sellingType = me.sellTypes.CROPS;
        this.hasTalk = (this.details.talk && player.questsCleared.indexOf(this.details.talk) < 0) ? this.details.talk : "";
        if(this.details.benignTalk && this.hasTalk === "") {
            this.isQuestTalk = false;
            this.hasTalk = this.details.benignTalk;
        } else { this.isQuestTalk = true; }
        this.sellOffset = 0;
        this.numArrows = 0;
        this.bookReading = null;
        this.bookState = -1;
        this.sleepsyData = null;
        this.howManyData = null;
        if(this.details.wares.length > 6 || (this.details.doesSell && this.details.wares.length > 5)) {
            this.dx = 1;
            this.initx = (this.hasTalk || this.details.doesSell) ? 3 : 2;
        } else {
            this.dx = 2;
            this.initx = (this.hasTalk || this.details.doesSell) ? 5 : 3;
        }
        this.cursorInitx = (this.hasTalk || this.details.doesSell) ? 2 : 1;
        this.cursorX = 0;
        this.cursors = new CursorAnimSet([
            { key: "main", x: this.cursorX, y: this.yPos, w: 0, h: 0, type: "cursor", layer: "menucursorA" }
        ]);
        gfx.drawFullImage(this.details.img);
        this.DrawDetails(GetText(this.details.opening), true);
        this.cursors.Start();
        this.blinkIdx = setInterval(this.Blinking, 50);
        this.blinkState = 0;
    },
    Blinking: function() {
        const blinkProb = (worldmap.shop.details.rapid ? 0.3 : 0.98);
        const blinkH = worldmap.shop.details.huge ? 416 : (worldmap.shop.details.big ? 300 : 100);
        const blinkW = worldmap.shop.details.huge ? 528 : 200;
        if(worldmap.shop.blinkState === -1 || (worldmap.shop.blinkState === 0 && Math.random() >= blinkProb)) {
            worldmap.shop.blinkState = 1;
            gfx.drawImage(gfx.ctx["foreground"], gfx.spritesheets[worldmap.shop.details.eyes], 0, 0, blinkW, blinkH, worldmap.shop.details.ex, worldmap.shop.details.ey, blinkW, blinkH);
        } else {
            if(worldmap.shop.blinkState > 2 || (worldmap.shop.blinkState * Math.random()) > 0.45) {
                gfx.clearLayer("foreground");
                worldmap.shop.blinkState = Math.random() < 0.15 ? -1 : 0;
            }
        }
    },
    resetTalk: function() {
        this.hasTalk = "";
        if(this.details.doesSell) { return; }
        if(this.details.wares.length > 6 || (this.details.doesSell && this.details.wares.length > 5)) {
            this.initx = 2;
        } else {
            this.initx = 3;
        }
        this.cursorInitx = 1;
    },
    DrawDetails: function(text, isopening) {
        gfx.clearSome(this.layersToClear);
        switch(this.sellingState) {
            case me.sellStates.SELLING: this.DrawDetailsSelling(); break;
            case me.sellStates.SELLSELECT: this.DrawDetailsSellingSelect(); break;
            case me.sellStates.READING:
            case me.sellStates.BUYING: this.DrawDetailsBuying(); break;
        }
        if(this.isUpgradeShop && this.availableIndexes.length === 0 && isopening) { text = GetText(this.details.empty); }
        gfx.drawText(GetText("s.coins").replace(/\{0\}/g, player.monies), 2, 16 * 9.25 + 1.5, gfx.GetWhite());
        if(text === undefined) {
            if(this.sellingState === me.sellStates.BUYING) { this.DrawText(); }
        } else {
            speaker.Fresh();
            speaker.SayThing(text, "dialog");
            this.WriteWrappedText(text);
        }
    },
    WriteWrappedText: function(text, y) {
        y = y || 159; // 16 * 10 - 1
        gfx.drawWrappedText(text, 4, y, 250, gfx.GetWhite());
    },
    isValidSellIdx: function(i) {
        if(this.sellingType === me.sellTypes.CROPS) {
            if(player.inventory[i][0][0] === me.sellTypes.FIXTURES || player.inventory[i][0][0] === me.sellTypes.EQUIPMENT) {
                return false;
            }
        } else if(player.inventory[i][0][0] !== this.sellingType) {
            return false;
        }
        if(this.sellingType === me.sellTypes.EQUIPMENT && player.isEquipped(player.inventory[i][0])) { return false; }
        return true;
    },
    getNthMatchingIdx: function(n) {
        if(n === 0) { return 0; }
        let j = -1;
        for(let i = 0; i < player.inventory.length; i++) {
            if(!this.isValidSellIdx(i)) { continue; }
            if(++j === n) { return i; }
        }
        return 0;
    },
    DrawDetailsSelling: function() {
        let j = 0;
        this.actualIdxs = [];
        this.numArrows = 0;
        const max = this.maxSell;
        if(this.sellOffset > 0) {
            this.numArrows += 1;
            gfx.drawTileToGrid("arrowL", 1, this.yPos, "characters");
        } else {
            gfx.drawTileToGrid("exit", 1, this.yPos, "characters");
        }
        let addArrow = false, lastIdx = 0;
        for(let i = this.getNthMatchingIdx(this.sellOffset); i < player.inventory.length; i++) {
            if(!this.isValidSellIdx(i)) { continue; }
            if((j + 1) === max) {
                addArrow = true;
                lastIdx = i;
                break;
            }
            gfx.drawInventoryItem(player.inventory[i], 2 + j, this.yPos, "characters");
            this.actualIdxs.push(i);
            j++;
        }
        if(addArrow) {
            let isLastItem = true;
            for(let i = lastIdx + 1; i < player.inventory.length; i++) {
                if(this.isValidSellIdx(i)) { isLastItem = false; break; }
            }
            if(isLastItem) {
                gfx.drawInventoryItem(player.inventory[lastIdx], 2 + (this.maxSell - 1), this.yPos, "characters");
                this.actualIdxs.push(lastIdx);
            } else {
                gfx.drawTileToGrid("arrowR", 2 + (this.maxSell - 1), this.yPos, "characters");
                this.numArrows += 2;
            }
        }
        this.cursors.RedimCursor("main", 1 + this.cursorX, this.yPos, 0, 0);
    },
    DrawDetailsSellingSelect: function() {
        gfx.drawTileToGrid("exit", 4, this.yPos, "characters");
        gfx.drawTileToGrid("seeds", 6, this.yPos, "characters");
        gfx.drawTileToGrid("tools", 8, this.yPos, "characters");
        gfx.drawTileToGrid("fixtures", 10, this.yPos, "characters");
        this.cursors.RedimCursor("main", 4 + this.cursorX * 2, this.yPos, 0, 0);
    },
    DrawDetailsBuying: function() {
        gfx.drawTileToGrid("exit", 1, this.yPos, "characters");
        if(this.hasTalk) {
            const talkTile = (this.isQuestTalk ? "helpBox" : "talk");
            gfx.drawTileToGrid(talkTile, (this.details.doesSell ? 2 : 1) + this.dx, this.yPos, "characters");
        } else if(this.details.doesSell) {
            gfx.drawTileToGrid("sell", 1 + this.dx, this.yPos, "characters");
        }
        this.availableIndexes = []; let j = 0;
        this.isUpgradeShop = false;
        let widecursor = false;
        for(let i = 0; i < this.details.wares.length; i++) {
            if(this.details.wares[i].type === "upgrade") {
                this.isUpgradeShop = true;
                const res = sprites[this.details.wares[i].product + "-" + player.gridLevel];
                if(res === undefined) { continue; }
                this.availableIndexes.push(i);
                gfx.drawTileToGrid(this.details.wares[i].product + "-" + player.gridLevel, this.initx + j * this.dx, this.yPos, "characters");
                j++;
            } else {
                if(this.details.wares[i].locked !== undefined && player.questsCleared.indexOf(this.details.wares[i].locked) < 0) { continue; }
                this.availableIndexes.push(i);
                if(this.details.wares[i].type === "equipment") {
                    gfx.drawTileToGrid(this.details.wares[i].product, this.initx + j * this.dx, this.yPos, "characters");
                } else if(this.bookState >= 0 && (this.cursorX - 1) === i) {
                    gfx.drawTileToGrid("bookOpenL", this.initx + j * this.dx - 0.5, this.yPos, "characters");
                    gfx.drawTileToGrid("bookOpenR", this.initx + j * this.dx + 0.5, this.yPos, "characters");
                    widecursor = true;
                    this.cursors.RedimCursor("main", 0.75 + this.cursorX * this.dx, this.yPos, 0.5, 0);
                } else {
                    gfx.drawTileToGrid(this.details.wares[i].product, this.initx + j * this.dx, this.yPos, "characters");
                }
                j++;
            }
        }
        if(!widecursor) { this.cursors.RedimCursor("main", 1 + this.cursorX * this.dx, this.yPos, 0, 0); }
    },
    CursorMove: function(pos) {
        switch(this.sellingState) {
            case me.sellStates.SELLING: return this.MoveSelling(pos);
            case me.sellStates.SELLSELECT: return this.MoveSellSelect(pos);
            case me.sellStates.BUYING: return this.MoveBuying(pos);
        }
    },
    MoveSelling: function(pos) {
        const newCursorX = pos.x - 1;
        if(newCursorX < 0) { return false; }
        if((this.numArrows & 2) === 2) {
            if(newCursorX > (this.actualIdxs.length + 1)) { return false; }
        } else {
            if(newCursorX > this.actualIdxs.length) { return false; }
        }
        this.cursorX = newCursorX;
        let text = "hi im craig";<commit_msg>book fix<commit_after>me.sellStates = { BUYING: 0, SELLSELECT: 1, SELLING: 2, READING: 3 };
me.sellTypes = {
    CROPS: "", CROPSIDX: 1, 
    EQUIPMENT: "!", EQUIPIDX: 2, 
    FIXTURES: "_", FIXIDX: 3
};
worldmap.shop = {
    details: null, cursorX: 0, cursorY: 0, 
    initx: 1, dx: 2, yPos: 7, cursorInitx: 0,
    sellingState: me.sellStates.BUYING, sellingType: me.sellTypes.CROPS, actualIdxs: [],
    maxSell: 12, sellOffset: 0, numArrows: 0, isUpgradeShop: false,
    bookReading: null, bookState: -1,
    layersToClear: ["characters", "menutext", "menuA"],
    availableIndexes: [], hasTalk: "", isQuestTalk: true, 
    sleepsyData: null, howManyData: null, 
    blinkIdx: -1, blinkState: 0, 
    setup: function(shopName) {
        this.details = stores[shopName];
        this.sellingState = me.sellStates.BUYING;
        this.sellingType = me.sellTypes.CROPS;
        this.hasTalk = (this.details.talk && player.questsCleared.indexOf(this.details.talk) < 0) ? this.details.talk : "";
        if(this.details.benignTalk && this.hasTalk === "") {
            this.isQuestTalk = false;
            this.hasTalk = this.details.benignTalk;
        } else { this.isQuestTalk = true; }
        this.sellOffset = 0;
        this.numArrows = 0;
        this.bookReading = null;
        this.bookState = -1;
        this.sleepsyData = null;
        this.howManyData = null;
        if(this.details.wares.length > 6 || (this.details.doesSell && this.details.wares.length > 5)) {
            this.dx = 1;
            this.initx = (this.hasTalk || this.details.doesSell) ? 3 : 2;
        } else {
            this.dx = 2;
            this.initx = (this.hasTalk || this.details.doesSell) ? 5 : 3;
        }
        this.cursorInitx = (this.hasTalk || this.details.doesSell) ? 2 : 1;
        this.cursorX = 0;
        this.cursors = new CursorAnimSet([
            { key: "main", x: this.cursorX, y: this.yPos, w: 0, h: 0, type: "cursor", layer: "menucursorA" }
        ]);
        gfx.drawFullImage(this.details.img);
        this.DrawDetails(GetText(this.details.opening), true);
        this.cursors.Start();
        this.blinkIdx = setInterval(this.Blinking, 50);
        this.blinkState = 0;
    },
    Blinking: function() {
        const blinkProb = (worldmap.shop.details.rapid ? 0.3 : 0.98);
        const blinkH = worldmap.shop.details.huge ? 416 : (worldmap.shop.details.big ? 300 : 100);
        const blinkW = worldmap.shop.details.huge ? 528 : 200;
        if(worldmap.shop.blinkState === -1 || (worldmap.shop.blinkState === 0 && Math.random() >= blinkProb)) {
            worldmap.shop.blinkState = 1;
            gfx.drawImage(gfx.ctx["foreground"], gfx.spritesheets[worldmap.shop.details.eyes], 0, 0, blinkW, blinkH, worldmap.shop.details.ex, worldmap.shop.details.ey, blinkW, blinkH);
        } else {
            if(worldmap.shop.blinkState > 2 || (worldmap.shop.blinkState * Math.random()) > 0.45) {
                gfx.clearLayer("foreground");
                worldmap.shop.blinkState = Math.random() < 0.15 ? -1 : 0;
            }
        }
    },
    resetTalk: function() {
        this.hasTalk = "";
        if(this.details.doesSell) { return; }
        if(this.details.wares.length > 6 || (this.details.doesSell && this.details.wares.length > 5)) {
            this.initx = 2;
        } else {
            this.initx = 3;
        }
        this.cursorInitx = 1;
    },
    DrawDetails: function(text, isopening) {
        gfx.clearSome(this.layersToClear);
        switch(this.sellingState) {
            case me.sellStates.SELLING: this.DrawDetailsSelling(); break;
            case me.sellStates.SELLSELECT: this.DrawDetailsSellingSelect(); break;
            case me.sellStates.READING:
            case me.sellStates.BUYING: this.DrawDetailsBuying(); break;
        }
        if(this.isUpgradeShop && this.availableIndexes.length === 0 && isopening) { text = GetText(this.details.empty); }
        gfx.drawText(GetText("s.coins").replace(/\{0\}/g, player.monies), 2, 16 * 9.25 + 1.5, gfx.GetWhite());
        if(text === undefined) {
            if(this.sellingState === me.sellStates.BUYING) { this.DrawText(); }
        } else {
            speaker.Fresh();
            speaker.SayThing(text, "dialog");
            this.WriteWrappedText(text);
        }
    },
    WriteWrappedText: function(text, y) {
        y = y || 159; // 16 * 10 - 1
        gfx.drawWrappedText(text, 4, y, 250, gfx.GetWhite());
    },
    isValidSellIdx: function(i) {
        if(this.sellingType === me.sellTypes.CROPS) {
            if(player.inventory[i][0][0] === me.sellTypes.FIXTURES || player.inventory[i][0][0] === me.sellTypes.EQUIPMENT) {
                return false;
            }
        } else if(player.inventory[i][0][0] !== this.sellingType) {
            return false;
        }
        if(this.sellingType === me.sellTypes.EQUIPMENT && player.isEquipped(player.inventory[i][0])) { return false; }
        return true;
    },
    getNthMatchingIdx: function(n) {
        if(n === 0) { return 0; }
        let j = -1;
        for(let i = 0; i < player.inventory.length; i++) {
            if(!this.isValidSellIdx(i)) { continue; }
            if(++j === n) { return i; }
        }
        return 0;
    },
    DrawDetailsSelling: function() {
        let j = 0;
        this.actualIdxs = [];
        this.numArrows = 0;
        const max = this.maxSell;
        if(this.sellOffset > 0) {
            this.numArrows += 1;
            gfx.drawTileToGrid("arrowL", 1, this.yPos, "characters");
        } else {
            gfx.drawTileToGrid("exit", 1, this.yPos, "characters");
        }
        let addArrow = false, lastIdx = 0;
        for(let i = this.getNthMatchingIdx(this.sellOffset); i < player.inventory.length; i++) {
            if(!this.isValidSellIdx(i)) { continue; }
            if((j + 1) === max) {
                addArrow = true;
                lastIdx = i;
                break;
            }
            gfx.drawInventoryItem(player.inventory[i], 2 + j, this.yPos, "characters");
            this.actualIdxs.push(i);
            j++;
        }
        if(addArrow) {
            let isLastItem = true;
            for(let i = lastIdx + 1; i < player.inventory.length; i++) {
                if(this.isValidSellIdx(i)) { isLastItem = false; break; }
            }
            if(isLastItem) {
                gfx.drawInventoryItem(player.inventory[lastIdx], 2 + (this.maxSell - 1), this.yPos, "characters");
                this.actualIdxs.push(lastIdx);
            } else {
                gfx.drawTileToGrid("arrowR", 2 + (this.maxSell - 1), this.yPos, "characters");
                this.numArrows += 2;
            }
        }
        this.cursors.RedimCursor("main", 1 + this.cursorX, this.yPos, 0, 0);
    },
    DrawDetailsSellingSelect: function() {
        gfx.drawTileToGrid("exit", 4, this.yPos, "characters");
        gfx.drawTileToGrid("seeds", 6, this.yPos, "characters");
        gfx.drawTileToGrid("tools", 8, this.yPos, "characters");
        gfx.drawTileToGrid("fixtures", 10, this.yPos, "characters");
        this.cursors.RedimCursor("main", 4 + this.cursorX * 2, this.yPos, 0, 0);
    },
    DrawDetailsBuying: function() {
        gfx.drawTileToGrid("exit", 1, this.yPos, "characters");
        if(this.hasTalk) {
            const talkTile = (this.isQuestTalk ? "helpBox" : "talk");
            gfx.drawTileToGrid(talkTile, (this.details.doesSell ? 2 : 1) + this.dx, this.yPos, "characters");
        } else if(this.details.doesSell) {
            gfx.drawTileToGrid("sell", 1 + this.dx, this.yPos, "characters");
        }
        this.availableIndexes = []; let j = 0;
        this.isUpgradeShop = false;
        let widecursor = false;
        for(let i = 0; i < this.details.wares.length; i++) {
            if(this.details.wares[i].type === "upgrade") {
                this.isUpgradeShop = true;
                const res = sprites[this.details.wares[i].product + "-" + player.gridLevel];
                if(res === undefined) { continue; }
                this.availableIndexes.push(i);
                gfx.drawTileToGrid(this.details.wares[i].product + "-" + player.gridLevel, this.initx + j * this.dx, this.yPos, "characters");
                j++;
            } else {
                if(this.details.wares[i].locked !== undefined && player.questsCleared.indexOf(this.details.wares[i].locked) < 0) { continue; }
                this.availableIndexes.push(i);
                if(this.details.wares[i].type === "equipment") {
                    gfx.drawTileToGrid(this.details.wares[i].product, this.initx + j * this.dx, this.yPos, "characters");
                } else if(this.bookState >= 0 && (this.cursorX - (this.hasTalk ? 2 : 1)) === i) {
                    gfx.drawTileToGrid("bookOpenL", this.initx + j * this.dx - 0.5, this.yPos, "characters");
                    gfx.drawTileToGrid("bookOpenR", this.initx + j * this.dx + 0.5, this.yPos, "characters");
                    widecursor = true;
                    this.cursors.RedimCursor("main", 0.75 + this.cursorX * this.dx, this.yPos, 0.5, 0);
                } else {
                    gfx.drawTileToGrid(this.details.wares[i].product, this.initx + j * this.dx, this.yPos, "characters");
                }
                j++;
            }
        }
        if(!widecursor) { this.cursors.RedimCursor("main", 1 + this.cursorX * this.dx, this.yPos, 0, 0); }
    },
    CursorMove: function(pos) {
        switch(this.sellingState) {
            case me.sellStates.SELLING: return this.MoveSelling(pos);
            case me.sellStates.SELLSELECT: return this.MoveSellSelect(pos);
            case me.sellStates.BUYING: return this.MoveBuying(pos);
        }
    },
    MoveSelling: function(pos) {
        const newCursorX = pos.x - 1;
        if(newCursorX < 0) { return false; }
        if((this.numArrows & 2) === 2) {
            if(newCursorX > (this.actualIdxs.length + 1)) { return false; }
        } else {
            if(newCursorX > this.actualIdxs.length) { return false; }
        }
        this.cursorX = newCursorX;
        let text = "hi im craig";
{'fraction_non_alphanumeric': 0.15134251461408899, 'fraction_numerical': 0.01659566035866442, 'mean_word_length': 2.048014494941869, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2314565', 'n_tokens_mistral': 7084, 'n_tokens_neox': 6595, 'n_words': 1206}