From 8fff8f283545148a8fc93e8f4c67ee1032a2dd22 Mon Sep 17 00:00:00 2001
From: thepaperpilot <thepaperpilot@gmail.com>
Date: Tue, 17 Aug 2021 08:06:30 -0500
Subject: [PATCH] setup basic mod info

---
 saves/safff.txt                  |    1 -
 src/components/system/Tabs.vue   |    8 +-
 src/data/layers/aca/a.ts         |  103 --
 src/data/layers/aca/c.ts         |  573 --------
 src/data/layers/aca/f.ts         |  151 --
 src/data/layers/demo-infinity.ts |  354 -----
 src/data/layers/demo.ts          | 2301 ------------------------------
 src/data/layers/main.ts          |   11 +
 src/data/mod.ts                  |  156 +-
 src/data/modInfo.json            |    8 +-
 10 files changed, 25 insertions(+), 3641 deletions(-)
 delete mode 100644 saves/safff.txt
 delete mode 100644 src/data/layers/aca/a.ts
 delete mode 100644 src/data/layers/aca/c.ts
 delete mode 100644 src/data/layers/aca/f.ts
 delete mode 100644 src/data/layers/demo-infinity.ts
 delete mode 100644 src/data/layers/demo.ts
 create mode 100644 src/data/layers/main.ts

diff --git a/saves/safff.txt b/saves/safff.txt
deleted file mode 100644
index 7a1451d..0000000
--- a/saves/safff.txt
+++ /dev/null
@@ -1 +0,0 @@
-eyJpZCI6InRtdC14LTEwNSIsIm5hbWUiOiJEZWZhdWx0IFNhZmZmZiAtIHNvbWV0aGluZyBlbHNlIiwidGFicyI6WyJtYWluIiwiYyJdLCJ0aW1lIjoxNjI0MjQ1MjYxMDg3LCJhdXRvc2F2ZSI6dHJ1ZSwib2ZmbGluZVByb2QiOnRydWUsInRpbWVQbGF5ZWQiOiIzNDQ4LjYxNTc4MTcwOTAxIiwia2VlcEdvaW5nIjpmYWxzZSwibGFzdFRlblRpY2tzIjpbMC4wNTEsMC4wNSwwLjA0OSwwLjA1LDAuMDUsMC4wNTEsMC4wNDksMC4wNSwwLjA1LDAuMDUxXSwic2hvd1RQUyI6dHJ1ZSwibXNEaXNwbGF5IjoiYWxsIiwiaGlkZUNoYWxsZW5nZXMiOmZhbHNlLCJ0aGVtZSI6InBhcGVyIiwic3VidGFicyI6e30sIm1pbmltaXplZCI6e30sIm1vZElEIjoidG10LXgiLCJtb2RWZXJzaW9uIjoiMC4wIiwicG9pbnRzIjoiMzMwMC4zNzc3NzM4NTkwNTUiLCJtYWluIjp7InVwZ3JhZGVzIjpbXSwiYWNoaWV2ZW1lbnRzIjpbXSwibWlsZXN0b25lcyI6W10sImluZm9ib3hlcyI6e319LCJmIjp7InVwZ3JhZGVzIjpbXSwiYWNoaWV2ZW1lbnRzIjpbXSwibWlsZXN0b25lcyI6W10sImluZm9ib3hlcyI6e30sImNsaWNrYWJsZXMiOnsiMTEiOiJTdGFydCJ9LCJ1bmxvY2tlZCI6ZmFsc2UsInBvaW50cyI6IjAiLCJib29wIjpmYWxzZX0sImMiOnsidXBncmFkZXMiOlsiMTEiXSwiYWNoaWV2ZW1lbnRzIjpbXSwibWlsZXN0b25lcyI6W10sImluZm9ib3hlcyI6e30sImJ1eWFibGVzIjp7IjExIjoiMCJ9LCJjaGFsbGVuZ2VzIjp7IjExIjoiMCJ9LCJ1bmxvY2tlZCI6dHJ1ZSwicG9pbnRzIjoiMCIsImJlc3QiOiIxIiwidG90YWwiOiIwIiwiYmVlcCI6ZmFsc2UsInRoaW5neSI6InBvaW50eSIsIm90aGVyVGhpbmd5IjoxMCwic3BlbnRPbkJ1eWFibGVzIjoiMCJ9LCJhIjp7InVwZ3JhZGVzIjpbXSwiYWNoaWV2ZW1lbnRzIjpbIjExIl0sIm1pbGVzdG9uZXMiOltdLCJpbmZvYm94ZXMiOnt9LCJ1bmxvY2tlZCI6dHJ1ZSwicG9pbnRzIjoiMCJ9LCJnIjp7InVwZ3JhZGVzIjpbXSwiYWNoaWV2ZW1lbnRzIjpbXSwibWlsZXN0b25lcyI6W10sImluZm9ib3hlcyI6e319LCJoIjp7InVwZ3JhZGVzIjpbXSwiYWNoaWV2ZW1lbnRzIjpbXSwibWlsZXN0b25lcyI6W10sImluZm9ib3hlcyI6e319LCJzcG9vayI6eyJ1cGdyYWRlcyI6W10sImFjaGlldmVtZW50cyI6W10sIm1pbGVzdG9uZXMiOltdLCJpbmZvYm94ZXMiOnt9fSwib29tcHNNYWciOjAsImxhc3RQb2ludHMiOiIzMzAwLjM3Nzc3Mzg1OTA1NSJ9
\ No newline at end of file
diff --git a/src/components/system/Tabs.vue b/src/components/system/Tabs.vue
index 94fc880..ec69f0e 100644
--- a/src/components/system/Tabs.vue
+++ b/src/components/system/Tabs.vue
@@ -14,7 +14,7 @@
                     :layer="tab"
                     :index="index"
                     v-else-if="tab in components"
