diff --git a/src/data/layers/aca/a.tsx b/src/data/layers/aca/a.tsx
deleted file mode 100644
index a1642a5..0000000
--- a/src/data/layers/aca/a.tsx
+++ /dev/null
@@ -1,135 +0,0 @@
-import Row from "@/components/layout/Row.vue";
-import Tooltip from "@/components/Tooltip.vue";
-import { main } from "@/data/mod";
-import { createAchievement } from "@/features/achievements/achievement";
-import { jsx } from "@/features/feature";
-import { createGrid } from "@/features/grids/grid";
-import { createResource } from "@/features/resources/resource";
-import { createTreeNode } from "@/features/trees/tree";
-import { createLayer } from "@/game/layers";
-import { DecimalSource } from "@/lib/break_eternity";
-import Decimal from "@/util/bignum";
-import { render, renderRow } from "@/util/vue";
-import { computed } from "vue";
-import f from "./f";
-
-const layer = createLayer(() => {
-    const id = "a";
-    const color = "yellow";
-    const name = "Achievements";
-    const points = createResource<DecimalSource>(0, "achievement power");
-
-    const treeNode = createTreeNode(() => ({
-        display: "A",
-        color,
-        tooltip: {
-            display: "Achievements",
-            right: true
-        },
-        onClick() {
-            main.showAchievements();
-        }
-    }));
-
-    const ach1 = createAchievement(() => ({
-        image: "https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png",
-        display: "Get me!",
-        tooltip: computed(() => {
-            if (ach1.earned.value) {
-                return "You did it!";
-            }
-            return "How did this happen?";
-        }),
-        shouldEarn: true
-    }));
-    const ach2 = createAchievement(() => ({
-        display: "Impossible!",
-        tooltip: computed(() => {
-            if (ach2.earned.value) {
-                return "HOW????";
-            }
-            return "Mwahahaha!";
-        }),
-        style: { color: "#04e050" }
-    }));
-    const ach3 = createAchievement(() => ({
-        display: "EIEIO",
-        tooltip:
-            "Get a farm point.\n\nReward: The dinosaur is now your friend (you can max Farm Points).",
-        shouldEarn: function () {
-            return Decimal.gte(f.points.value, 1);
-        },
-        onComplete() {
-            console.log("Bork bork bork!");
-        }
-    }));
-    const achievements = [ach1, ach2, ach3];
-
-    const grid = createGrid(() => ({
-        rows: 2,
-        cols: 2,
-        getStartState(id) {
-            return id;
-        },
-        getStyle(id, state) {
-            return { backgroundColor: `#${(Number(state) * 1234) % 999999}` };
-        },
-        // TODO display should return an object
-        getTitle(id) {
-            let direction = "";
-            if (id === "101") {
-                direction = "top";
-            } else if (id === "102") {
-                direction = "bottom";
-            } else if (id === "201") {
-                direction = "left";
-            } else if (id === "202") {
-                direction = "right";
-            }
-            return jsx(() => (
-                <Tooltip display={JSON.stringify(this.cells[id].style)} {...{ [direction]: true }}>
-                    <h3>Gridable #{id}</h3>
-                </Tooltip>
-            ));
-        },
-        getDisplay(id, state) {
-            return String(state);
-        },
-        getCanClick() {
-            return Decimal.eq(main.points.value, 10);
-        },
-        onClick(id, state) {
-            this.cells[id].state = Number(state) + 1;
-        }
-    }));
-
-    const display = jsx(() => (
-        <>
-            <Row>
-                <Tooltip display={ach1.tooltip} bottom>
-                    {render(ach1)}
-                </Tooltip>
-                <Tooltip display={ach2.tooltip} bottom>
-                    {render(ach2)}
-                </Tooltip>
-                <Tooltip display={ach3.tooltip} bottom>
-                    {render(ach3)}
-                </Tooltip>
-            </Row>
-            {renderRow(grid)}
-        </>
-    ));
-
-    return {
-        id,
-        color,
-        name,
-        points,
-        achievements,
-        grid,
-        treeNode,
-        display
-    };
-});
-
-export default layer;
diff --git a/src/data/layers/aca/c.tsx b/src/data/layers/aca/c.tsx
deleted file mode 100644
index aab8664..0000000
--- a/src/data/layers/aca/c.tsx
+++ /dev/null
@@ -1,686 +0,0 @@
-import Slider from "@/components/fields/Slider.vue";
-import Text from "@/components/fields/Text.vue";
-import Toggle from "@/components/fields/Toggle.vue";
-import Column from "@/components/layout/Column.vue";
-import Row from "@/components/layout/Row.vue";
-import Spacer from "@/components/layout/Spacer.vue";
-import Sticky from "@/components/layout/Sticky.vue";
-import VerticalRule from "@/components/layout/VerticalRule.vue";
-import Modal from "@/components/Modal.vue";
-import { createLayerTreeNode, createResetButton } from "@/data/common";
-import { main } from "@/data/mod";
-import themes from "@/data/themes";
-import { createBar, Direction } from "@/features/bars/bar";
-import { createBuyable } from "@/features/buyable";
-import { createChallenge } from "@/features/challenges/challenge";
-import { createClickable } from "@/features/clickables/clickable";
-import {
-    addSoftcap,
-    createCumulativeConversion,
-    createExponentialScaling
-} from "@/features/conversion";
-import { jsx, showIf, Visibility } from "@/features/feature";
-import { createHotkey } from "@/features/hotkey";
-import { createInfobox } from "@/features/infoboxes/infobox";
-import { createMilestone } from "@/features/milestones/milestone";
-import { createReset } from "@/features/reset";
-import MainDisplay from "@/features/resources/MainDisplay.vue";
-import { createResource, displayResource, trackBest } from "@/features/resources/resource";
-import Resource from "@/features/resources/Resource.vue";
-import { createTab } from "@/features/tabs/tab";
-import { createTabFamily } from "@/features/tabs/tabFamily";
-import { createTree, createTreeNode, GenericTreeNode, TreeBranch } from "@/features/trees/tree";
-import { createUpgrade } from "@/features/upgrades/upgrade";
-import { createLayer } from "@/game/layers";
-import { persistent } from "@/game/persistence";
-import settings from "@/game/settings";
-import { DecimalSource } from "@/lib/break_eternity";
-import Decimal, { format, formatWhole } from "@/util/bignum";
-import { render, renderCol, renderRow } from "@/util/vue";
-import { computed, ComputedRef, ref } from "vue";
-import f from "./f";
-
-const layer = createLayer(() => {
-    const id = "c";
-    const color = "#4BDC13";
-    const name = "Candies";
-    const points = createResource<DecimalSource>(0, "lollipops");
-    const best = trackBest(points);
-    const beep = persistent<boolean>(false);
-    const thingy = persistent<string>("pointy");
-    const otherThingy = persistent<number>(10);
-    const spentOnBuyables = persistent(new Decimal(10));
-
-    const waffleBoost = computed(() => Decimal.pow(points.value, 0.2));
-    const icecreamCap = computed(() => Decimal.times(points.value, 10));
-
-    const coolInfo = createInfobox(() => ({
-        title: "Lore",
-        titleStyle: { color: "#FE0000" },
-        display: "DEEP LORE!",
-        bodyStyle: { backgroundColor: "#0000EE" },
-        color: "rgb(75, 220, 19)"
-    }));
-
-    const lollipopMilestone3 = createMilestone(() => ({
-        shouldEarn() {
-            return Decimal.gte(best.value, 3);
-        },
-        display: {
-            requirement: "3 Lollipops",
-            effectDisplay: "Unlock the next milestone"
-        }
-    }));
-    const lollipopMilestone4 = createMilestone(() => ({
-        visibility() {
-            return showIf(lollipopMilestone3.earned.value);
-        },
-        shouldEarn() {
-            return Decimal.gte(best.value, 4);
-        },
-        display: {
-            requirement: "4 Lollipops",
-            effectDisplay: "You can toggle beep and boop (which do nothing)",
-            optionsDisplay: jsx(() => (
-                <>
-                    <Toggle
-                        title="beep"
-                        onUpdate:modelValue={value => (beep.value = value)}
-                        modelValue={beep.value}
-                    />
-                    <Toggle
-                        title="boop"
-                        onUpdate:modelValue={value => (f.boop.value = value)}
-                        modelValue={f.boop.value}
-                    />
-                </>
-            ))
-        },
-        style() {
-            if (this.earned) {
-                return { backgroundColor: "#1111DD" };
-            }
-            return {};
-        }
-    }));
-    const lollipopMilestones = [lollipopMilestone3, lollipopMilestone4];
-
-    const funChallenge = createChallenge(() => ({
-        title: "Fun",
-        completionLimit: 3,
-        display() {
-            return {
-                description: `Makes the game 0% harder<br>${formatWhole(this.completions.value)}/${
-                    this.completionLimit
-                } completions`,
-                goal: "Have 20 points I guess",
-                reward: "Says hi",
-                effectDisplay: format(funEffect.value) + "x"
-            };
-        },
-        visibility() {
-            return showIf(Decimal.gt(best.value, 0));
-        },
-        goal: 20,
-        resource: main.points,
-        onComplete() {
-            console.log("hiii");
-        },
-        onEnter() {
-            main.points.value = 0;
-            main.best.value = main.points.value;
-            main.total.value = main.points.value;
-            console.log("So challenging");
-        },
-        onExit() {
-            console.log("Sweet freedom!");
-        },
-        style: {
-            height: "200px"
-        }
-    }));
-    const funEffect = computed(() => Decimal.add(points.value, 1).tetrate(0.02));
-
-    const generatorUpgrade = createUpgrade(() => ({
-        display: {
-            title: "Generator of Genericness",
-            description: "Gain 1 point every second"
-        },
-        cost: 1,
-        resource: points
-    }));
-    const lollipopMultiplierUpgrade = createUpgrade(() => ({
-        display: () => ({
-            description: "Point generation is faster based on your unspent Lollipops",
-            effectDisplay: `${format(lollipopMultiplierEffect.value)}x`
-        }),
-        cost: 1,
-        resource: points,
-        visibility: () => showIf(generatorUpgrade.bought.value)
-    }));
-    const lollipopMultiplierEffect = computed(() => {
-        let ret = Decimal.add(points.value, 1).pow(0.5);
-        if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000");
-        return ret;
-    });
-    const unlockIlluminatiUpgrade = createUpgrade(() => ({
-        visibility() {
-            return showIf(lollipopMultiplierUpgrade.bought.value);
-        },
-        canAfford() {
-            return Decimal.lt(main.points.value, 7);
-        },
-        onPurchase() {
-            main.points.value = Decimal.add(main.points.value, 7);
-        },
-        display:
-            "Only buyable with less than 7 points, and gives you 7 more. Unlocks a secret subtab.",
-        style() {
-            if (this.bought) {
-                return { backgroundColor: "#1111dd" };
-            }
-            if (!this.canAfford) {
-                return { backgroundColor: "#dd1111" };
-            }
-            return {};
-        }
-    }));
-    const quasiUpgrade = createUpgrade(() => ({
-        resource: createResource(exhancers.amount, "Exhancers", 0),
-        cost: 3,
-        display: {
-            title: "This upgrade doesn't exist",
-            description: "Or does it?"
-        }
-    }));
-    const upgrades = [generatorUpgrade, lollipopMultiplierUpgrade, unlockIlluminatiUpgrade];
-
-    const exhancers = createBuyable(() => ({
-        resource: points,
-        cost() {
-            let x = new Decimal(this.amount.value);
-            if (x.gte(25)) {
-                x = x.pow(2).div(25);
-            }
-            const cost = Decimal.pow(2, x.pow(1.5));
-            return cost.floor();
-        },
-        display() {
-            return {
-                title: "Exhancers",
-                description: `Adds ${format(
-                    thingEffect.value
-                )} things and multiplies stuff by ${format(stuffEffect.value)}.`
-            };
-        },
-        onPurchase(cost) {
-            spentOnBuyables.value = Decimal.add(spentOnBuyables.value, cost);
-        },
-        style: { height: "222px" },
-        purchaseLimit: 4
-    }));
-    // The following need redundant ComputedRef<Decimal> type annotations because otherwise the ts
-    // interpreter thinks exhancers are cyclically referenced
-    const thingEffect: ComputedRef<Decimal> = computed(() => {
-        if (Decimal.gte(exhancers.amount.value, 0)) {
-            return Decimal.pow(25, Decimal.pow(exhancers.amount.value, 1.1));
-        }
-        return Decimal.pow(1 / 25, Decimal.times(exhancers.amount.value, -1).pow(1.1));
-    });
-    const stuffEffect: ComputedRef<Decimal> = computed(() => {
-        if (Decimal.gte(exhancers.amount.value, 0)) {
-            return Decimal.pow(25, Decimal.pow(exhancers.amount.value, 1.1));
-        }
-        return Decimal.pow(1 / 25, Decimal.times(exhancers.amount.value, -1).pow(1.1));
-    });
-    const confirmRespec = persistent<boolean>(false);
-    const confirming = ref(false);
-    const respecBuyables = createClickable(() => ({
-        small: true,
-        display: "Respec Thingies",
-        onClick() {
-            if (confirmRespec.value && !confirming.value) {
-                confirming.value = true;
-                return;
-            }
-
-            points.value = Decimal.add(points.value, spentOnBuyables.value);
-            exhancers.amount.value = 0;
-            main.tree.reset(treeNode);
-        }
-    }));
-    const sellExhancer = createClickable(() => ({
-        small: true,
-        display: "Sell One",
-        onClick() {
-            if (Decimal.lte(exhancers.amount.value, 0)) {
-                return;
-            }
-            exhancers.amount.value = Decimal.sub(exhancers.amount.value, 1);
-            points.value = Decimal.add(points.value, exhancers.cost.value);
-            spentOnBuyables.value = Decimal.sub(spentOnBuyables.value, exhancers.cost.value);
-        }
-    }));
-    const buyablesDisplay = jsx(() => (
-        <Column>
-            <Row>
-                <Toggle
-                    title="Confirm"
-                    onUpdate:modelValue={value => (confirmRespec.value = value)}
-                    modelValue={confirmRespec.value}
-                />
-                {renderRow(respecBuyables)}
-            </Row>
-            {renderRow(exhancers)}
-            {renderRow(sellExhancer)}
-            <Modal
-                modelValue={confirming.value}
-                onUpdate:modelValue={value => (confirming.value = value)}
-                v-slots={{
-                    header: () => <h2>Confirm Respec</h2>,
-                    body: () => <>Are you sure? Respeccing these doesn't accomplish much</>,
-                    footer: () => (
-                        <div class="modal-default-footer">
-                            <div class="modal-default-flex-grow"></div>
-                            <button
-                                class="button modal-default-button"
-                                onClick={() => (confirming.value = false)}
-                            >
-                                Cancel
-                            </button>
-                            <button
-                                class="button modal-default-button danger"
-                                onClick={() => {
-                                    respecBuyables.onClick();
-                                    confirming.value = false;
-                                }}
-                            >
-                                Respec
-                            </button>
-                        </div>
-                    )
-                }}
-            />
-        </Column>
-    ));
-
-    const longBoi = createBar(() => ({
-        fillStyle: { backgroundColor: "#FFFFFF" },
-        baseStyle: { backgroundColor: "#696969" },
-        textStyle: { color: "#04e050" },
-        direction: Direction.Right,
-        width: 300,
-        height: 30,
-        progress() {
-            return Decimal.add(main.points.value, 1).log(10).div(10).toNumber();
-        },
-        display() {
-            return format(main.points.value) + " / 1e10 points";
-        }
-    }));
-    const tallBoi = createBar(() => ({
-        fillStyle: { backgroundColor: "#4BEC13" },
-        baseStyle: { backgroundColor: "#000000" },
-        textStyle: { textShadow: "0px 0px 2px #000000" },
-        borderStyle: { borderWidth: "7px" },
-        direction: Direction.Up,
-        width: 50,
-        height: 200,
-        progress() {
-            return Decimal.div(main.points.value, 100);
-        },
-        display() {
-            return formatWhole(Decimal.div(main.points.value, 1).min(100)) + "%";
-        }
-    }));
-    const flatBoi = createBar(() => ({
-        fillStyle: { backgroundColor: "#FE0102" },
-        baseStyle: { backgroundColor: "#222222" },
-        textStyle: { textShadow: "0px 0px 2px #000000" },
-        direction: Direction.Up,
-        width: 100,
-        height: 30,
-        progress() {
-            return Decimal.div(points.value, 50);
-        }
-    }));
-
-    const conversion = createCumulativeConversion(() => ({
-        scaling: addSoftcap(createExponentialScaling(10, 5, 0.5), 1e100, 0.5),
-        baseResource: main.points,
-        gainResource: points,
-        roundUpCost: true
-    }));
-
-    const reset = createReset(() => ({
-        thingsToReset: (): Record<string, unknown>[] => [layer]
-    }));
-
-    const hotkeys = [
-        createHotkey(() => ({
-            key: "c",
-            description: "reset for lollipops or whatever",
-            onPress() {
-                if (resetButton.canClick.value) {
-                    resetButton.onClick();
-                }
-            }
-        })),
-        createHotkey(() => ({
-            key: "ctrl+c",
-            description: "respec things",
-            onPress() {
-                respecBuyables.onClick();
-            }
-        }))
-    ];
-
-    const treeNode = createLayerTreeNode(() => ({
-        layerID: id,
-        color,
-        reset,
-        mark: "https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png",
-        tooltip() {
-            let tooltip = displayResource(points);
-            if (Decimal.gt(exhancers.amount.value, 0)) {
-                tooltip += `<br><i><br><br><br>${formatWhole(
-                    exhancers.amount.value
-                )} Exhancers</i>`;
-            }
-            return tooltip;
-        },
-        style: {
-            color: "#3325CC",
-            textDecoration: "underline"
-        }
-    }));
-
-    const resetButton = createResetButton(() => ({
-        conversion,
-        tree: main.tree,
-        treeNode,
-        style: {
-            color: "#AA66AA"
-        },
-        resetDescription: "Melt your points into "
-    }));
-
-    const g = createTreeNode(() => ({
-        display: "TH",
-        color: "#6d3678",
-        canClick() {
-            return Decimal.gte(main.points.value, 10);
-        },
-        tooltip: "Thanos your points",
-        onClick() {
-            main.points.value = Decimal.div(main.points.value, 2);
-            console.log("Thanos'd");
-        },
-        glowColor() {
-            if (Decimal.eq(exhancers.amount.value, 1)) {
-                return "orange";
-            }
-            return "";
-        }
-    }));
-    const h = createTreeNode(() => ({
-        display: "h",
-        color() {
-            return themes[settings.theme].variables["--locked"];
-        },
-        tooltip: {
-            display: computed(() => `Restore your points to ${format(otherThingy.value)}`),
-            right: true
-        },
-        canClick() {
-            return Decimal.lt(main.points.value, otherThingy.value);
-        },
-        onClick() {
-            main.points.value = otherThingy.value;
-        }
-    }));
-    const spook = createTreeNode(() => ({
-        visibility: Visibility.Hidden
-    }));
-    const tree = createTree(() => ({
-        nodes(): GenericTreeNode[][] {
-            return [
-                [f.treeNode, treeNode],
-                [g, spook, h]
-            ];
-        },
-        branches(): TreeBranch[] {
-            return [
-                {
-                    startNode: f.treeNode,
-                    endNode: treeNode,
-                    "stroke-width": "25px",
-                    stroke: "green",
-                    style: {
-                        filter: "blur(5px)"
-                    }
-                },
-                { startNode: treeNode, endNode: g },
-                { startNode: g, endNode: h }
-            ];
-        }
-    }));
-
-    const illuminatiTabs = createTabFamily(() => ({
-        tabs: {
-            first: {
-                tab: jsx(() => (
-                    <>
-                        {renderRow(...upgrades)}
-                        {renderRow(quasiUpgrade)}
-                        <div>confirmed</div>
-                    </>
-                )),
-                display: "first"
-            },
-            second: {
-                tab: f.display,
-                display: "second"
-            }
-        },
-        style: {
-            width: "660px",
-            backgroundColor: "brown",
-            "--background": "brown",
-            border: "solid white",
-            marginLeft: "auto",
-            marginRight: "auto"
-        }
-    }));
-
-    const tabs = createTabFamily(() => ({
-        tabs: {
-            mainTab: {
-                tab: createTab(() => ({
-                    display: jsx(() => (
-                        <>
-                            <MainDisplay
-                                resource={points}
-                                color={color}
-                                effectDisplay={`which are boosting waffles by ${format(
-                                    waffleBoost.value
-                                )} and increasing the Ice Cream cap by ${format(
-                                    icecreamCap.value
-                                )}`}
-                            />
-                            <Sticky>{render(resetButton)}</Sticky>
-                            <Resource resource={points} color={color} />
-                            <Spacer height="5px" />
-                            <button onClick={() => console.log("yeet")}>'HI'</button>
-                            <div>Name your points!</div>
-                            <Text
-                                modelValue={thingy.value}
-                                onUpdate:modelValue={value => (thingy.value = value)}
-                            />
-                            <Sticky style="color: red; font-size: 32px; font-family: Comic Sans MS;">
-                                I have {displayResource(main.points)} {thingy.value} points!
-                            </Sticky>
-                            <hr />
-                            {renderCol(...lollipopMilestones)}
-                            <Spacer />
-                            {renderRow(...upgrades)}
-                            {renderRow(quasiUpgrade)}
-                            {renderRow(funChallenge)}
-                        </>
-                    ))
-                })),
-                display: "main tab",
-                glowColor() {
-                    if (
-                        generatorUpgrade.canPurchase.value ||
-                        lollipopMultiplierUpgrade.canPurchase.value ||
-                        unlockIlluminatiUpgrade.canPurchase.value ||
-                        funChallenge.canComplete.value
-                    ) {
-                        return "blue";
-                    }
-                    return "";
-                },
-                style: { color: "orange" }
-            },
-            thingies: {
-                tab: createTab(() => ({
-                    style() {
-                        return { backgroundColor: "#222222", "--background": "#222222" };
-                    },
-                    display: jsx(() => (
-                        <>
-                            {render(buyablesDisplay)}
-                            <Spacer />
-                            <Row style="width: 600px; height: 350px; background-color: green; border-style: solid;">
-                                <Toggle
-                                    onUpdate:modelValue={value => (beep.value = value)}
-                                    modelValue={beep.value}
-                                />
-                                <Spacer width="30px" height="10px" />
-                                <div>
-                                    <span>Beep</span>
-                                </div>
-                                <Spacer />
-                                <VerticalRule height="200px" />
-                            </Row>
-                            <Spacer />
-                            <img src="https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png" />
-                        </>
-                    ))
-                })),
-                glowColor: "white",
-                display: "thingies",
-                style: { borderColor: "orange" }
-            },
-            jail: {
-                tab: createTab(() => ({
-                    display: jsx(() => (
-                        <>
-                            {render(coolInfo)}
-                            {render(longBoi)}
-                            <Spacer />
-                            <Row>
-                                <Column style="background-color: #555555; padding: 15px">
-                                    <div style="color: teal">Sugar level:</div>
-                                    <Spacer />
-                                    {render(tallBoi)}
-                                </Column>
-                                <Spacer />
-                                <Column>
-                                    <div>idk</div>
-                                    <Spacer width="0" height="50px" />
-                                    {render(flatBoi)}
-                                </Column>
-                            </Row>
-                            <Spacer />
-                            <div>It's jail because "bars"! So funny! Ha ha!</div>
-                            {render(tree)}
-                        </>
-                    ))
-                })),
-                display: "jail"
-            },
-            illuminati: {
-                tab: createTab(() => ({
-                    display: jsx(() => (
-                        // This should really just be <> and </>, however for some reason the
-                        // typescript interpreter can't figure out this layer and f.tsx otherwise
-                        <div>
-                            <h1> C O N F I R M E D </h1>
-                            <Spacer />
-                            {render(illuminatiTabs)}
-                            <div>Adjust how many points H gives you!</div>
-                            <Slider
-                                onUpdate:modelValue={value => (otherThingy.value = value)}
-                                modelValue={otherThingy.value}
-                                min={1}
-                                max={30}
-                            />
-                        </div>
-                    )),
-                    style: {
-                        backgroundColor: "#3325CC"
-                    }
-                })),
-                visibility() {
-                    return showIf(unlockIlluminatiUpgrade.bought.value);
-                },
-                display: "illuminati"
-            }
-        }
-    }));
-
-    return {
-        id,
-        color,
-        name,
-        links() {
-            const links = tree.links.value.slice();
-            links.push({
-                startNode: h,
-                endNode: flatBoi,
-                "stroke-width": "5px",
-                stroke: "red",
-                offsetEnd: { x: -50 + 100 * flatBoi.progress.value.toNumber(), y: 0 }
-            });
-            return links;
-        },
-        points,
-        best,
-        beep,
-        thingy,
-        otherThingy,
-        spentOnBuyables,
-        waffleBoost,
-        icecreamCap,
-        coolInfo,
-        lollipopMilestones,
-        funChallenge,
-        funEffect,
-        generatorUpgrade,
-        lollipopMultiplierUpgrade,
-        lollipopMultiplierEffect,
-        unlockIlluminatiUpgrade,
-        quasiUpgrade,
-        exhancers,
-        respecBuyables,
-        sellExhancer,
-        bars: { tallBoi, longBoi, flatBoi },
-        tree,
-        g,
-        h,
-        spook,
-        conversion,
-        reset,
-        hotkeys,
-        treeNode,
-        resetButton,
-        confirmRespec,
-        minWidth: 800,
-        tabs,
-        display: jsx(() => <>{render(tabs)}</>)
-    };
-});
-
-export default layer;
diff --git a/src/data/layers/aca/f.tsx b/src/data/layers/aca/f.tsx
deleted file mode 100644
index 0aa7a90..0000000
--- a/src/data/layers/aca/f.tsx
+++ /dev/null
@@ -1,179 +0,0 @@
-import { createLayerTreeNode, createResetButton } from "@/data/common";
-import { main } from "@/data/mod";
-import { createClickable } from "@/features/clickables/clickable";
-import { createExponentialScaling, createIndependentConversion } from "@/features/conversion";
-import { jsx } from "@/features/feature";
-import { createInfobox } from "@/features/infoboxes/infobox";
-import { createReset } from "@/features/reset";
-import MainDisplay from "@/features/resources/MainDisplay.vue";
-import { createResource, displayResource } from "@/features/resources/resource";
-import { createLayer } from "@/game/layers";
-import { persistent } from "@/game/persistence";
-import Decimal, { DecimalSource, formatWhole } from "@/util/bignum";
-import { render } from "@/util/vue";
-import c from "./c";
-
-const layer = createLayer(() => {
-    const id = "f";
-    const color = "#FE0102";
-    const name = "Farms";
-    const points = createResource<DecimalSource>(0, "farm points");
-    const boop = persistent<boolean>(false);
-
-    const coolInfo = createInfobox(() => ({
-        title: "Lore",
-        titleStyle: { color: "#FE0000" },
-        display: "DEEP LORE!",
-        bodyStyle: { backgroundColor: "#0000EE" }
-    }));
-
-    const clickableState = persistent<string>("Start");
-    const clickable = createClickable(() => ({
-        display() {
-            return {
-                title: "Clicky clicky!",
-                description: "Current state:<br>" + clickableState.value
-            };
-        },
-        initialState: "Start",
-        canClick() {
-            return clickableState.value !== "Borkened...";
-        },
-        onClick() {
-            switch (clickableState.value) {
-                case "Start":
-                    clickableState.value = "A new state!";
-                    break;
-                case "A new state!":
-                    clickableState.value = "Keep going!";
-                    break;
-                case "Keep going!":
-                    clickableState.value = "Maybe that's a bit too far...";
-                    break;
-                case "Maybe that's a bit too far...":
-                    //makeParticles(coolParticle, 4)
-                    clickableState.value = "Borkened...";
-                    break;
-                default:
-                    clickableState.value = "Start";
-                    break;
-            }
-        },
-        onHold() {
-            console.log("Clickkkkk...");
-        },
-        style() {
-            switch (clickableState.value) {
-                case "Start":
-                    return { "background-color": "green" };
-                case "A new state!":
-                    return { "background-color": "yellow" };
-                case "Keep going!":
-                    return { "background-color": "orange" };
-                case "Maybe that's a bit too far...":
-                    return { "background-color": "red" };
-                default:
-                    return {};
-            }
-        }
-    }));
-
-    const resetClickable = createClickable(() => ({
-        onClick() {
-            if (clickableState.value == "Borkened...") {
-                clickableState.value = "Start";
-            }
-        },
-        display() {
-            return clickableState.value == "Borkened..." ? "Fix the clickable!" : "Does nothing";
-        }
-    }));
-
-    const reset = createReset(() => ({
-        thingsToReset: (): Record<string, unknown>[] => [layer]
-    }));
-
-    const conversion = createIndependentConversion(() => ({
-        scaling: createExponentialScaling(10, 3, 0.5),
-        baseResource: main.points,
-        gainResource: points,
-        modifyGainAmount: gain => Decimal.times(gain, c.otherThingy.value)
-    }));
-
-    const treeNode = createLayerTreeNode(() => ({
-        layerID: id,
-        color,
-        reset,
-        tooltip() {
-            if (treeNode.canClick.value) {
-                return `${displayResource(points)} ${points.displayName}`;
-            }
-            return `This weird farmer dinosaur will only see you if you have at least 10 points. You only have ${displayResource(
-                main.points
-            )}`;
-        },
-        canClick() {
-            return Decimal.gte(main.points.value, 10);
-        }
-    }));
-
-    const resetButton = createResetButton(() => ({
-        conversion,
-        tree: main.tree,
-        treeNode,
-        display: jsx(() => {
-            if (resetButton.conversion.buyMax) {
-                return (
-                    <span>
-                        Hi! I'm a <u>weird dinosaur</u> and I'll give you{" "}
-                        <b>{formatWhole(resetButton.conversion.currentGain.value)}</b> Farm Points
-                        in exchange for all of your points and lollipops! (You'll get another one at{" "}
-                        {formatWhole(resetButton.conversion.nextAt.value)} points)
-                    </span>
-                );
-            } else {
-                return (
-                    <span>
-                        Hi! I'm a <u>weird dinosaur</u> and I'll give you a Farm Point in exchange
-                        for all of your points and lollipops! (At least{" "}
-                        {formatWhole(resetButton.conversion.nextAt.value)} points)
-                    </span>
-                );
-            }
-        })
-    }));
-
-    const tab = jsx(() => (
-        <>
-            {render(coolInfo)}
-            <MainDisplay resource={points} color={color} />
-            {render(resetButton)}
-            <div>You have {formatWhole(conversion.baseResource.value)} points</div>
-            <div>
-                <br />
-                <img src="https://images.beano.com/store/24ab3094eb95e5373bca1ccd6f330d4406db8d1f517fc4170b32e146f80d?auto=compress%2Cformat&dpr=1&w=390" />
-                <div>Bork Bork!</div>
-            </div>
-            {render(clickable)}
-        </>
-    ));
-
-    return {
-        id,
-        color,
-        name,
-        points,
-        boop,
-        coolInfo,
-        clickable,
-        clickableState,
-        resetClickable,
-        reset,
-        conversion,
-        treeNode,
-        resetButton,
-        display: tab
-    };
-});
-
-export default layer;
diff --git a/src/data/layers/demo-infinity.ts b/src/data/layers/demo-infinity.ts
deleted file mode 100644
index 6e62446..0000000
--- a/src/data/layers/demo-infinity.ts
+++ /dev/null
@@ -1,354 +0,0 @@
-/* eslint-disable */
-import { layers } from "@/game/layers";
-import player from "@/game/player";
-import { Layer, RawLayer } from "@/typings/layer";
-import Decimal, { format } from "@/util/bignum";
-import {
-  getBuyableAmount, hasChallenge, hasMilestone, hasUpgrade, setBuyableAmount
-} from "@/util/features";
-import { resetLayer } from "@/util/layers";
-
-export default {
-  id: "i",
-  position: 2, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
-  startData() {
-    return {
-      unlocked: false,
-      points: new Decimal(0)
-    };
-  },
-  branches: ["p"],
-  color: "#964B00",
-  requires() {
-    const require = new Decimal(8).plus(
-      player.layers.i.points
-        .div(10)
-        .floor()
-        .times(2)
-    );
-    return require;
-  }, // Can be a function that takes requirement increases into account
-  effectDisplay() {
-    return (
-      "Multiplying points and prestige points by " +
-      format(
-        player.layers[this.layer].points
-          .plus(1)
-          .pow(hasUpgrade("p", 235) ? 6.942 : 1)
-      )
-    );
-  },
-  resource: "Infinity", // Name of prestige currency
-  baseResource: "pointy points", // Name of resource prestige is based on
-  baseAmount() {
-    return player.layers.p.buyables![21];
-  }, // Get the current amount of baseResource
-  type: "custom", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have
-  resetGain() {
-    if (hasMilestone("p", 12)) {
-      return getBuyableAmount("p", 21)!
-        .div(2)
-        .floor()
-        .times(2)
-        .times(5)
-        .sub(30)
-        .sub(player.layers.i.points);
-    }
-    return player.layers.p.buyables![21].gte(layers.i.requires!) ? 1 : 0;
-  }, // Prestige currency exponent
-  getNextAt() {
-    return new Decimal(100);
-  },
-  canReset() {
-    return player.layers.p.buyables![21].gte(layers.i.requires!);
-  },
-  prestigeButtonDisplay() {
-    return (
-      "Reset everything for +" +
-      format(layers.i.resetGain) +
-      " Infinity.<br>You need " +
-      format(layers.i.requires!) +
-      " pointy points to reset."
-    );
-  },
-  row: 1, // Row the layer is in on the tree (0 is the first row)
-  hotkeys: [
-    {
-      key: "i",
-      description: "I: Infinity",
-      press() {
-        if (layers.i.canReset) resetLayer(this.layer);
-      }
-    }
-  ],
-  layerShown() {
-    return (
-      player.layers[this.layer].unlocked ||
-      new Decimal(player.layers.p.buyables[21]).gte(8)
-    );
-  },
-  milestones: {
-    data: {
-      0: {
-        requirementDisplay: "2 Infinity points",
-        effectDisplay: "Keep ALL milestones on reset",
-        done() {
-          return player.layers[this.layer].points.gte(2);
-        }
-      },
-      1: {
-        requirementDisplay: "3 Infinity points",
-        effectDisplay: "Pointy points don't reset generators",
-        done() {
-          return player.layers[this.layer].points.gte(3);
-        },
-        unlocked() {
-          return hasMilestone(this.layer, Number(this.id) - 1);
-        }
-      },
-      2: {
-        requirementDisplay: "4 Infinity points",
-        effectDisplay:
-          "Start with 6 <b>Time Dilation</b>, 3 <b>Point</b>, and 1 of the other 2 challenges",
-        done() {
-          return player.layers[this.layer].points.gte(4);
-        },
-        unlocked() {
-          return hasMilestone(this.layer, Number(this.id) - 1);
-        }
-      },
-      3: {
-        requirementDisplay: "5 Infinity points",
-        effectDisplay: "Start with 40 upgrades and 6 boosts",
-        done() {
-          return player.layers[this.layer].points.gte(5);
-        },
-        unlocked() {
-          return hasMilestone(this.layer, Number(this.id) - 1);
-        }
-      },
-      4: {
-        requirementDisplay: "6 Infinity points",
-        effectDisplay:
-          "You can choose all of the 14th row upgrades, and remove the respec button",
-        done() {
-          return player.layers[this.layer].points.gte(6);
-        },
-        unlocked() {
-          return hasMilestone(this.layer, Number(this.id) - 1);
-        }
-      },
-      5: {
-        requirementDisplay: "8 Infinity points",
-        effectDisplay: "Keep all upgrades and 7 Time dilation",
-        done() {
-          return player.layers[this.layer].points.gte(8);
-        },
-        unlocked() {
-          return hasMilestone(this.layer, Number(this.id) - 1);
-        }
-      },
-      6: {
-        requirementDisplay: "10 Infinity points",
-        effectDisplay: "Infinity reset nothing and auto prestige",
-        done() {
-          return player.layers[this.layer].points.gte(10);
-        },
-        unlocked() {
-          return hasMilestone(this.layer, Number(this.id) - 1);
-        }
-      }
-    }
-  },
-  resetsNothing() {
-    return hasMilestone(this.layer, 6);
-  },
-  update(this: Layer) {
-    if (hasMilestone(this.layer, 0)) {
-      if (!hasMilestone("p", 0)) {
-        player.layers.p.milestones!.push(0);
-        player.layers.p.milestones!.push(1);
-        player.layers.p.milestones!.push(2);
-        player.layers.p.milestones!.push(3);
-        player.layers.p.milestones!.push(4);
-        player.layers.p.milestones!.push(5);
-        player.layers.p.milestones!.push(6);
-        player.layers.p.milestones!.push(7);
-        player.layers.p.milestones!.push(8);
-      }
-    }
-    if (hasMilestone(this.layer, 2)) {
-      if (!hasChallenge("p", 11)) {
-        player.layers.p.challenges![11] = new Decimal(
-          hasMilestone(this.layer, 5) ? 7 : 6
-        );
-        player.layers.p.challenges![12] = new Decimal(3);
-        player.layers.p.challenges![21] = new Decimal(1);
-        player.layers.p.challenges![22] = new Decimal(1);
-      }
-    }
-    if (hasMilestone(this.layer, 3)) {
-      if (!hasUpgrade("p", 71)) {
-        player.layers.p.upgrades = [
-          11,
-          12,
-          13,
-          14,
-          21,
-          22,
-          23,
-          24,
-          31,
-          32,
-          33,
-          34,
-          41,
-          42,
-          43,
-          44,
-          51,
-          52,
-          53,
-          54,
-          61,
-          62,
-          63,
-          64,
-          71,
-          72,
-          73,
-          74,
-          81,
-          82,
-          83,
-          84,
-          91,
-          92,
-          93,
-          94,
-          101,
-          102,
-          103,
-          104
-        ];
-      }
-      if (getBuyableAmount("p", 11)!.lt(6)) {
-        setBuyableAmount("p", 11, new Decimal(6));
-      }
-    }
-    if (hasUpgrade(this.layer, 13)) {
-      for (
-        let i = 0;
-        i < (hasUpgrade("p", 222) ? 100 : hasUpgrade("p", 215) ? 10 : 1);
-        i++
-      ) {
-        if (layers.p.buyables!.data[12].canAfford) layers.p.buyables!.data[12].buy();
-        if (layers.p.buyables!.data[13].canAfford) layers.p.buyables!.data[13].buy();
-        if (
-          layers.p.buyables!.data[14].canAfford &&
-          layers.p.buyables!.data[14].unlocked
-        )
-          layers.p.buyables!.data[14].buy();
-        if (layers.p.buyables!.data[21].canAfford) layers.p.buyables!.data[21].buy();
-      }
-    }
-    if (hasUpgrade("p", 223)) {
-      if (hasMilestone("p", 14))
-        player.layers.p.buyables![22] = player.layers.p.buyables![22].max(
-          player.layers.p.buyables![21].sub(7)
-        );
-      else if (layers.p.buyables!.data[22].canAfford) layers.p.buyables!.data[22].buy();
-    }
-    if (hasMilestone(this.layer, 5) && !hasUpgrade("p", 111)) {
-      player.layers.p.upgrades = [
-        11,
-        12,
-        13,
-        14,
-        21,
-        22,
-        23,
-        24,
-        31,
-        32,
-        33,
-        34,
-        41,
-        42,
-        43,
-        44,
-        51,
-        52,
-        53,
-        54,
-        61,
-        62,
-        63,
-        64,
-        71,
-        72,
-        73,
-        74,
-        81,
-        82,
-        83,
-        84,
-        91,
-        92,
-        93,
-        94,
-        101,
-        102,
-        103,
-        104,
-        111,
-        121,
-        122,
-        131,
-        132,
-        141,
-        142,
-        143
-      ];
-    }
-    if (hasMilestone(this.layer, 6)) {
-      this.reset();
-    }
-  },
-  upgrades: {
-    rows: 999,
-    cols: 5,
-    data: {
-      11: {
-        title: "Prestige",
-        description: "Gain 100% of prestige points per second",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasMilestone(this.layer, 4);
-        }
-      },
-      12: {
-        title: "Automation",
-        description: "Remove the nerf of upgrade <b>Active</b>",
-        cost() {
-          return new Decimal(2);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 11);
-        }
-      },
-      13: {
-        title: "Pointy",
-        description: "Automatically buy generators and pointy points",
-        cost() {
-          return new Decimal(5);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 11);
-        }
-      }
-    }
-  }
-} as RawLayer;
diff --git a/src/data/layers/demo.ts b/src/data/layers/demo.ts
deleted file mode 100644
index cb4630b..0000000
--- a/src/data/layers/demo.ts
+++ /dev/null
@@ -1,2298 +0,0 @@
-/* eslint-disable */
-import { layers } from "@/game/layers";
-import player from "@/game/player";
-import { RawLayer } from "@/typings/layer";
-import Decimal, { format } from "@/util/bignum";
-import {
-  getBuyableAmount, hasChallenge, hasMilestone, hasUpgrade, setBuyableAmount
-} from "@/util/features";
-import { resetLayer } from "@/util/layers";
-
-export default {
-  id: "p",
-  position: 2,
-  startData() {
-    return {
-      unlocked: true,
-      points: new Decimal(0),
-      gp: new Decimal(0),
-      g: new Decimal(0),
-      geff: new Decimal(1),
-      cmult: new Decimal(1)
-    };
-  },
-  color: "#4BDC13",
-  requires() {
-    let require = new Decimal(68.99);
-    if (hasMilestone(this.layer, 0)) require = require.plus(0.01);
-    if (hasUpgrade(this.layer, 21))
-      require = require.tetrate(
-        hasUpgrade("p", 34)
-          ? new Decimal(1)
-              .div(
-                new Decimal(1).plus(
-                  layers.p.upgrades!.data[34].effect as Decimal
-                )
-              )
-              .toNumber()
-          : 1
-      );
-    if (hasUpgrade(this.layer, 22))
-      require = require.pow(
-        hasUpgrade("p", 34)
-          ? new Decimal(1).div(
-              new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal)
-            )
-          : 1
-      );
-    if (hasUpgrade(this.layer, 23))
-      require = require.div(
-        hasUpgrade("p", 34)
-          ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal)
-          : 1
-      );
-    if (hasUpgrade(this.layer, 24))
-      require = require.sub(
-        hasUpgrade("p", 34)
-          ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal)
-          : 1
-      );
-    return require.max(1);
-  },
-  resource: "prestige points",
-  baseResource: "points",
-  baseAmount() {
-    return player.points;
-  }, // Get the current amount of baseResource
-  type: "normal", // normal: cost to gain currency depends on amount gained. static: cost depends on how much you already have
-  exponent: 0.5, // Prestige currency exponent
-  gainMult() {
-    // Calculate the multiplier for main currency from bonuses
-    let mult = new Decimal(1);
-    if (hasUpgrade(this.layer, 131)) mult = mult.times(10);
-    if (player.layers.i.unlocked)
-      mult = mult.times(
-        player.layers.i.points.plus(1).pow(hasUpgrade("p", 235) ? 6.942 : 1)
-      );
-    if (hasUpgrade(this.layer, 222))
-      mult = mult.times(getBuyableAmount(this.layer, 22)!.plus(1));
-    if (hasUpgrade("p", 231)) {
-      const asdf = hasUpgrade("p", 132)
-        ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(2))
-        : hasUpgrade("p", 101)
-        ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(3))
-        : hasUpgrade("p", 93)
-        ? (player.layers.p.gp as Decimal).plus(1).pow(0.2)
-        : (player.layers.p.gp as Decimal).plus(1).log10();
-      mult = mult.mul(asdf.plus(1));
-    }
-    if (hasMilestone(this.layer, 13))
-      mult = mult.mul(
-        new Decimal(2)
-          .plus(layers.p.buyables!.data[33].effect as Decimal)
-          .pow(getBuyableAmount(this.layer, 32)!)
-      );
-    return mult;
-  },
-  gainExp() {
-    // Calculate the exponent on main currency from bonuses
-    return new Decimal(1);
-  },
-  row: 0, // Row the layer is in on the tree (0 is the first row)
-  hotkeys: [
-    {
-      key: "p",
-      description: "P: Reset for prestige points",
-      press() {
-        if (layers.p.canReset) resetLayer(this.layer);
-      }
-    }
-  ],
-  layerShown() {
-    return true;
-  },
-  upgrades: {
-    data: {
-      11: {
-        title: "Gain points",
-        description: "Point generation is increased by 1",
-        cost() {
-          if (hasMilestone(this.layer, 2)) return new Decimal(1);
-          return new Decimal(1.00001);
-        },
-        unlocked() {
-          return true;
-        }
-      },
-      12: {
-        title: "Gain more points",
-        description: "Point generation is singled",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 11);
-        }
-      },
-      13: {
-        title: "Gain more points",
-        description: "Point generation is lined",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 12);
-        }
-      },
-      14: {
-        title: "Gain more points",
-        description: "Point generation is tetrated by 1",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 13);
-        }
-      },
-      21: {
-        title: "Lower prestige requirement",
-        description: "Prestige point requirement is superrooted by 1",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 14);
-        }
-      },
-      22: {
-        title: "Lower prestige requirement more",
-        description: "Prestige point requirement is line rooted",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 21);
-        }
-      },
-      23: {
-        title: "Lower prestige requirement more",
-        description: "Prestige point requirement is wholed",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 22);
-        }
-      },
-      24: {
-        title: "Lower prestige requirement more",
-        description: "Prestige point requirement is decreased by 1",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 23);
-        }
-      },
-      31: {
-        title: "Unlock",
-        description: "Unlock an upgrade",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 24);
-        }
-      },
-      32: {
-        title: "An",
-        description: "Unlock an upgrade",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 31);
-        }
-      },
-      33: {
-        title: "Upgrade",
-        description: "Unlock an upgrade",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 32);
-        }
-      },
-      34: {
-        title: "Increase",
-        description() {
-          return (
-            "Add 0.01 to all above upgrades. Currently: +" +
-            format(this.effect as Decimal)
-          );
-        },
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 33);
-        },
-        effect() {
-          let r = hasUpgrade("p", 41)
-            ? new Decimal(0.01).times(layers.p.upgrades!.data[41].effect as Decimal)
-            : new Decimal(0.01);
-          r = r.times(
-            new Decimal(1).plus(
-              new Decimal(player.layers[this.layer].challenges![11])
-                .add(1)
-                .pow(hasUpgrade(this.layer, 121) ? 1.2 : 1)
-            )
-          );
-          if (hasUpgrade(this.layer, 92))
-            r = r.plus(
-              new Decimal(0.001)
-                .times((player.layers[this.layer].g as Decimal).plus(1))
-                .min(0.05)
-            );
-          return r;
-        }
-      },
-      41: {
-        title: "Increase again",
-        description() {
-          return (
-            "Multiply the previous upgrade by 1.01. Currently: x" +
-            format(this.effect as Decimal)
-          );
-        },
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 34);
-        },
-        effect() {
-          return new Decimal(1.01)
-            .pow(hasUpgrade("p", 42) ? layers.p.upgrades!.data[42].effect as Decimal : 1)
-            .times(hasUpgrade("p", 63) ? 2 : 1);
-        }
-      },
-      42: {
-        title: "Increase again",
-        description() {
-          return (
-            "Exponentiate the previous upgrade by 1.01. Currently: ^" +
-            format(this.effect as Decimal)
-          );
-        },
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 41);
-        },
-        effect() {
-          return new Decimal(1.01)
-            .tetrate(hasUpgrade("p", 43) ? (layers.p.upgrades!.data[43].effect as Decimal).toNumber() : 1)
-            .times(hasUpgrade("p", 63) ? 2 : 1)
-            .times(hasUpgrade("p", 64) ? 2 : 1);
-        }
-      },
-      43: {
-        title: "Increase again",
-        description() {
-          return (
-            "Tetrate the previous upgrade by 1.01. Currently: ^^" +
-            format(this.effect as Decimal)
-          );
-        },
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 42);
-        },
-        effect() {
-          return new Decimal(1.01)
-            .pentate(hasUpgrade("p", 44) ? (layers.p.upgrades!.data[44].effect as Decimal).toNumber() : 1)
-            .times(hasUpgrade("p", 63) ? 2 : 1)
-            .times(hasUpgrade("p", 64) ? 2 : 1);
-        }
-      },
-      44: {
-        title: "Increase again",
-        description() {
-          return (
-            "Pentate the previous upgrade by 1.01. Currently: ^^^" +
-            format(this.effect as Decimal)
-          );
-        },
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 43);
-        },
-        effect() {
-          return new Decimal(1.01)
-            .times(hasUpgrade("p", 63) ? 2 : 1)
-            .times(hasUpgrade("p", 64) ? 2 : 1);
-        }
-      },
-      51: {
-        title: "Challenging",
-        description: "This upgrade doesn't unlock a challenge",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 44);
-        }
-      },
-      52: {
-        title: "Not challenging",
-        description: "This upgrade doesn't add 1 to the completion limit",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 51);
-        }
-      },
-      53: {
-        title: "Not not challenging",
-        description: "This upgrade doesn't add 1 to the completion limit",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 52);
-        }
-      },
-      54: {
-        title: "(not^3) challenging",
-        description:
-          "Fix the bug where you can't buy upgrades when you have 1 prestige point",
-        cost() {
-          return new Decimal(0.99999);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 53);
-        },
-        onPurchase() {
-          player.layers.p.points = player.layers.p.points.round();
-        }
-      },
-      61: {
-        title: "(not^4) challenging",
-        description: "Doesn't unlock a second challenge",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 54) && hasUpgrade(this.layer, 53);
-        }
-      },
-      62: {
-        title: "Infinity points",
-        description: "You can now complete Time Dilation 4 more times",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 61);
-        }
-      },
-      63: {
-        title: "Eternity points",
-        description: "Double all fourth row upgrade effects",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 62);
-        }
-      },
-      64: {
-        title: "Reality points",
-        description: "Previous upgrade, but only to the last 3 upgrades",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 63);
-        }
-      },
-      71: {
-        title: "1",
-        description: "Add 1.1 to point gain, but reset all above upgrades",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 64);
-        },
-        onPurchase() {
-          if (!hasMilestone(this.layer, 0))
-            player.layers[this.layer].upgrades = [71];
-        }
-      },
-      72: {
-        title: "2",
-        description: "Multiply point gain by 1.1, but reset all above upgrades",
-        cost() {
-          return new Decimal(2);
-        },
-        unlocked() {
-          return (
-            hasUpgrade(this.layer, 64) &&
-            hasUpgrade(this.layer, Number(this.id) - 1)
-          );
-        },
-        onPurchase() {
-          if (!hasMilestone(this.layer, 1))
-            player.layers[this.layer].upgrades = [71, 72];
-        }
-      },
-      73: {
-        title: "3",
-        description: "Raise point gain by ^1.1, but reset all above upgrades",
-        cost() {
-          return new Decimal(4);
-        },
-        unlocked() {
-          return (
-            hasUpgrade(this.layer, 64) &&
-            hasUpgrade(this.layer, Number(this.id) - 1)
-          );
-        },
-        onPurchase() {
-          if (!hasMilestone(this.layer, 1))
-            player.layers[this.layer].upgrades = [71, 72, 73];
-        }
-      },
-      74: {
-        title: "4",
-        description: "Tetrate point gain by 1.1, but reset all above upgrades",
-        cost() {
-          return new Decimal(8);
-        },
-        unlocked() {
-          return (
-            hasUpgrade(this.layer, 64) &&
-            hasUpgrade(this.layer, Number(this.id) - 1)
-          );
-        },
-        onPurchase() {
-          if (!hasMilestone(this.layer, 2))
-            player.layers[this.layer].upgrades = [71, 72, 73, 74];
-          if (hasMilestone(this.layer, 1) && !hasMilestone(this.layer, 2)) {
-            player.layers[this.layer].upgrades = [
-              11,
-              12,
-              13,
-              14,
-              21,
-              22,
-              23,
-              24,
-              71,
-              72,
-              73,
-              74
-            ];
-          }
-        }
-      },
-      81: {
-        title: "5",
-        description: "Generator efficiency is increased by 2",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return (
-            hasUpgrade(this.layer, 74) &&
-            (player.layers[this.layer].buyables![12].gt(0) ||
-              player.layers[this.layer].buyables![21].gt(0))
-          );
-        }
-      },
-      82: {
-        title: "6",
-        description: "Unlock another way to buy generators",
-        cost() {
-          return new Decimal(1);
-        },
-        unlocked() {
-          return (
-            hasUpgrade(this.layer, 81) &&
-            (player.layers[this.layer].buyables![12].gt(0) ||
-              player.layers[this.layer].buyables![21].gt(0))
-          );
-        }
-      },
-      83: {
-        title: "7",
-        description: "Generator efficiency is boosted by prestige points",
-        cost() {
-          return new Decimal(3);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 82);
-        }
-      },
-      84: {
-        title: "8",
-        description: "You can complete <b>Point</b> one more time",
-        cost() {
-          return new Decimal(3);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 83);
-        }
-      },
-      91: {
-        title: "9",
-        description: "New Challenge Time",
-        cost() {
-          return new Decimal(20);
-        },
-        unlocked() {
-          return (
-            hasUpgrade(this.layer, 84) &&
-            new Decimal(player.layers[this.layer].challenges![12]).gte(3)
-          );
-        }
-      },
-      92: {
-        title: "10",
-        description:
-          "Each of the first 50 generators adds 0.001 to <b>Increase</b>",
-        cost() {
-          return new Decimal(5);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 91) && hasChallenge(this.layer, 21);
-        }
-      },
-      93: {
-        title: "11",
-        description:
-          "Change the tree trunk in generator effect to a hypertessaract root",
-        cost() {
-          return new Decimal(7);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 92);
-        }
-      },
-      94: {
-        title: "12",
-        description: "Unlock a clickable in generators",
-        cost() {
-          return new Decimal(50);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 93);
-        }
-      },
-      101: {
-        title: "10th row????",
-        description: "Decrease the dimensions of <b>11</b> by 2",
-        cost() {
-          return new Decimal(10);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 94);
-        }
-      },
-      102: {
-        title: "2 Tree Trunks",
-        description:
-          "Double log of generator points adds to generator efficiency",
-        cost() {
-          return new Decimal(25);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 101);
-        }
-      },
-      103: {
-        title: "(not^5) challenging",
-        description: "Unlock the last challenge",
-        cost() {
-          return new Decimal(103);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 102);
-        }
-      },
-      104: {
-        title: "2 layers tree",
-        description: "Prestige points boost points, and unlock another tab",
-        cost() {
-          return new Decimal(100);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 103) && hasChallenge(this.layer, 22);
-        }
-      },
-      111: {
-        title: "not (hardcapped)",
-        description:
-          "Remove the generator clickable hardcap, and you can only pick one upgrade on each row below this",
-        cost() {
-          return new Decimal(110);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 104) && hasMilestone(this.layer, 6);
-        }
-      },
-      112: {
-        title: "Respec button",
-        description: "Respec all lower upgrades, but you don't get points back",
-        cost() {
-          return new Decimal(100);
-        },
-        unlocked() {
-          return (
-            hasUpgrade(this.layer, 111) &&
-            (hasUpgrade(this.layer, 121) || hasUpgrade(this.layer, 122)) &&
-            !hasMilestone("i", 4)
-          );
-        },
-        onPurchase() {
-          player.layers.p.upgrades = player.layers.p.upgrades!.filter((i: string | number) => {
-            return Number(i) < 112;
-          });
-        }
-      },
-      121: {
-        title: "Timers",
-        description: "Raise the <b>Time Dilation</b> reward effect to the 1.2",
-        cost() {
-          return new Decimal(500);
-        },
-        unlocked() {
-          return (
-            hasUpgrade(this.layer, 111) &&
-            (!hasUpgrade(this.layer, 122) || hasMilestone(this.layer, 7))
-          );
-        }
-      },
-      122: {
-        title: "Generators",
-        description:
-          "Decrease the first generator buyable cost scaling base by 2",
-        cost() {
-          return new Decimal(500);
-        },
-        unlocked() {
-          return (
-            hasUpgrade(this.layer, 111) &&
-            (!hasUpgrade(this.layer, 121) || hasMilestone(this.layer, 7))
-          );
-        }
-      },
-      131: {
-        title: "Prestige",
-        description: "Gain 10x more prestige points",
-        cost() {
-          return new Decimal(5000);
-        },
-        unlocked() {
-          return (
-            (hasUpgrade(this.layer, 121) || hasUpgrade(this.layer, 122)) &&
-            (!hasUpgrade(this.layer, 132) || hasMilestone(this.layer, 7))
-          );
-        }
-      },
-      132: {
-        title: "One and a half",
-        description: "Raise generator effect to the 1.5",
-        cost() {
-          return new Decimal(5000);
-        },
-        unlocked() {
-          return (
-            (hasUpgrade(this.layer, 121) || hasUpgrade(this.layer, 122)) &&
-            (!hasUpgrade(this.layer, 131) || hasMilestone(this.layer, 7))
-          );
-        }
-      },
-
-      141: {
-        title: "Active",
-        description:
-          "Multiply generator efficiency now increases by 1, but it doesn't automatically click.",
-        cost() {
-          return new Decimal(50000);
-        },
-        unlocked() {
-          return (
-            (hasUpgrade(this.layer, 131) || hasUpgrade(this.layer, 132)) &&
-            ((!hasUpgrade(this.layer, 142) && !hasUpgrade(this.layer, 143)) ||
-              hasMilestone("i", 4))
-          );
-        }
-      },
-      142: {
-        title: "Passive",
-        description: "Gain 5x more points",
-        cost() {
-          return new Decimal(50000);
-        },
-        unlocked() {
-          return (
-            (hasUpgrade(this.layer, 131) || hasUpgrade(this.layer, 132)) &&
-            ((!hasUpgrade(this.layer, 141) && !hasUpgrade(this.layer, 143)) ||
-              hasMilestone("i", 4))
-          );
-        }
-      },
-      143: {
-        title: "Idle",
-        description: "Hours played multiply generator power",
-        cost() {
-          return new Decimal(50000);
-        },
-        unlocked() {
-          return (
-            (hasUpgrade(this.layer, 131) || hasUpgrade(this.layer, 132)) &&
-            ((!hasUpgrade(this.layer, 142) && !hasUpgrade(this.layer, 141)) ||
-              hasMilestone("i", 4))
-          );
-        }
-      },
-      211: {
-        title: "Prestige",
-        description: "Pointy points multiply points",
-        cost() {
-          return new Decimal(1);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) && player.subtabs.p.mainTabs != "Upgrades"
-          );
-        }
-      },
-      212: {
-        title: "Pointy",
-        description:
-          "Pointy prestige points reduce the cost scaling of pointy points",
-        cost() {
-          return new Decimal(2);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) &&
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasUpgrade(this.layer, 211)
-          );
-        }
-      },
-      213: {
-        title: "Time",
-        description: "Generator power also multiplies point gain",
-        cost() {
-          return new Decimal(6);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) &&
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasUpgrade(this.layer, 212)
-          );
-        }
-      },
-      214: {
-        title: "^0",
-        description: "Further reduce the pointy point scaling",
-        cost() {
-          return new Decimal(11);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) &&
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasUpgrade(this.layer, 213)
-          );
-        }
-      },
-      215: {
-        title: "bulk",
-        description: "Auto-pointy points now buys 10 per tick",
-        cost() {
-          return new Decimal(27);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) &&
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasUpgrade(this.layer, 214)
-          );
-        }
-      },
-      221: {
-        title: "^-1",
-        description: "^0 is even more powerful",
-        cost() {
-          return new Decimal(28);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) &&
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasUpgrade(this.layer, 215)
-          );
-        }
-      },
-      222: {
-        title: "???",
-        description:
-          "square <b>bulk</b> and pointy prestige points multiply prestige points",
-        cost() {
-          return new Decimal(90);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) &&
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasUpgrade(this.layer, 221)
-          );
-        }
-      },
-      223: {
-        title: "more automation",
-        description: "Automatically gain pointy prestige points",
-        cost() {
-          return new Decimal(96);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) &&
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasUpgrade(this.layer, 222)
-          );
-        }
-      },
-      224: {
-        title: "Generation",
-        description: "Generator costs are divided by generator effect",
-        cost() {
-          return new Decimal(100);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) &&
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasUpgrade(this.layer, 223)
-          );
-        }
-      },
-      225: {
-        title: "Boosters",
-        description: "Unlock boosters (next update)",
-        cost() {
-          return new Decimal(135);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 22)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            22,
-            getBuyableAmount(this.layer, 22)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("i", 5) &&
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasUpgrade(this.layer, 224)
-          );
-        }
-      },
-      231: {
-        title: "Blue",
-        description: "The generator effect also affects prestige points",
-        cost() {
-          return new Decimal(4);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 23)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            23,
-            getBuyableAmount(this.layer, 23)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasMilestone(this.layer, 11)
-          );
-        },
-        currencyDisplayName: "pointy boosters"
-      },
-      232: {
-        title: "Red",
-        description: "Unlock a third way to buy generators",
-        cost() {
-          return new Decimal(5);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 23)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            23,
-            getBuyableAmount(this.layer, 23)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasMilestone(this.layer, 12)
-          );
-        },
-        currencyDisplayName: "pointy boosters"
-      },
-      233: {
-        title: "Green",
-        description:
-          "Prestige points do not reset your pointy points and boosters don't reset generators",
-        cost() {
-          return new Decimal(5);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 23)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            23,
-            getBuyableAmount(this.layer, 23)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasMilestone(this.layer, 12)
-          );
-        },
-        currencyDisplayName: "pointy boosters"
-      },
-      234: {
-        title: "Yellow",
-        description:
-          "Divide the cost of the third generator buyable based on boosters",
-        cost() {
-          return new Decimal(6);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 23)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            23,
-            getBuyableAmount(this.layer, 23)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasMilestone(this.layer, 12)
-          );
-        },
-        currencyDisplayName: "pointy boosters"
-      },
-      235: {
-        title: "Orange",
-        description: "Raise the Infinity effect to the 6.9420th power",
-        cost() {
-          return new Decimal(8);
-        },
-        canAfford() {
-          return getBuyableAmount(this.layer, 23)!.gte(this.cost);
-        },
-        pay() {
-          setBuyableAmount(
-            this.layer,
-            23,
-            getBuyableAmount(this.layer, 23)!.sub(this.cost)
-          );
-        },
-        unlocked() {
-          return (
-            player.subtabs.p.mainTabs != "Upgrades" &&
-            hasMilestone(this.layer, 12)
-          );
-        },
-        currencyDisplayName: "pointy boosters"
-      }
-    }
-  },
-
-  clickables: {
-    rows: 1,
-    cols: 1,
-    data: {
-      11: {
-        display() {
-          return (
-            "Multiply generator efficiency by " +
-            format(player.layers.p.cmult as Decimal) +
-            ((player.layers.p.cmult as Decimal).min(100).eq(100) && !hasUpgrade(this.layer, 111)
-              ? " (hardcapped)"
-              : "")
-          );
-        },
-        unlocked() {
-          return hasUpgrade("p", 94);
-        },
-        click() {
-          player.layers.p.cmult = (player.layers.p.cmult as Decimal).plus(hasUpgrade("p", 141) ? 1 : 0.01);
-          if (!hasUpgrade(this.layer, 111))
-            player.layers.p.cmult = (player.layers.p.cmult as Decimal).min(100);
-        },
-        canClick() {
-          return (player.layers.p.cmult as Decimal).lt(100) || hasUpgrade(this.layer, 111);
-        }
-      }
-    }
-  },
-
-  challenges: {
-    rows: 99,
-    cols: 2,
-    data: {
-      11: {
-        name: "Time dilation",
-        challengeDescription() {
-          return "Point gain exponent is raised to the ^0.75";
-        },
-        goal() {
-          return new Decimal(100).times(
-            new Decimal(10).pow(
-              new Decimal(player.layers[this.layer].challenges![this.id])
-                .times(
-                  new Decimal(1).sub(
-                    new Decimal(
-                      layers[this.layer].challenges!.data[12].effect as number
-                    ).div(100)
-                  )
-                )
-                .pow(2)
-            )
-          );
-        },
-        rewardDescription() {
-          return (
-            "You have completed this challenge " +
-            player.layers[this.layer].challenges![this.id] +
-            "/" +
-            this.completionLimit +
-            " times. Multiply <b>Increase</b>'s effect by challenge completions+1. Currently: x" +
-            format(
-              new Decimal(player.layers[this.layer].challenges![this.id])
-                .add(1)
-                .pow(hasUpgrade(this.layer, 121) ? 1.2 : 1)
-            )
-          );
-        },
-        unlocked() {
-          return hasUpgrade("p", 51) || hasChallenge(this.layer, this.id);
-        },
-        completionLimit() {
-          if (hasUpgrade("p", 62)) return 7;
-          if (hasUpgrade("p", 53)) return 3;
-          if (hasUpgrade("p", 52)) return 2;
-          return 1;
-        }
-      },
-      12: {
-        name: "Point",
-        challengeDescription: "Points are pointed",
-        goal() {
-          return new Decimal(100);
-        },
-        rewardDescription() {
-          return (
-            "You have completed this challenge " +
-            player.layers[this.layer].challenges![this.id] +
-            "/" +
-            this.completionLimit +
-            " times, making previous challenge goal scale " +
-            layers[this.layer].challenges!.data[this.id].effect +
-            "% slower."
-          );
-        },
-        unlocked() {
-          return hasUpgrade("p", 61) || hasChallenge(this.layer, this.id);
-        },
-        effect() {
-          if (!hasChallenge(this.layer, this.id)) return 0;
-          if (Decimal.eq(player.layers[this.layer].challenges![this.id], 1))
-            return 50;
-            if (Decimal.eq(player.layers[this.layer].challenges![this.id], 2))
-            return 60;
-            if (Decimal.eq(player.layers[this.layer].challenges![this.id], 3))
-            return 70;
-        },
-        completionLimit() {
-          let l = new Decimal(1);
-          if (hasUpgrade("p", 84)) l = l.plus(1);
-          if (hasMilestone("p", 3)) l = l.plus(1);
-          return l;
-        }
-      },
-      21: {
-        name: "Time Points",
-        challengeDescription: "You are stuck in all above challenges",
-        goal() {
-          return new Decimal(308.25);
-        },
-        rewardDescription() {
-          return "Lower the first generator buyable cost base by 6";
-        },
-        unlocked() {
-          return hasUpgrade("p", 91) || hasChallenge(this.layer, this.id);
-        }
-      },
-      22: {
-        name: "Last Challenge",
-        challengeDescription: "Generator points do nothing",
-        goal() {
-          return new Decimal(9999);
-        },
-        rewardDescription() {
-          return "Autoclick the clickable and reduce <b>2 Tree Trunks</b> by 1";
-        },
-        unlocked() {
-          return hasUpgrade("p", 103) || hasChallenge(this.layer, this.id);
-        }
-      }
-    }
-  },
-  buyables: {
-    rows: 99,
-    cols: 4,
-    data: {
-      11: {
-        cost() {
-          return new Decimal(0);
-        },
-        display() {
-          return (
-            "Reset all upgrades and challenges, but get a boost. You have reset " +
-            getBuyableAmount(this.layer, this.id) +
-            " times.<br>" +
-            (getBuyableAmount(this.layer, this.id)!.eq(6)
-              ? "You can't buy more than 6 boosts!"
-              : "You need all upgrades to reset.")
-          );
-        },
-        canAfford() {
-          return (
-            player.layers[this.layer].points.gte(this.cost!) &&
-            hasUpgrade(this.layer, 74) &&
-            hasUpgrade(this.layer, 64) &&
-            getBuyableAmount(this.layer, this.id)!.lt(6)
-          );
-        },
-        buy() {
-          player.layers[this.layer].points = player.layers[
-            this.layer
-          ].points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-          player.layers[this.layer].points = new Decimal(0);
-          player.layers[this.layer].upgrades = [];
-          if (hasMilestone(this.layer, 1))
-            player.layers[this.layer].upgrades = [
-              11,
-              12,
-              13,
-              14,
-              21,
-              22,
-              23,
-              24
-            ];
-          if (hasMilestone(this.layer, 3))
-            player.layers[this.layer].upgrades = [
-              11,
-              12,
-              13,
-              14,
-              21,
-              22,
-              23,
-              24,
-              31,
-              32,
-              33,
-              34,
-              41,
-              42,
-              43,
-              44,
-              51,
-              52,
-              53,
-              54,
-              61,
-              62,
-              63,
-              64
-            ];
-          if (!hasMilestone(this.layer, 2)) {
-            for (const c in layers[this.layer].challenges) {
-              player.layers[this.layer].challenges![c] = new Decimal(0);
-            }
-          }
-        },
-        unlocked() {
-          return (
-            (hasUpgrade(this.layer, 74) && hasUpgrade(this.layer, 64)) ||
-            hasMilestone(this.layer, 0)
-          );
-        }
-      },
-      12: {
-        cost() {
-          return new Decimal(1)
-            .times(
-              new Decimal(hasChallenge(this.layer, 21) ? 4 : 10)
-                .sub(hasUpgrade(this.layer, 122) ? 2 : 0)
-                .pow(player.layers.p.buyables![this.id])
-            )
-            .div(
-              hasUpgrade(this.layer, 224)
-                ? hasUpgrade("p", 132)
-                  ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(2))
-                  : hasUpgrade("p", 101)
-                  ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(3))
-                  : hasUpgrade("p", 93)
-                  ? (player.layers.p.gp as Decimal).plus(1).pow(0.2)
-                  : (player.layers.p.gp as Decimal).plus(1).log10()
-                : 1
-            );
-        },
-        display() {
-          return "Buy a generator for " + format(this.cost!) + " points";
-        },
-        canAfford() {
-          return player.points.gte(this.cost!) && hasMilestone(this.layer, 5);
-        },
-        buy() {
-          if (!hasMilestone("p", 13))
-            player.points = player.points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-          player.layers[this.layer].g = (player.layers[this.layer].g as Decimal).plus(1);
-        },
-        unlocked() {
-          return hasMilestone(this.layer, 5);
-        }
-      },
-      13: {
-        cost() {
-          return new Decimal(1)
-            .times(new Decimal(2).pow(player.layers.p.buyables![this.id]))
-            .div(
-              hasUpgrade(this.layer, 224)
-                ? hasUpgrade("p", 132)
-                  ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(2))
-                  : hasUpgrade("p", 101)
-                  ? (player.layers.p.gp as Decimal).plus(1).pow(new Decimal(1).div(3))
-                  : hasUpgrade("p", 93)
-                  ? (player.layers.p.gp as Decimal).plus(1).pow(0.2)
-                  : (player.layers.p.gp as Decimal).plus(1).log10()
-                : 1
-            );
-        },
-        display() {
-          return (
-            "Buy a generator for " + format(this.cost!) + " prestige points"
-          );
-        },
-        canAfford() {
-          return player.layers.p.points.gte(this.cost!) && hasUpgrade("p", 82);
-        },
-        buy() {
-          if (!hasMilestone("p", 13))
-            player.layers.p.points = player.layers.p.points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-          player.layers[this.layer].g = (player.layers[this.layer].g as Decimal).plus(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 82);
-        }
-      },
-      14: {
-        cost() {
-          return new Decimal(900)
-            .mul(new Decimal(1.01).pow(getBuyableAmount(this.layer, this.id)!))
-            .round()
-            .div(
-              hasUpgrade(this.layer, 234)
-                ? getBuyableAmount(this.layer, 23)!
-                    .pow(0.3)
-                    .plus(1)
-                : 1
-            );
-        },
-        display() {
-          return (
-            "Buy a generator for " + format(this.cost!) + " Infinity points"
-          );
-        },
-        canAfford() {
-          return player.layers.i.points.gte(this.cost!) && hasUpgrade("p", 232);
-        },
-        buy() {
-          if (!hasMilestone("p", 13))
-            player.layers.i.points = player.layers.i.points.sub(this.cost!).round();
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-          player.layers[this.layer].g = (player.layers[this.layer].g as Decimal).plus(1);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 232);
-        }
-      },
-      21: {
-        cost() {
-          return new Decimal(20).plus(
-            getBuyableAmount(this.layer, this.id)!.pow(
-              new Decimal(2).sub(
-                new Decimal(
-                  hasUpgrade(this.layer, 221)
-                    ? 0.9
-                    : hasUpgrade(this.layer, 214)
-                    ? 0.6
-                    : 0.3
-                ).times(
-                  hasUpgrade(this.layer, 212)
-                    ? new Decimal(1).sub(
-                        new Decimal(0.75).pow(getBuyableAmount(this.layer, 22)!)
-                      )
-                    : 0
-                )
-              )
-            )
-          );
-        },
-        display() {
-          return (
-            "Reset your generators for +1 pointy point! Cost: " +
-            format(this.cost!) +
-            " Generators"
-          );
-        },
-        canAfford() {
-          return (player.layers.p.g as Decimal).gte(this.cost!) && hasUpgrade("p", 104);
-        },
-        buy() {
-          if (!hasMilestone("i", 1)) player.layers.p.g = new Decimal(0);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-          if (!hasMilestone("i", 1))
-            setBuyableAmount(this.layer, 12, new Decimal(0));
-          if (!hasMilestone("i", 1))
-            setBuyableAmount(this.layer, 13, new Decimal(0));
-          if (!hasMilestone("i", 1)) player.layers.p.gp = new Decimal(0);
-        },
-        unlocked() {
-          return hasUpgrade(this.layer, 104);
-        }
-      },
-      22: {
-        cost() {
-          return new Decimal(8).plus(getBuyableAmount(this.layer, this.id)!);
-        },
-        display() {
-          return (
-            "Gain a pointy prestige point. Cost: " +
-            format(this.cost!) +
-            " Pointy Points"
-          );
-        },
-        canAfford() {
-          return (
-            getBuyableAmount(this.layer, 21)!.gte(this.cost!) &&
-            hasMilestone("i", 5)
-          );
-        },
-        buy() {
-          if (!hasUpgrade(this.layer, 233))
-            setBuyableAmount(
-              this.layer,
-              21,
-              getBuyableAmount(this.layer, 21)!.sub(this.cost!)
-            );
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-        },
-        unlocked() {
-          return hasMilestone("i", 5);
-        }
-      },
-      23: {
-        cost() {
-          return new Decimal(124).plus(
-            getBuyableAmount(this.layer, this.id)!
-              .times(2)
-              .pow(2)
-          );
-        },
-        display() {
-          return (
-            "Gain a booster. Cost: " + format(this.cost!) + " Pointy Points"
-          );
-        },
-        canAfford() {
-          return (
-            getBuyableAmount(this.layer, 21)!.gte(this.cost!) &&
-            hasMilestone("i", 5)
-          );
-        },
-        buy() {
-          if (!hasMilestone(this.layer, 15))
-            setBuyableAmount(
-              this.layer,
-              21,
-              getBuyableAmount(this.layer, 21)!.sub(this.cost!)
-            );
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-          if (!hasMilestone(this.layer, 15)) {
-            if (!hasMilestone(this.layer, 12)) {
-              player.layers.p.upgrades = player.layers.p.upgrades!.filter((x: string | Number) => {
-                return Number(x) < 200 || Number(x) > 230;
-              });
-              if (hasMilestone(this.layer, 11)) {
-                player.layers.p.upgrades.push(215);
-                player.layers.p.upgrades.push(225);
-                player.layers.p.upgrades.push(223);
-                player.layers.p.upgrades.push(222);
-              }
-            }
-            setBuyableAmount("p", 21, new Decimal(0));
-            setBuyableAmount("p", 22, new Decimal(0));
-            if (!hasUpgrade("p", 233)) {
-              setBuyableAmount("p", 12, new Decimal(0));
-              setBuyableAmount("p", 13, new Decimal(0));
-              setBuyableAmount("p", 14, new Decimal(0));
-
-              player.layers.p.g = new Decimal(0);
-            }
-            player.layers.p.gp = new Decimal(0);
-          }
-        },
-        unlocked() {
-          return hasUpgrade("p", 225) || getBuyableAmount("p", 23)!.gt(0);
-        }
-      },
-      31: {
-        cost() {
-          return new Decimal(1e93)
-            .times(new Decimal(1.5).pow(getBuyableAmount(this.layer, this.id)!))
-            .times(
-              new Decimal(1.1).pow(
-                getBuyableAmount(this.layer, this.id)!.pow(2)
-              )
-            );
-        },
-        effect() {
-          return new Decimal(2)
-            .plus(layers.p.buyables!.data[33].effect as Decimal)
-            .pow(
-              getBuyableAmount(this.layer, this.id)!.plus(
-                layers.p.buyables!.data[51].effect as Decimal
-              )
-            );
-        },
-        display() {
-          return (
-            "Double point gain. \nCurrently: x" +
-            format(this.effect as Decimal) +
-            "\nCost: " +
-            format(this.cost!) +
-            " Prestige points"
-          );
-        },
-        canAfford() {
-          return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13);
-        },
-        buy() {
-          player.layers.p.points = player.layers.p.points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-        },
-        unlocked() {
-          return hasMilestone("p", 13);
-        }
-      },
-      32: {
-        cost() {
-          return new Decimal(1e95)
-            .times(new Decimal(2).pow(getBuyableAmount(this.layer, this.id)!))
-            .times(
-              new Decimal(1.01).pow(
-                getBuyableAmount(this.layer, this.id)!.pow(2)
-              )
-            );
-        },
-        display() {
-          return (
-            "Double prestige point gain. \nCurrently: x" +
-            format(
-              new Decimal(2)
-                .plus(layers.p.buyables!.data[33].effect as Decimal)
-                .pow(getBuyableAmount(this.layer, this.id)!)
-            ) +
-            "\nCost: " +
-            format(this.cost!) +
-            " Prestige points"
-          );
-        },
-        canAfford() {
-          return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13);
-        },
-        buy() {
-          player.layers.p.points = player.layers.p.points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("p", 13) && getBuyableAmount(this.layer, 31)!.gte(5)
-          );
-        }
-      },
-      33: {
-        cost() {
-          return new Decimal(1e100)
-            .times(new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!))
-            .times(
-              new Decimal(1.01).pow(
-                getBuyableAmount(this.layer, this.id)!.pow(2)
-              )
-            );
-        },
-        effect() {
-          return new Decimal(0.01)
-            .mul(getBuyableAmount(this.layer, this.id)!)
-            .times(layers.p.buyables!.data[43].effect as Decimal);
-        },
-        display() {
-          return (
-            "Add 0.01 to the previous 2 buyable bases. \nCurrently: +" +
-            format(this.effect as Decimal) +
-            "\nCost: " +
-            format(this.cost!) +
-            " Prestige points"
-          );
-        },
-        canAfford() {
-          return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13);
-        },
-        buy() {
-          player.layers.p.points = player.layers.p.points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("p", 13) &&
-            (getBuyableAmount(this.layer, this.id)!.gt(0) ||
-              player.layers.p.points.gte(1e100))
-          );
-        }
-      },
-      41: {
-        cost() {
-          return new Decimal(1e110)
-            .times(new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!))
-            .times(
-              new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!.pow(2))
-            );
-        },
-        effect() {
-          return new Decimal(0.01).mul(
-            getBuyableAmount(this.layer, this.id)!.plus(
-              layers.p.buyables!.data[51].effect as Decimal
-            )
-          );
-        },
-        display() {
-          return (
-            "Add 0.01 to the booster effect base. \nCurrently: +" +
-            format(this.effect as Decimal) +
-            "\nCost: " +
-            format(this.cost!) +
-            " Prestige points"
-          );
-        },
-        canAfford() {
-          return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13);
-        },
-        buy() {
-          player.layers.p.points = player.layers.p.points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("p", 13) &&
-            (getBuyableAmount(this.layer, this.id)!.gt(0) ||
-              player.layers.p.points.gte(1e110))
-          );
-        }
-      },
-      42: {
-        cost() {
-          const c = new Decimal(1e270)
-            .times(new Decimal(2).pow(getBuyableAmount(this.layer, this.id)!))
-            .times(
-              new Decimal(1.01).pow(
-                getBuyableAmount(this.layer, this.id)!.pow(2)
-              )
-            );
-
-          return c;
-        },
-        effect() {
-          let f = new Decimal(1.001).pow(
-            getBuyableAmount(this.layer, this.id)!
-          );
-          if (f.gte(1.1)) f = f.pow(0.8).times(new Decimal(1.1).pow(0.2));
-          if (f.gte(1.35)) f = f.pow(0.5).times(new Decimal(1.35).pow(0.5));
-          if (f.gte(3)) f = new Decimal(3);
-          return f;
-        },
-        display() {
-          return (
-            "Raise point gain to the 1.001 \nCurrently: ^" +
-            format(this.effect as Decimal) +
-            ((this.effect as Decimal).eq(3) ? "(hardcapped)" : "") +
-            "\nCost: " +
-            format(this.cost!) +
-            " Prestige points"
-          );
-        },
-        canAfford() {
-          return (
-            player.layers.p.points.gte(this.cost!) &&
-            hasMilestone("p", 13) &&
-            (this.effect as Decimal).lt(3)
-          );
-        },
-        buy() {
-          player.layers.p.points = player.layers.p.points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("p", 13) &&
-            (getBuyableAmount(this.layer, this.id)!.gt(0) ||
-              player.layers.p.points.gte(1e270))
-          );
-        }
-      },
-      43: {
-        cost() {
-          return new Decimal("1e375")
-            .times(new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!))
-            .times(
-              new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!.pow(2))
-            );
-        },
-        effect() {
-          return new Decimal(0.01)
-            .mul(getBuyableAmount(this.layer, this.id)!)
-            .plus(1);
-        },
-        display() {
-          return (
-            "Multiply the above buyable effect. \nCurrently: *" +
-            format(this.effect as Decimal) +
-            "\nCost: " +
-            format(this.cost!) +
-            " Prestige points"
-          );
-        },
-        canAfford() {
-          return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13);
-        },
-        buy() {
-          player.layers.p.points = player.layers.p.points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("p", 13) &&
-            (getBuyableAmount(this.layer, this.id)!.gt(0) ||
-              player.layers.p.points.gte("1e375"))
-          );
-        }
-      },
-      51: {
-        cost() {
-          return new Decimal("1e1740")
-            .times(new Decimal(10).pow(getBuyableAmount(this.layer, this.id)!))
-            .times(
-              new Decimal(1e10).pow(
-                getBuyableAmount(this.layer, this.id)!.pow(2)
-              )
-            );
-        },
-        effect() {
-          return getBuyableAmount(this.layer, this.id)!.pow(0.55);
-        },
-        display() {
-          return (
-            "Add free levels to the above 2 buyables \nCurrently: " +
-            format(this.effect as Decimal) +
-            "\nCost: " +
-            format(this.cost!) +
-            " Prestige points"
-          );
-        },
-        canAfford() {
-          return player.layers.p.points.gte(this.cost!) && hasMilestone("p", 13);
-        },
-        buy() {
-          player.layers.p.points = player.layers.p.points.sub(this.cost!);
-          setBuyableAmount(
-            this.layer,
-            this.id,
-            getBuyableAmount(this.layer, this.id)!.add(1)
-          );
-        },
-        unlocked() {
-          return (
-            hasMilestone("p", 15) &&
-            (getBuyableAmount(this.layer, this.id)!.gt(0) ||
-              player.layers.p.points.gte("1e1700"))
-          );
-        }
-      }
-    }
-  },
-  milestones: {
-    data: {
-      0: {
-        requirementDisplay: "1 reset",
-        effectDisplay:
-          "Add 0.01 to base point gain and prestige requirement, and <b>1</b> doesn't reset upgrades",
-        done() {
-          return getBuyableAmount("p", 11)!.gte(1);
-        },
-        unlocked() {
-          return layers.p.activeSubtab?.id != "Pointy points";
-        }
-      },
-      1: {
-        requirementDisplay: "2 resets",
-        effectDisplay:
-          "<div><b>2</b> and <b>3</b> don't reset upgrades, and start with the first 8 upgrades on reset</div>",
-        done() {
-          return getBuyableAmount("p", 11)!.gte(2);
-        },
-        unlocked() {
-          return (
-            hasMilestone(this.layer, Number(this.id) - 1) &&
-            layers.p.activeSubtab?.id != "Pointy points"
-          );
-        }
-      },
-      2: {
-        requirementDisplay: "3 resets",
-        effectDisplay:
-          "<div><b>4</b> doesn't reset upgrades, and permanently fix the bug where you can't buy upgrades when you have 1 prestige point</div>",
-        done() {
-          return getBuyableAmount("p", 11)!.gte(3);
-        },
-        unlocked() {
-          return (
-            hasMilestone(this.layer, Number(this.id) - 1) &&
-            layers.p.activeSubtab?.id != "Pointy points"
-          );
-        }
-      },
-      3: {
-        requirementDisplay: "4 resets",
-        effectDisplay:
-          "Don't reset challenges, add 1 to <b>Point</b> maximum completions, and start with 24 upgrades",
-        done() {
-          return getBuyableAmount("p", 11)!.gte(4);
-        },
-        unlocked() {
-          return (
-            hasMilestone(this.layer, Number(this.id) - 1) &&
-            layers.p.activeSubtab?.id != "Pointy points"
-          );
-        }
-      },
-      4: {
-        requirementDisplay: "5 resets",
-        effectDisplay: "Each useless upgrade adds 0.1 to base point gain",
-        done() {
-          return getBuyableAmount("p", 11)!.gte(5);
-        },
-        unlocked() {
-          return (
-            hasMilestone(this.layer, Number(this.id) - 1) &&
-            layers.p.activeSubtab?.id != "Pointy points"
-          );
-        }
-      },
-      5: {
-        requirementDisplay: "6 resets",
-        effectDisplay: "Unlock something",
-        done() {
-          return getBuyableAmount("p", 11)!.gte(6);
-        },
-        unlocked() {
-          return (
-            hasMilestone(this.layer, Number(this.id) - 1) &&
-            layers.p.activeSubtab?.id != "Pointy points"
-          );
-        }
-      },
-      6: {
-        requirementDisplay: "1 pointy point",
-        effectDisplay: "Unlock the upgrade tree",
-        done() {
-          return getBuyableAmount("p", 21)!.gte(1);
-        },
-        unlocked() {
-          return (
-            hasMilestone(this.layer, Number(this.id) - 1) &&
-            (hasUpgrade(this.layer, 104) || player.layers.i.unlocked) &&
-            layers.p.activeSubtab?.id != "Pointy points"
-          );
-        }
-      },
-      7: {
-        requirementDisplay: "7 pointy points",
-        effectDisplay:
-          "You can now buy both first and second row upgrade tree upgrades",
-        done() {
-          return getBuyableAmount("p", 21)!.gte(7);
-        },
-        unlocked() {
-          return (
-            hasMilestone(this.layer, Number(this.id) - 1) &&
-            (hasUpgrade(this.layer, 111) || player.layers.i.unlocked) &&
-            layers.p.activeSubtab?.id != "Pointy points"
-          );
-        }
-      },
-      8: {
-        requirementDisplay: "8 pointy points",
-        effectDisplay: "Unlock another layer",
-        done() {
-          return getBuyableAmount("p", 21)!.gte(8);
-        },
-        unlocked() {
-          return (
-            hasMilestone(this.layer, Number(this.id) - 1) &&
-            (hasUpgrade(this.layer, 141) ||
-              hasUpgrade(this.layer, 143) ||
-              hasUpgrade(this.layer, 142) ||
-              player.layers.i.unlocked) &&
-            layers.p.activeSubtab?.id != "Pointy points"
-          );
-        }
-      },
-      11: {
-        requirementDisplay: "3 boosters",
-        effectDisplay: "Keep automation on booster reset",
-        done() {
-          return getBuyableAmount("p", 23)!.gte(3);
-        },
-        unlocked() {
-          return (
-            getBuyableAmount("p", 23)!.gt(0) ||
-            hasMilestone(this.layer, this.id)
-          );
-        }
-      },
-      12: {
-        requirementDisplay: "5 boosters",
-        effectDisplay:
-          "Keep all prestige upgrades on booster reset and buy max infinity points",
-        done() {
-          return getBuyableAmount("p", 23)!.gte(5);
-        },
-        unlocked() {
-          return (
-            getBuyableAmount("p", 23)!.gt(0) ||
-            hasMilestone(this.layer, this.id)
-          );
-        }
-      },
-      13: {
-        requirementDisplay: "10 boosters",
-        effectDisplay: "Generators cost nothing",
-        done() {
-          return getBuyableAmount("p", 23)!.gte(10);
-        },
-        unlocked() {
-          return (
-            getBuyableAmount("p", 23)!.gt(0) ||
-            hasMilestone(this.layer, this.id)
-          );
-        }
-      },
-      14: {
-        requirementDisplay: "15 boosters",
-        effectDisplay:
-          "Auto buy the first 3 buyables and buy max pointy prestige points",
-        done() {
-          return getBuyableAmount("p", 23)!.gte(15);
-        },
-        unlocked() {
-          return (
-            getBuyableAmount("p", 41)!.gt(0) ||
-            hasMilestone(this.layer, this.id)
-          );
-        }
-      },
-      15: {
-        requirementDisplay: "20 boosters",
-        effectDisplay: "Boosters reset nothing and auto booster",
-        done() {
-          return getBuyableAmount("p", 23)!.gte(16);
-        },
-        unlocked() {
-          return (
-            getBuyableAmount("p", 41)!.gt(0) ||
-            hasMilestone(this.layer, this.id)
-          );
-        }
-      }
-    }
-  },
-  passiveGeneration() {
-    return hasUpgrade("i", 11) ? 1 : 0;
-  },
-  update(diff) {
-    if (hasMilestone(this.layer, 2) && !hasUpgrade(this.layer, 54)) {
-      player.layers[this.layer].upgrades!.push(54);
-    }
-    if (
-      hasMilestone(this.layer, 1) &&
-      !hasUpgrade(this.layer, 11) &&
-      !hasMilestone(this.layer, 3)
-    ) {
-      player.layers[this.layer].upgrades = [11, 12, 13, 14, 21, 22, 23, 24];
-    }
-    if (hasMilestone(this.layer, 3) && !hasUpgrade(this.layer, 31)) {
-      player.layers[this.layer].upgrades = [
-        11,
-        12,
-        13,
-        14,
-        21,
-        22,
-        23,
-        24,
-        31,
-        32,
-        33,
-        34,
-        41,
-        42,
-        43,
-        44,
-        51,
-        52,
-        53,
-        54,
-        61,
-        62,
-        63,
-        64
-      ];
-    }
-    if (hasMilestone(this.layer, 5)) {
-      player.layers[this.layer].gp = (player.layers[this.layer].gp as Decimal).plus(
-        (player.layers.p.g as Decimal).times(diff).times(player.layers.p.geff as Decimal)
-      );
-    }
-    let geff = new Decimal(1);
-    if (hasUpgrade("p", 81)) geff = geff.plus(2);
-    if (hasUpgrade("p", 102))
-      geff = geff.plus(
-        hasChallenge("p", 22)
-          ? (player.layers.p.gp as Decimal).plus(1).log(10)
-          : (player.layers.p.gp as Decimal)
-              .plus(1)
-              .log(10)
-              .plus(1)
-              .log(10)
-      );
-    if (hasUpgrade("p", 83))
-      geff = geff.times(
-        player.layers.p.points
-          .plus(1)
-          .log(10)
-          .plus(1)
-      );
-    if (hasUpgrade("p", 94)) geff = geff.times(player.layers.p.cmult as Decimal);
-    if (hasUpgrade("p", 104))
-      geff = geff.times(new Decimal(player.layers.p.buyables![21]).plus(1));
-    if (hasUpgrade("p", 143))
-      geff = geff.times(new Decimal(player.timePlayed).div(3600).max(1));
-    if (hasUpgrade("p", 225))
-      geff = geff.pow(
-        new Decimal(player.layers.p.buyables![23])
-          .div(10)
-          .mul(
-            new Decimal(0.1)
-              .plus(layers.p.buyables!.data[41].effect as Decimal)
-              .times(10)
-          )
-          .plus(1)
-      );
-    player.layers.p.geff = geff;
-    if (hasChallenge("p", 22) && (!hasUpgrade("p", 141) || hasUpgrade("i", 12)))
-      player.layers.p.cmult = (player.layers.p.cmult as Decimal).plus(hasUpgrade("p", 141) ? 1 : 0.01);
-    if (!hasUpgrade("p", 111)) player.layers.p.cmult = (player.layers.p.cmult as Decimal).min(100);
-    if (hasMilestone(this.layer, 14)) {
-      if (layers.p.buyables!.data[31].canAfford)
-        layers.p.buyables!.data[31].buy();
-      if (layers.p.buyables!.data[32].canAfford)
-        layers.p.buyables!.data[32].buy();
-      if (layers.p.buyables!.data[33].canAfford)
-        layers.p.buyables!.data[33].buy();
-    }
-    if (hasMilestone(this.layer, 15)) {
-      if (layers.p.buyables!.data[23].canAfford)
-        layers.p.buyables!.data[23].buy();
-    }
-  },
-  subtabs: {
-    Upgrades: {
-      display: `
-				<main-display />
-				<spacer />
-				<prestige-button display="" />
-				<spacer />
-				<spacer />
-				<upgrades />`
-    },
-    Challenges: {
-      unlocked() {
-        return hasUpgrade("p", 51) || hasMilestone("p", 0);
-      },
-      display: `
-				<spacer />
-				<spacer />
-				<challenges />`
-    },
-    "Buyables and Milestones": {
-      unlocked() {
-        return hasUpgrade("p", 74) || hasMilestone("p", 0);
-      },
-      display: `
-				<spacer />
-				<spacer />
-				<row><buyable id="11" /></row>
-				<spacer />
-				<div v-if="hasMilestone('p', 0)">Your boosts are making the point challenge {{ getBuyableAmount('p', 11).plus(1) }}x less pointy</div>
-				<spacer />
-				<milestones />`
-    },
-    Generators: {
-      unlocked() {
-        return hasMilestone("p", 5) || player.layers.i.points.gte(1);
-      },
-      display: `
-				<spacer />
-				<div>You have {{ format(player.layers.p.gp) }} generator points, adding {{ format(hasUpgrade("p",132)?player.layers.p.gp.plus(1).pow(new Decimal(1).div(2)):hasUpgrade("p",101)?player.layers.p.gp.plus(1).pow(new Decimal(1).div(3)):hasUpgrade("p",93)?player.layers.p.gp.plus(1).pow(0.2):player.layers.p.gp.plus(1).log10()) }} to point gain</div>
-				<div>You have {{ format(player.layers.p.g) }} generators, generating {{ format(player.layers.p.g.times(player.layers.p.geff)) }} generator points per second</div>
-				<div>Generator efficiency is {{ format(player.layers.p.geff) }}</div>
-				<spacer />
-				<spacer />
-				<buyables :buyables="[12, 13, 14]" />
-				<row><clickable id="11" /></row>`
-    },
-    "Pointy Points": {
-      unlocked() {
-        return hasUpgrade("p", 104) || player.layers.i.points.gte(1);
-      },
-      display: `
-				<div style="color: red; font-size: 32px; font-family: Comic Sans MS">{{ format(player.layers.p.buyables[21]) }} pointy points</div>
-				<div style="color: red; font-size: 32px; font-family: Comic Sans MS">My pointy points are multiplying generator efficiency by {{ format(new Decimal(player.layers.p.buyables[21]).plus(1)) }}</div>
-				<spacer />
-				<spacer />
-				<row><buyable id="21" /></row>
-				<div v-if="hasMilestone('i', 5)" style="color: red; font-size: 32px; font-family: Comic Sans MS">I have {{ format(player.layers.p.buyables[22]) }} pointy prestige points</div>
-				<row><buyable id="22" /></row>
-				<spacer />
-				<upgrades :upgrades="[211, 212, 213, 214, 215]" />
-				<upgrades :upgrades="[221, 222, 223, 224, 225]" />
-				<div v-if="hasUpgrade('p', 225)" style="color: red; font-size: 32px; font-family: Comic Sans MS">I have {{ format(player.layers.p.buyables[23]) }} pointy boosters!</div>
-				<row><buyable id="23" /></row>
-				<div v-if="hasUpgrade('p', 225) || getBuyableAmount('p', 23).gt(0)" style="color: red; font-size: 32px; font-family: Comic Sans MS">My pointy boosters are raising generator efficiency to the ^{{ format(new Decimal(player.layers.p.buyables[23]).div(10).mul(new Decimal(0.1).plus(layers.p.buyables[41].effect).times(10)).plus(1)) }}</div>
-				<spacer />
-				<spacer />
-				<div v-if="hasMilestone('p', 11)" style="font-size: 24px">Booster upgrades</div>
-				<upgrades :upgrades="[231, 232, 233, 234, 235]" />`
-    },
-    Buyables: {
-      unlocked() {
-        return hasMilestone("p", 13);
-      },
-      display: `
-				<buyables :buyables="[31, 32, 33]" />
-				<buyables :buyables="[41, 42, 43]" />`
-    }
-  }
-} as RawLayer;
diff --git a/src/data/layers/prestige.tsx b/src/data/layers/prestige.tsx
new file mode 100644
index 0000000..d0dbb63
--- /dev/null
+++ b/src/data/layers/prestige.tsx
@@ -0,0 +1,56 @@
+import { main } from "@/data/mod";
+import { createCumulativeConversion, createExponentialScaling } from "@/features/conversion";
+import { jsx } from "@/features/feature";
+import { createReset } from "@/features/reset";
+import MainDisplay from "@/features/resources/MainDisplay.vue";
+import { createResource } from "@/features/resources/resource";
+import { createLayer } from "@/game/layers";
+import { DecimalSource } from "@/lib/break_eternity";
+import { render } from "@/util/vue";
+import { createLayerTreeNode, createResetButton } from "../common";
+
+const layer = createLayer(() => {
+    const id = "p";
+    const name = "Prestige";
+    const color = "#4BDC13";
+    const points = createResource<DecimalSource>(0, "prestige points");
+
+    const conversion = createCumulativeConversion(() => ({
+        scaling: createExponentialScaling(10, 5, 0.5),
+        baseResource: main.points,
+        gainResource: points,
+        roundUpCost: true
+    }));
+
+    const reset = createReset(() => ({
+        thingsToReset: (): Record<string, unknown>[] => [layer]
+    }));
+
+    const treeNode = createLayerTreeNode(() => ({
+        layerID: id,
+        color,
+        reset
+    }));
+
+    const resetButton = createResetButton(() => ({
+        conversion,
+        tree: main.tree,
+        treeNode
+    }));
+
+    return {
+        id,
+        name,
+        color,
+        points,
+        display: jsx(() => (
+            <>
+                <MainDisplay resource={points} color={color} />
+                {render(resetButton)}
+            </>
+        )),
+        treeNode
+    };
+});
+
+export default layer;
diff --git a/src/data/mod.tsx b/src/data/mod.tsx
index ad0600d..fa6f4e6 100644
--- a/src/data/mod.tsx
+++ b/src/data/mod.tsx
@@ -1,18 +1,15 @@
-import Profectus from "@/components/Profectus.vue";
 import Spacer from "@/components/layout/Spacer.vue";
 import { jsx } from "@/features/feature";
 import { createResource, trackBest, trackOOMPS, trackTotal } from "@/features/resources/resource";
 import { branchedResetPropagation, createTree, GenericTree } from "@/features/trees/tree";
 import { globalBus } from "@/game/events";
-import { createLayer, GenericLayer, setupLayerModal } from "@/game/layers";
+import { createLayer, GenericLayer } from "@/game/layers";
 import player, { PlayerData } from "@/game/player";
 import { DecimalSource } from "@/lib/break_eternity";
 import Decimal, { format, formatTime } from "@/util/bignum";
 import { render } from "@/util/vue";
 import { computed, toRaw } from "vue";
-import a from "./layers/aca/a";
-import c from "./layers/aca/c";
-import f from "./layers/aca/f";
+import prestige from "./layers/prestige";
 
 export const main = createLayer(() => {
     const points = createResource<DecimalSource>(10);
@@ -20,10 +17,7 @@ export const main = createLayer(() => {
     const total = trackTotal(points);
 
     const pointGain = computed(() => {
-        if (!c.generatorUpgrade.bought.value) return new Decimal(0);
-        let gain = new Decimal(3.19);
-        if (c.lollipopMultiplierUpgrade.bought.value)
-            gain = gain.times(c.lollipopMultiplierEffect.value);
+        let gain = new Decimal(1);
         return gain;
     });
     globalBus.on("update", diff => {
@@ -31,34 +25,17 @@ export const main = createLayer(() => {
     });
     const oomps = trackOOMPS(points, pointGain);
 
-    const { openModal, modal } = setupLayerModal(a);
-
-    // Note: Casting as generic tree to avoid recursive type definitions
     const tree = createTree(() => ({
-        nodes: [[c.treeNode], [f.treeNode, c.spook]],
-        leftSideNodes: [a.treeNode, c.h],
-        branches: [
-            {
-                startNode: f.treeNode,
-                endNode: c.treeNode,
-                stroke: "blue",
-                "stroke-width": "25px",
-                style: {
-                    filter: "blur(5px)"
-                }
-            }
-        ],
+        nodes: [[prestige.treeNode]],
+        branches: [],
         onReset() {
-            points.value = toRaw(this.resettingNode.value) === toRaw(c.treeNode) ? 0 : 10;
+            points.value = toRaw(this.resettingNode.value) === toRaw(prestige.treeNode) ? 0 : 10;
             best.value = points.value;
             total.value = points.value;
         },
         resetPropagation: branchedResetPropagation
     })) as GenericTree;
 
-    // Note: layers don't _need_ a reference to everything,
-    //  but I'd recommend it over trying to remember what does and doesn't need to be included.
-    // Officially all you need are anything with persistency or that you want to access elsewhere
     return {
         id: "main",
         name: "Tree",
@@ -79,28 +56,24 @@ export const main = createLayer(() => {
                 </div>
                 <div v-show={Decimal.gt(pointGain.value, 0)}>({oomps.value})</div>
                 <Spacer />
-                <button onClick={openModal}>open achievements</button>
-                {render(modal)}
                 {render(tree)}
-                <Profectus height="200px" style="margin: 10px auto; display: block" />
             </>
         )),
         points,
         best,
         total,
         oomps,
-        tree,
-        showAchievements: openModal
+        tree
     };
 });
 
 export const getInitialLayers = (
     /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
     player: Partial<PlayerData>
-): Array<GenericLayer> => [main, f, c, a];
+): Array<GenericLayer> => [main, prestige];
 
 export const hasWon = computed(() => {
-    return Decimal.gt(main.points.value, 25);
+    return false;
 });
 
 /* eslint-disable @typescript-eslint/no-unused-vars */
diff --git a/src/data/modInfo.json b/src/data/modInfo.json
index 7d67019..62b417c 100644
--- a/src/data/modInfo.json
+++ b/src/data/modInfo.json
@@ -1,6 +1,6 @@
 {
 	"title": "Profectus",
-	"id": "profectus-demo",
+	"id": "profectus",
 	"author": "thepaperpilot",
 	"discordName": "The Paper Pilot Community",
 	"discordLink": "https://discord.gg/WzejVAx",
@@ -13,8 +13,8 @@
 	"defaultDecimalsShown": 2,
 	"useHeader": true,
 	"banner": null,
-	"logo": "Logo.png",
-	"initialTabs": [ "main", "c" ],
+	"logo": "",
+	"initialTabs": [ "main" ],
 
 	"maxTickLength": 3600,
 	"offlineLimit": 1