-                    :minimizable="true"
+                    :minimizable="minimizable[tab]"
                     :tab="() => $refs[`tab-${index}`]"
                 />
                 <component :is="tab" :index="index" v-else />
@@ -47,6 +47,12 @@ export default defineComponent({
                 },
                 {}
             );
+        },
+        minimizable() {
+            return Object.keys(layers).reduce((acc: Record<string, boolean>, curr) => {
+                acc[curr] = layers[curr].minimizable !== false;
+                return acc;
+            }, {});
         }
     }
 });
diff --git a/src/data/layers/aca/a.ts b/src/data/layers/aca/a.ts
deleted file mode 100644
index a18fdab..0000000
--- a/src/data/layers/aca/a.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-/* eslint-disable */
-import player from "@/game/player";
-import { GridCell } from "@/typings/features/grid";
-import { RawLayer } from "@/typings/layer";
-import Decimal from "@/util/bignum";
-
-export default {
-  id: "a",
-  startData() {
-    return {
-      unlocked: true,
-      points: new Decimal(0)
-    };
-  },
-  color: "yellow",
-  modal: true,
-  name: "Achievements",
-  resource: "achievement power",
-  row: "side",
-  tooltip() {
-    // Optional, tooltip displays when the layer is locked
-    return "Achievements";
-  },
-  achievementPopups: true,
-  achievements: {
-    data: {
-      11: {
-        image: "https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png",
-        name: "Get me!",
-        done() {
-          return true;
-        }, // This one is a freebie
-        goalTooltip: "How did this happen?", // Shows when achievement is not completed
-        doneTooltip: "You did it!" // Showed when the achievement is completed
-      },
-      12: {
-        name: "Impossible!",
-        done() {
-          return false;
-        },
-        goalTooltip: "Mwahahaha!", // Shows when achievement is not completed
-        doneTooltip: "HOW????", // Showed when the achievement is completed
-        style: { color: "#04e050" }
-      },
-      13: {
-        name: "EIEIO",
-        done() {
-          return player.layers.f.points.gte(1);
-        },
-        tooltip:
-          "Get a farm point.\n\nReward: The dinosaur is now your friend (you can max Farm Points).", // Showed when the achievement is completed
-        onComplete() {
-          console.log("Bork bork bork!");
-        }
-      }
-    }
-  },
-  midsection: "<grid id='test' />",
-  grids: {
-    data: {
-      test: {
-        maxRows: 3,
-        rows: 2,
-        cols: 2,
-        getStartData(cell: string) {
-          return cell;
-        },
-        getUnlocked() {
-          // Default
-          return true;
-        },
-        getCanClick() {
-          return player.points.eq(10);
-        },
-        getStyle(cell) {
-          return { backgroundColor: "#" + ((Number((this[cell] as GridCell).data) * 1234) % 999999) };
-        },
-        click(cell) {
-          // Don't forget onHold
-          (this[cell] as GridCell).data = ((this[cell] as GridCell).data as number) + 1;
-        },
-        getTitle(cell) {
-          let direction;
-          if (cell === "101") {
-            direction = "top";
-          } else if (cell === "102") {
-            direction = "bottom";
-          } else if (cell === "201") {
-            direction = "left";
-          } else if (cell === "202") {
-            direction = "right";
-          }
-          return `<tooltip display='${JSON.stringify(this.style)}' ${direction}>
-                        <h3>Gridable #${cell}</h3>
-                    </tooltip>`;
-        },
-        getDisplay(cell) {
-          return (this[cell] as GridCell).data;
-        }
-      }
-    }
-  }
-} as RawLayer;
diff --git a/src/data/layers/aca/c.ts b/src/data/layers/aca/c.ts
deleted file mode 100644
index b291172..0000000
--- a/src/data/layers/aca/c.ts
+++ /dev/null
@@ -1,573 +0,0 @@
-/* eslint-disable */
-import { Direction } from "@/game/enums";
-import { layers } from "@/game/layers";
-import player from "@/game/player";
-import { DecimalSource } from "@/lib/break_eternity";
-import { RawLayer } from "@/typings/layer";
-import Decimal, { format, formatWhole } from "@/util/bignum";
-import {
-  buyableEffect,
-  challengeCompletions,
-  getBuyableAmount,
-  hasMilestone,
-  hasUpgrade,
-  setBuyableAmount,
-  upgradeEffect
-} from "@/util/features";
-import { resetLayer, resetLayerData } from "@/util/layers";
-
-export default {
-  id: "c", // This is assigned automatically, both to the layer and all upgrades, etc. Shown here so you know about it
-  name: "Candies", // This is optional, only used in a few places, If absent it just uses the layer id.
-  symbol: "C", // This appears on the layer's node. Default is the id with the first letter capitalized
-  position: 0, // Horizontal position within a row. By default it uses the layer id and sorts in alphabetical order
-  startData() {
-    return {
-      unlocked: true,
-      points: new Decimal(0),
-      best: new Decimal(0),
-      total: new Decimal(0),
-      beep: false,
-      thingy: "pointy",
-      otherThingy: 10,
-      spentOnBuyables: new Decimal(0)
-    };
-  },
-  minWidth: 800,
-  color: "#4BDC13",
-  requires: new Decimal(10), // Can be a function that takes requirement increases into account
-  resource: "lollipops", // Name of prestige currency
-  baseResource: "points", // Name of resource prestige is based on
-  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
-  base: 5, // Only needed for static layers, base of the formula (b^(x^exp))
-  roundUpCost: false, // True if the cost needs to be rounded up (use when baseResource is static?)
-
-  // For normal layers, gain beyond [softcap] points is put to the [softcapPower]th power
-  softcap: new Decimal(1e100),
-  softcapPower: new Decimal(0.5),
-  canBuyMax() {}, // Only needed for static layers with buy max
-  gainMult() {
-    // Calculate the multiplier for main currency from bonuses
-    let mult = new Decimal(1);
-    /*
-    if (hasUpgrade(this.layer, 166)) mult = mult.times(2); // These upgrades don't exist
-    if (hasUpgrade(this.layer, 120))
-      mult = mult.times(upgradeEffect(this.layer, 120) as DecimalSource);
-    */
-    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)
-  effect() {
-    return {
-      // Formulas for any boosts inherent to resources in the layer. Can return a single value instead of an object if there is just one effect
-      waffleBoost: Decimal.pow(player.layers[this.layer].points, 0.2),
-      icecreamCap: player.layers[this.layer].points.times(10)
-    };
-  },
-  effectDisplay() {
-    // Optional text to describe the effects
-    const eff = this.effect as { waffleBoost: Decimal; icecreamCap: Decimal };
-    const waffleBoost = eff.waffleBoost.times(
-      (buyableEffect(this.layer, 11) as { first: Decimal, second: Decimal }).first
-    );
-    return (
-      "which are boosting waffles by " +
-      format(waffleBoost) +
-      " and increasing the Ice Cream cap by " +
-      format(eff.icecreamCap)
-    );
-  },
-  infoboxes: {
-    data: {
-      coolInfo: {
-        title: "Lore",
-        titleStyle: { color: "#FE0000" },
-        body: "DEEP LORE!",
-        bodyStyle: { "background-color": "#0000EE" }
-      }
-    }
-  },
-  milestones: {
-    data: {
-      0: {
-        requirementDisplay: "3 Lollipops",
-        done() {
-          return (player.layers[this.layer].best as Decimal).gte(3);
-        }, // Used to determine when to give the milestone
-        effectDisplay: "Unlock the next milestone"
-      },
-      1: {
-        requirementDisplay: "4 Lollipops",
-        unlocked() {
-          return hasMilestone(this.layer, 0);
-        },
-        done() {
-          return (player.layers[this.layer].best as Decimal).gte(4);
-        },
-        effectDisplay: "You can toggle beep and boop (which do nothing)",
-        optionsDisplay: `
-					<div style="display: flex; justify-content: center">
-						<Toggle :value="player.layers.c.beep" @change="value => player.layers.c.beep = value" />
-						<Toggle :value="player.layers.f.boop" @change="value => player.layers.f.boop = value" />
-					</div>
-				`,
-        style() {
-          if (hasMilestone(this.layer, this.id))
-            return {
-              backgroundColor: "#1111DD"
-            };
-        }
-      }
-    }
-  },
-  challenges: {
-    data: {
-      11: {
-        name: "Fun",
-        completionLimit: 3,
-        challengeDescription() {
-          return (
-            "Makes the game 0% harder<br>" +
-            challengeCompletions(this.layer, this.id) +
-            "/" +
-            this.completionLimit +
-            " completions"
-          );
-        },
-        unlocked() {
-          return (player.layers[this.layer].best as Decimal).gt(0);
-        },
-        goalDescription: "Have 20 points I guess",
-        canComplete() {
-          return player.points.gte(20);
-        },
-        effect() {
-          const ret = player.layers[this.layer].points.add(1).tetrate(0.02);
-          return ret;
-        },
-        rewardDisplay() {
-          return format(this.effect as Decimal) + "x";
-        },
-        countsAs: [12, 21], // Use this for if a challenge includes the effects of other challenges. Being in this challenge "counts as" being in these.
-        rewardDescription: "Says hi",
-        onComplete() {
-          console.log("hiii");
-        }, // Called when you successfully complete the challenge
-        onEnter() {
-          console.log("So challenging");
-        },
-        onExit() {
-          console.log("Sweet freedom!");
-        }
-      }
-    }
-  },
-  upgrades: {
-    data: {
-      11: {
-        title: "Generator of Genericness",
-        description: "Gain 1 Point every second.",
-        cost: new Decimal(1),
-        unlocked() {
-          return player.layers[this.layer].unlocked;
-        } // The upgrade is only visible when this is true
-      },
-      12: {
-        description:
-          "Point generation is faster based on your unspent Lollipops.",
-        cost: new Decimal(1),
-        unlocked() {
-          return hasUpgrade(this.layer, 11);
-        },
-        effect() {
-          // Calculate bonuses from the upgrade. Can return a single value or an object with multiple values
-          let ret = player.layers[this.layer].points
-            .add(1)
-            .pow(
-              player.layers[this.layer].upgrades!.includes(24)
-                ? 1.1
-                : player.layers[this.layer].upgrades!.includes(14)
-                ? 0.75
-                : 0.5
-            );
-          if (ret.gte("1e20000000")) ret = ret.sqrt().times("1e10000000");
-          return ret;
-        },
-        effectDisplay() {
-          return format(this.effect as Decimal) + "x";
-        } // Add formatting to the effect
-      },
-      13: {
-        unlocked() {
-          return hasUpgrade(this.layer, 12);
-        },
-        onPurchase() {
-          // This function triggers when the upgrade is purchased
-          player.layers[this.layer].unlockOrder = 0;
-        },
-        style() {
-          if (hasUpgrade(this.layer, this.id))
-            return {
-              "background-color": "#1111dd"
-            };
-          else if (!this.canAfford) {
-            return {
-              "background-color": "#dd1111"
-            };
-          } // Otherwise use the default
-        },
-        canAfford() {
-          return player.points.lte(7);
-        },
-        pay() {
-          player.points = player.points.add(7);
-        },
-        fullDisplay:
-          "Only buyable with less than 7 points, and gives you 7 more. Unlocks a secret subtab."
-      },
-      22: {
-        title: "This upgrade doesn't exist",
-        description: "Or does it?.",
-        currencyLocation() {
-          return player.layers[this.layer].buyables;
-        }, // The object in player data that the currency is contained in
-        currencyDisplayName: "exhancers", // Use if using a nonstandard currency
-        currencyInternalName: 11, // Use if using a nonstandard currency
-
-        cost: new Decimal(3),
-        unlocked() {
-          return player.layers[this.layer].unlocked;
-        } // The upgrade is only visible when this is true
-      }
-    }
-  },
-  buyables: {
-    showBRespecButton: true,
-    respec() {
-      // Optional, reset things and give back your currency. Having this function makes a respec button appear
-      player.layers[this.layer].points = player.layers[this.layer].points.add(
-        player.layers[this.layer].spentOnBuyables as Decimal
-      ); // A built-in thing to keep track of this but only keeps a single value
-      this.reset();
-      resetLayer(this.layer, true); // Force a reset
-    },
-    respecButtonDisplay: "Respec Thingies", // Text on Respec button, optional
-    respecWarningDisplay:
-      "Are you sure? Respeccing these doesn't accomplish much.",
-    data: {
-      11: {
-        title: "Exhancers", // Optional, displayed at the top in a larger font
-        cost() {
-          // cost for buying xth buyable, can be an object if there are multiple currencies
-          let x = this.amount;
-          if (x.gte(25)) x = x.pow(2).div(25);
-          const cost = Decimal.pow(2, x.pow(1.5));
-          return cost.floor();
-        },
-        effect() {
-          // Effects of owning x of the items, x is a decimal
-          const x = this.amount;
-          const eff = {} as { first?: Decimal; second?: Decimal };
-          if (x.gte(0)) eff.first = Decimal.pow(25, x.pow(1.1));
-          else eff.first = Decimal.pow(1 / 25, x.times(-1).pow(1.1));
-
-          if (x.gte(0)) eff.second = x.pow(0.8);
-          else
-            eff.second = x
-              .times(-1)
-              .pow(0.8)
-              .times(-1);
-          return eff;
-        },
-        display() {
-          // Everything else displayed in the buyable button after the title
-          return (
-            "Cost: " +
-            format(this.cost!) +
-            " lollipops\n\
-					Amount: " +
-            player.layers[this.layer].buyables![this.id] +
-            "/4\n\
-					Adds + " +
-            format((this.effect as { first: Decimal; second: Decimal }).first) +
-            " things and multiplies stuff by " +
-            format((this.effect as { first: Decimal; second: Decimal }).second)
-          );
-        },
-        unlocked() {
-          return player.layers[this.layer].unlocked;
-        },
-        canAfford() {
-          return player.layers[this.layer].points.gte(this.cost!);
-        },
-        buy() {
-          const cost = this.cost!;
-          player.layers[this.layer].points = player.layers[
-            this.layer
-          ].points.sub(cost);
-          player.layers[this.layer].buyables![this.id] = player.layers[
-            this.layer
-          ].buyables![this.id].add(1);
-          player.layers[this.layer].spentOnBuyables = (player.layers[
-            this.layer
-          ].spentOnBuyables as Decimal).add(cost); // This is a built-in system that you can use for respeccing but it only works with a single Decimal value
-        },
-        buyMax() {}, // You'll have to handle this yourself if you want
-        style: { height: "222px" },
-        purchaseLimit: new Decimal(4),
-        sellOne() {
-          const amount = getBuyableAmount(this.layer, this.id)!;
-          if (amount.lte(0)) return; // Only sell one if there is at least one
-          setBuyableAmount(this.layer, this.id, amount.sub(1));
-          player.layers[this.layer].points = player.layers[
-            this.layer
-          ].points.add(this.cost!);
-        }
-      }
-    }
-  },
-  onReset(resettingLayer: string) {
-    // Triggers when this layer is being reset, along with the layer doing the resetting. Not triggered by lower layers resetting, but is by layers on the same row.
-    if (
-      layers[resettingLayer].row != undefined &&
-      this.row != undefined &&
-      layers[resettingLayer].row! > this.row!
-    )
-      resetLayerData(this.layer, ["points"]); // This is actually the default behavior
-  },
-  automate() {}, // Do any automation inherent to this layer if appropriate
-  resetsNothing() {
-    return false;
-  },
-  onPrestige() {
-    return;
-  }, // Useful for if you gain secondary resources or have other interesting things happen to this layer when you reset it. You gain the currency after this function ends.
-
-  hotkeys: [
-    {
-      key: "c",
-      description: "reset for lollipops or whatever",
-      press() {
-        if (layers[this.layer].canReset) resetLayer(this.layer);
-      }
-    },
-    {
-      key: "ctrl+c",
-      description: "respec things",
-      press() {
-        layers[this.layer].buyables!.respec!();
-      },
-      unlocked() {
-        return hasUpgrade("c", "22");
-      }
-    }
-  ],
-  increaseUnlockOrder: [], // Array of layer names to have their order increased when this one is first unlocked
-
-  microtabs: {
-    stuff: {
-      data: {
-        first: {
-          display: `
-						<upgrades />
-						<div>confirmed</div>`
-        },
-        second: {
-          embedLayer: "f"
-        }
-      }
-    },
-    otherStuff: {
-      // There could be another set of microtabs here
-      data: {}
-    }
-  },
-
-  bars: {
-    data: {
-      longBoi: {
-        fillStyle: { "background-color": "#FFFFFF" },
-        baseStyle: { "background-color": "#696969" },
-        textStyle: { color: "#04e050" },
-
-        borderStyle() {
-          return {};
-        },
-        direction: Direction.Right,
-        width: 300,
-        height: 30,
-        progress() {
-          return player.points
-            .add(1)
-            .log(10)
-            .div(10)
-            .toNumber();
-        },
-        display() {
-          return format(player.points) + " / 1e10 points";
-        },
-        unlocked: true
-      },
-      tallBoi: {
-        fillStyle: { "background-color": "#4BEC13" },
-        baseStyle: { "background-color": "#000000" },
-        textStyle: { "text-shadow": "0px 0px 2px #000000" },
-
-        borderStyle() {
-          return { "border-width": "7px" };
-        },
-        direction: Direction.Up,
-        width: 50,
-        height: 200,
-        progress() {
-          return player.points.div(100);
-        },
-        display() {
-          return formatWhole(player.points.div(1).min(100)) + "%";
-        },
-        unlocked: true
-      },
-      flatBoi: {
-        fillStyle: { "background-color": "#FE0102" },
-        baseStyle: { "background-color": "#222222" },
-        textStyle: { "text-shadow": "0px 0px 2px #000000" },
-
-        borderStyle() {
-          return {};
-        },
-        direction: Direction.Up,
-        width: 100,
-        height: 30,
-        progress() {
-          return player.layers.c.points.div(50);
-        },
-        unlocked: true
-      }
-    }
-  },
-
-  // Optional, lets you format the tab yourself by listing components. You can create your own components in v.js.
-  subtabs: {
-    "main tab": {
-      buttonStyle() {
-        return { color: "orange" };
-      },
-      notify: true,
-      display: `
-				<main-display />
-				<sticky><prestige-button /></sticky>
-				<resource-display />
-				<spacer height="5px" />
-				<button onclick='console.log("yeet")'>'HI'</button>
-				<div>Name your points!</div>
-				<TextField :value="player.layers.c.thingy" @input="value => player.layers.c.thingy = value" :field="false" />
-				<sticky style="color: red; font-size: 32px; font-family: Comic Sans MS;">I have {{ format(player.points) }} {{ player.layers.c.thingy }} points!</sticky>
-				<hr />
-				<milestones />
-				<spacer />
-				<upgrades />
-				<challenges />`,
-      glowColor: "blue"
-    },
-    thingies: {
-      resetNotify: true,
-      style() {
-        return { "background-color": "#222222", "--background": "#222222" };
-      },
-      buttonStyle() {
-        return { "border-color": "orange" };
-      },
-      display: `
-				<buyables />
-				<spacer />
-				<row style="width: 600px; height: 350px; background-color: green; border-style: solid;">
-					<Toggle :value="player.layers.c.beep" @change="value => player.layers.c.beep = value" />
-					<spacer width="30px" height="10px" />
-					<div>Beep</div>
-					<spacer />
-					<vr height="200px"/>
-					<column>
-						<prestige-button style="width: 150px; height: 80px" />
-						<prestige-button style="width: 100px; height: 150px" />
-					</column>
-				</row>
-				<spacer />
-				<img src="https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png" />`
-    },
-    jail: {
-      display: `
-				<infobox id="coolInfo" />
-				<bar id="longBoi" />
-				<spacer />
-				<row>
-					<column style="background-color: #555555; padding: 15px">
-						<div style="color: teal">Sugar level:</div><spacer /><bar id="tallBoi" />
-					</column>
-					<spacer />
-					<column>
-						<div>idk</div>
-						<spacer width="0" height="50px" />
-						<bar id="flatBoi" />
-					</column>
-				</row>
-				<spacer />
-				<div>It's jail because "bars"! So funny! Ha ha!</div>
-				<tree :nodes="[['f', 'c'], ['g', 'spook', 'h']]" />`
-    },
-    illuminati: {
-      unlocked() {
-        return hasUpgrade("c", 13);
-      },
-      display: `
-				<h1> C O N F I R M E D </h1>
-				<spacer />
-				<microtab family="stuff" style="width: 660px; height: 370px; background-color: brown; --background: brown; border: solid white; margin: auto" />
-				<div>Adjust how many points H gives you!</div>
-				<Slider :value="player.layers.c.otherThingy" @change="value => player.c.otherThingy = value" :min="1" :max="30" />`
-    }
-  },
-  style() {
-    return {
-      //'background-color': '#3325CC'
-    };
-  },
-  nodeStyle() {
-    return {
-      // Style on the layer node
-      color: "#3325CC",
-      "text-decoration": "underline"
-    };
-  },
-  glowColor: "orange", // If the node is highlighted, it will be this color (default is red)
-  componentStyles: {
-    challenge() {
-      return { height: "200px" };
-    },
-    "prestige-button"() {
-      return { color: "#AA66AA" };
-    }
-  },
-  tooltip() {
-    // Optional, tooltip displays when the layer is unlocked
-    let tooltip = "{{ formatWhole(player.layers.c.points) }} {{ layers.c.resource }}";
-    if (player.layers[this.layer].buyables![11].gt(0))
-      tooltip +=
-        "<br><i><br><br><br>{{ formatWhole(player.layers.c.buyables![11]) }} Exhancers</i>";
-    return tooltip;
-  },
-  shouldNotify() {
-    // Optional, layer will be highlighted on the tree if true.
-    // Layer will automatically highlight if an upgrade is purchasable.
-    return player.layers.c.buyables![11] == new Decimal(1);
-  },
-  mark: "https://unsoftcapped2.github.io/The-Modding-Tree-2/discord.png",
-  resetDescription: "Melt your points into "
-} as RawLayer;
diff --git a/src/data/layers/aca/f.ts b/src/data/layers/aca/f.ts
deleted file mode 100644
index 95c2bdd..0000000
--- a/src/data/layers/aca/f.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-/* eslint-disable */
-import { layers as tmp } from "@/game/layers";
-import player from "@/game/player";
-import { RawLayer } from "@/typings/layer";
-import Decimal, { formatWhole } from "@/util/bignum";
-import { getClickableState } from "@/util/features";
-
-export default {
-  id: "f",
-  infoboxes: {
-    data: {
-      coolInfo: {
-        title: "Lore",
-        titleStyle: { color: "#FE0000" },
-        body: "DEEP LORE!",
-        bodyStyle: { "background-color": "#0000EE" }
-      }
-    }
-  },
-
-  startData() {
-    return {
-      unlocked: false,
-      points: new Decimal(0),
-      boop: false,
-      clickables: { [11]: "Start" } // Optional default Clickable state
-    };
-  },
-  color: "#FE0102",
-  requires() {
-    return new Decimal(10);
-  },
-  resource: "farm points",
-  baseResource: "points",
-  baseAmount() {
-    return player.points;
-  },
-  type: "static",
-  exponent: 0.5,
-  base: 3,
-  roundUpCost: true,
-  canBuyMax() {
-    return false;
-  },
-  name: "Farms",
-  //directMult() {return new Decimal(player.c.otherThingy)},
-
-  row: 1,
-  branches: [
-    {
-      target: "c",
-      "stroke-width": "25px",
-      stroke: "blue",
-      style: "filter: blur(5px)"
-    }
-  ], // When this layer appears, a branch will appear from this layer to any layers here. Each entry can be a pair consisting of a layer id and a color.
-
-  tooltipLocked() {
-    // Optional, tooltip displays when the layer is locked
-    return "This weird farmer dinosaur will only see you if you have at least {{layers.f.requires}} points. You only have {{ formatWhole(player.points) }}";
-  },
-  midsection:
-    '<div><br/><img src="https://images.beano.com/store/24ab3094eb95e5373bca1ccd6f330d4406db8d1f517fc4170b32e146f80d?auto=compress%2Cformat&dpr=1&w=390" /><div>Bork Bork!</div></div>',
-  // The following are only currently used for "custom" Prestige type:
-  prestigeButtonDisplay() {
-    //Is secretly HTML
-    if (!this.canBuyMax)
-      return (
-        "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(tmp[this.layer].nextAt) +
-        " points)"
-      );
-    if (this.canBuyMax)
-      return (
-        "Hi! I'm a <u>weird dinosaur</u> and I'll give you <b>" +
-        formatWhole(tmp[this.layer].resetGain) +
-        "</b> Farm Points in exchange for all of your points and lollipops! (You'll get another one at " +
-        formatWhole(tmp[this.layer].nextAt) +
-        " points)"
-      );
-  },
-  canReset() {
-    return Decimal.gte(tmp[this.layer].baseAmount!, tmp[this.layer].nextAt);
-  },
-  // This is also non minimal, a Clickable!
-  clickables: {
-    masterButtonClick() {
-      if (getClickableState(this.layer, 11) == "Borkened...")
-        player.layers[this.layer].clickables![11] = "Start";
-    },
-    masterButtonDisplay() {
-      return getClickableState(this.layer, 11) == "Borkened..."
-        ? "Fix the clickable!"
-        : "Does nothing";
-    }, // Text on Respec button, optional
-    data: {
-      11: {
-        title: "Clicky clicky!", // Optional, displayed at the top in a larger font
-        display() {
-          // Everything else displayed in the buyable button after the title
-          const data = getClickableState(this.layer, this.id);
-          return "Current state:<br>" + data;
-        },
-        unlocked() {
-          return player.layers[this.layer].unlocked;
-        },
-        canClick() {
-          return getClickableState(this.layer, this.id) !== "Borkened...";
-        },
-        click() {
-          switch (getClickableState(this.layer, this.id)) {
-            case "Start":
-              player.layers[this.layer].clickables![this.id] = "A new state!";
-              break;
-            case "A new state!":
-              player.layers[this.layer].clickables![this.id] = "Keep going!";
-              break;
-            case "Keep going!":
-              player.layers[this.layer].clickables![this.id] =
-                "Maybe that's a bit too far...";
-              break;
-            case "Maybe that's a bit too far...":
-              //makeParticles(coolParticle, 4)
-              player.layers[this.layer].clickables![this.id] = "Borkened...";
-              break;
-            default:
-              player.layers[this.layer].clickables![this.id] = "Start";
-              break;
-          }
-        },
-        hold() {
-          console.log("Clickkkkk...");
-        },
-        style() {
-          switch (getClickableState(this.layer, this.id)) {
-            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 {};
-          }
-        }
-      }
-    }
-  }
-} as RawLayer;
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 329ac6f..0000000
--- a/src/data/layers/demo.ts
+++ /dev/null
@@ -1,2301 +0,0 @@
-/* eslint-disable */
-import { layers } from "@/game/layers";
-import player from "@/game/player";
-import { DecimalSource } from "@/lib/break_eternity";
-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: {
-    rows: 999,
-    cols: 5,
-    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 (player.layers[this.layer].challenges![this.id] == new Decimal(1))
-            return 50;
-          if (player.layers[this.layer].challenges![this.id] == new Decimal(2))
-            return 60;
-          if (player.layers[this.layer].challenges![this.id] == new Decimal(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="hasMilestone('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="hasMilestone('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/main.ts b/src/data/layers/main.ts
new file mode 100644
index 0000000..0206502
--- /dev/null
+++ b/src/data/layers/main.ts
@@ -0,0 +1,11 @@
+import { RawLayer } from "@/typings/layer";
+
+export default {
+    id: "main",
+    display: `
+		<div v-if="player.devSpeed === 0">Game Paused</div>
+		<div v-else-if="player.devSpeed && player.devSpeed !== 1">Dev Speed: {{ format(player.devSpeed) }}x</div>
+        <div>TODO: Board</div>
+		`,
+    minimizable: false
+} as RawLayer;
diff --git a/src/data/mod.ts b/src/data/mod.ts
index 6dfbc4e..1c3ef96 100644
--- a/src/data/mod.ts
+++ b/src/data/mod.ts
@@ -1,97 +1,13 @@
-import { layers } from "@/game/layers";
-import player from "@/game/player";
 import { RawLayer } from "@/typings/layer";
 import { PlayerData } from "@/typings/player";
 import Decimal from "@/util/bignum";
-import {
-    getBuyableAmount,
-    hasMilestone,
-    hasUpgrade,
-    inChallenge,
-    upgradeEffect
-} from "@/util/features";
 import { computed } from "vue";
-import a from "./layers/aca/a";
-import c from "./layers/aca/c";
-import f from "./layers/aca/f";
-import demoLayer from "./layers/demo";
-import demoInfinityLayer from "./layers/demo-infinity";
-
-// Import initial layers
-
-const g = {
-    id: "g",
-    symbol: "TH",
-    branches: ["c"],
-    color: "#6d3678",
-    shown: true,
-    canClick() {
-        return player.points.gte(10);
-    },
-    tooltip: "Thanos your points",
-    click() {
-        player.points = player.points.div(2);
-        console.log(this.layer);
-    }
-} as RawLayer;
-const h = {
-    id: "h",
-    branches: [
-        "g",
-        () => ({
-            target: "flatBoi",
-            featureType: "bar",
-            endOffset: {
-                x:
-                    -50 +
-                    100 *
-                        (layers.c.bars!.data.flatBoi.progress instanceof Number
-                            ? (layers.c.bars!.data.flatBoi.progress as number)
-                            : (layers.c.bars!.data.flatBoi.progress as Decimal).toNumber())
-            }
-        })
-    ],
-    tooltip() {
-        return "Restore your points to {{ player.c.otherThingy }}";
-    },
-    row: "side",
-    position: 3,
-    canClick() {
-        return player.points.lt(player.layers.c.otherThingy as Decimal);
-    },
-    click() {
-        player.points = new Decimal(player.layers.c.otherThingy as Decimal);
-    }
-} as RawLayer;
-const spook = {
-    id: "spook",
-    row: 1,
-    layerShown: "ghost"
-} as RawLayer;
-
-const main = {
-    id: "main",
-    display: `
-		<div v-if="player.devSpeed === 0">Game Paused</div>
-		<div v-else-if="player.devSpeed && player.devSpeed !== 1">Dev Speed: {{ format(player.devSpeed) }}x</div>
-		<div v-if="player.offTime != undefined">Offline Time: {{ formatTime(player.offTime.remain) }}</div>
-		<div>
-			<span v-if="player.points.lt('1e1000')">You have </span>
-			<h2>{{ format(player.points) }}</h2>
-			<span v-if="player.points.lt('1e1e6')"> points</span>
-		</div>
-		<div v-if="Decimal.gt(pointGain, 0)">
-			({{ player.oompsMag != 0 ? format(player.oomps) + " OOM" + (player.oompsMag < 0 ? "^OOM" : player.oompsMag > 1 ? "^" + player.oompsMag : "") + "s" : formatSmall(pointGain) }}/sec)
-		</div>
-		<spacer />
-		<tree :append="true" />`,
-    name: "Tree"
-} as RawLayer;
+import main from "./layers/main";
 
 export const getInitialLayers = (
     /* eslint-disable-next-line @typescript-eslint/no-unused-vars */
     playerData: Partial<PlayerData>
-): Array<RawLayer> => [main, f, c, a, g, h, spook, demoLayer, demoInfinityLayer];
+): Array<RawLayer> => [main];
 
 export function getStartingData(): Record<string, unknown> {
     return {
@@ -104,73 +20,7 @@ export const hasWon = computed(() => {
 });
 
 export const pointGain = computed(() => {
-    if (!hasUpgrade("c", 11)) return new Decimal(0);
-    let gain = new Decimal(3.19);
-    if (hasUpgrade("c", 12)) gain = gain.times(upgradeEffect("c", 12) as Decimal);
-    if (hasMilestone("p", 0)) gain = gain.plus(0.01);
-    if (hasMilestone("p", 4)) {
-        if (hasUpgrade("p", 12)) gain = gain.plus(0.1);
-        if (hasUpgrade("p", 13)) gain = gain.plus(0.1);
-        if (hasUpgrade("p", 14)) gain = gain.plus(0.1);
-        if (hasUpgrade("p", 21)) gain = gain.plus(0.1);
-        if (hasUpgrade("p", 22)) gain = gain.plus(0.1);
-        if (hasUpgrade("p", 23)) gain = gain.plus(0.1);
-        if (hasUpgrade("p", 31)) gain = gain.plus(0.1);
-        if (hasUpgrade("p", 32)) gain = gain.plus(0.1);
-        if (hasUpgrade("p", 33)) gain = gain.plus(0.1);
-    }
-    if (hasUpgrade("p", 11))
-        gain = gain.plus(
-            hasUpgrade("p", 34)
-                ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal)
-                : 1
-        );
-    if (hasUpgrade("p", 12))
-        gain = gain.times(
-            hasUpgrade("p", 34)
-                ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal)
-                : 1
-        );
-    if (hasUpgrade("p", 13))
-        gain = gain.pow(
-            hasUpgrade("p", 34)
-                ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal)
-                : 1
-        );
-    if (hasUpgrade("p", 14))
-        gain = gain.tetrate(
-            hasUpgrade("p", 34)
-                ? new Decimal(1).plus(layers.p.upgrades!.data[34].effect as Decimal).toNumber()
-                : 1
-        );
-
-    if (hasUpgrade("p", 71)) gain = gain.plus(1.1);
-    if (hasUpgrade("p", 72)) gain = gain.times(1.1);
-    if (hasUpgrade("p", 73)) gain = gain.pow(1.1);
-    if (hasUpgrade("p", 74)) gain = gain.tetrate(1.1);
-    if (hasMilestone("p", 5) && !inChallenge("p", 22)) {
-        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();
-        gain = gain.plus(asdf);
-        if (hasUpgrade("p", 213)) gain = gain.mul(asdf.plus(1));
-    }
-    if (hasUpgrade("p", 104)) gain = gain.times(player.layers.p.points.plus(1).pow(0.5));
-    if (hasUpgrade("p", 142)) gain = gain.times(5);
-    if (player.layers.i.unlocked)
-        gain = gain.times(player.layers.i.points.plus(1).pow(hasUpgrade("p", 235) ? 6.942 : 1));
-    if (inChallenge("p", 11) || inChallenge("p", 21))
-        gain = new Decimal(10).pow(gain.log10().pow(0.75));
-    if (inChallenge("p", 12) || inChallenge("p", 21))
-        gain = gain.pow(new Decimal(1).sub(new Decimal(1).div(getBuyableAmount("p", 11)!.plus(1))));
-    if (hasUpgrade("p", 211)) gain = gain.times(getBuyableAmount("p", 21)!.plus(1));
-    if (hasMilestone("p", 13)) gain = gain.times(layers.p.buyables!.data[31].effect as Decimal);
-    if (hasMilestone("p", 13)) gain = gain.pow(layers.p.buyables!.data[42].effect as Decimal);
-    return gain;
+    return new Decimal(0);
 });
 
 /* eslint-disable @typescript-eslint/no-unused-vars */
diff --git a/src/data/modInfo.json b/src/data/modInfo.json
index 8a6d164..42c9ed0 100644
--- a/src/data/modInfo.json
+++ b/src/data/modInfo.json
@@ -1,6 +1,6 @@
 {
-	"title": "The Modding Tree X",
-	"id": "tmt-x",
+	"title": "Side Project",
+	"id": "side-project",
 	"author": "thepaperpilot",
 	"discordName": "The Paper Pilot Community",
 	"discordLink": "https://discord.gg/WzejVAx",
@@ -14,8 +14,8 @@
 	"useHeader": true,
 	"banner": null,
 	"logo": null,
-	"initialTabs": [ "main", "c" ],
+	"initialTabs": [ "main" ],
 
 	"maxTickLength": 3600,
-	"offlineLimit": 1
+	"offlineLimit": 0
 }