forked from OpenWF/SpaceNinjaServer
		
	feat(webui): add options to add and remove archon shard upgrades (#437)
This commit is contained in:
		
							parent
							
								
									b7bf40ebe5
								
							
						
					
					
						commit
						afbc1801f6
					
				@ -13,10 +13,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => {
 | 
			
		||||
            const request = getJSONfromString(String(req.body)) as IShardInstallRequest;
 | 
			
		||||
            const inventory = await getInventory(accountId);
 | 
			
		||||
            const suit = inventory.Suits.find(suit => suit._id.toString() == request.SuitId.$oid)!;
 | 
			
		||||
            if (
 | 
			
		||||
                !suit.ArchonCrystalUpgrades ||
 | 
			
		||||
                suit.ArchonCrystalUpgrades.length != 5 // we shouldn't have an array like this, but older inventories may disagree...
 | 
			
		||||
            ) {
 | 
			
		||||
            if (!suit.ArchonCrystalUpgrades || suit.ArchonCrystalUpgrades.length != 5) {
 | 
			
		||||
                suit.ArchonCrystalUpgrades = [{}, {}, {}, {}, {}];
 | 
			
		||||
            }
 | 
			
		||||
            suit.ArchonCrystalUpgrades[request.Slot] = {
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@ import {
 | 
			
		||||
    ExportWarframes,
 | 
			
		||||
    ExportWeapons
 | 
			
		||||
} from "warframe-public-export-plus";
 | 
			
		||||
import archonCrystalUpgrades from "@/static/fixed_responses/webuiArchonCrystalUpgrades.json";
 | 
			
		||||
 | 
			
		||||
interface ListedItem {
 | 
			
		||||
    uniqueName: string;
 | 
			
		||||
@ -77,7 +78,8 @@ const getItemListsController: RequestHandler = (_req, res) => {
 | 
			
		||||
        weapons,
 | 
			
		||||
        miscitems,
 | 
			
		||||
        mods,
 | 
			
		||||
        badItems
 | 
			
		||||
        badItems,
 | 
			
		||||
        archonCrystalUpgrades
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								src/controllers/custom/popArchonCrystalUpgradeController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/controllers/custom/popArchonCrystalUpgradeController.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
export const popArchonCrystalUpgradeController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const inventory = await getInventory(accountId);
 | 
			
		||||
    const suit = inventory.Suits.find(suit => suit._id.toString() == (req.query.oid as string));
 | 
			
		||||
    if (suit && suit.ArchonCrystalUpgrades) {
 | 
			
		||||
        suit.ArchonCrystalUpgrades = suit.ArchonCrystalUpgrades.filter(
 | 
			
		||||
            x => x.UpgradeType != (req.query.type as string)
 | 
			
		||||
        );
 | 
			
		||||
        await inventory.save();
 | 
			
		||||
        res.end();
 | 
			
		||||
    }
 | 
			
		||||
    res.status(400).end();
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										20
									
								
								src/controllers/custom/pushArchonCrystalUpgradeController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/controllers/custom/pushArchonCrystalUpgradeController.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
export const pushArchonCrystalUpgradeController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const inventory = await getInventory(accountId);
 | 
			
		||||
    const suit = inventory.Suits.find(suit => suit._id.toString() == (req.query.oid as string));
 | 
			
		||||
    if (suit) {
 | 
			
		||||
        suit.ArchonCrystalUpgrades ??= [];
 | 
			
		||||
        const count = (req.query.count as number | undefined) ?? 1;
 | 
			
		||||
        for (let i = 0; i != count; ++i) {
 | 
			
		||||
            suit.ArchonCrystalUpgrades.push({ UpgradeType: req.query.type as string });
 | 
			
		||||
        }
 | 
			
		||||
        await inventory.save();
 | 
			
		||||
        res.end();
 | 
			
		||||
    }
 | 
			
		||||
    res.status(400).end();
 | 
			
		||||
};
 | 
			
		||||
@ -1,13 +1,20 @@
 | 
			
		||||
import express from "express";
 | 
			
		||||
 | 
			
		||||
import { getItemListsController } from "@/src/controllers/custom/getItemListsController";
 | 
			
		||||
import { pushArchonCrystalUpgradeController } from "@/src/controllers/custom/pushArchonCrystalUpgradeController";
 | 
			
		||||
import { popArchonCrystalUpgradeController } from "@/src/controllers/custom/popArchonCrystalUpgradeController";
 | 
			
		||||
 | 
			
		||||
import { createAccountController } from "@/src/controllers/custom/createAccountController";
 | 
			
		||||
import { addItemController } from "@/src/controllers/custom/addItemController";
 | 
			
		||||
 | 
			
		||||
import { getConfigDataController } from "@/src/controllers/custom/getConfigDataController";
 | 
			
		||||
import { updateConfigDataController } from "@/src/controllers/custom/updateConfigDataController";
 | 
			
		||||
 | 
			
		||||
const customRouter = express.Router();
 | 
			
		||||
 | 
			
		||||
customRouter.get("/getItemLists", getItemListsController);
 | 
			
		||||
customRouter.get("/pushArchonCrystalUpgrade", pushArchonCrystalUpgradeController);
 | 
			
		||||
customRouter.get("/popArchonCrystalUpgrade", popArchonCrystalUpgradeController);
 | 
			
		||||
 | 
			
		||||
customRouter.post("/createAccount", createAccountController);
 | 
			
		||||
customRouter.post("/addItem", addItemController);
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,9 @@ webuiRouter.use("/webui", (req, res, next) => {
 | 
			
		||||
webuiRouter.get("/webui/inventory", (_req, res) => {
 | 
			
		||||
    res.sendFile(path.join(rootDir, "static/webui/index.html"));
 | 
			
		||||
});
 | 
			
		||||
webuiRouter.get(/webui\/powersuit\/(.+)/, (_req, res) => {
 | 
			
		||||
    res.sendFile(path.join(rootDir, "static/webui/index.html"));
 | 
			
		||||
});
 | 
			
		||||
webuiRouter.get("/webui/mods", (_req, res) => {
 | 
			
		||||
    res.sendFile(path.join(rootDir, "static/webui/index.html"));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										81
									
								
								static/fixed_responses/webuiArchonCrystalUpgrades.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								static/fixed_responses/webuiArchonCrystalUpgrades.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,81 @@
 | 
			
		||||
{
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeEquilibrium": "+20% Energy from Health pickups, +20% Health from Energy pickups",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeEquilibriumMythic": "+30% Energy from Health pickups, +30% Health from Energy pickups",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeMeleeCritDamage": "+25% Melee Critical Damage",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeMeleeCritDamageMythic": "+37.5% Melee Critical Damage",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradePrimaryStatusChance": "+25% Primary Status Chance",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradePrimaryStatusChanceMythic": "+37.5% Primary Status Chance",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeSecondaryCritChance": "+25% Secondary Critical Chance",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeSecondaryCritChanceMythic": "+37.5% Secondary Critical Chance",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityDuration": "+10% Ability Duration",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityDurationMythic": "+15% Ability Duration",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityStrength": "+10% Ability Strength",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeAbilityStrengthMythic": "+15% Ability Strength",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeArmourMax": "+150 Armor",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeArmourMaxMythic": "+225 Armor",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeBlastProc": "+5 Shields on inflicting Blast Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeBlastProcMythic": "+7.5 Shields on inflicting Blast Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCastingSpeed": "+25% Casting Speed",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCastingSpeedMythic": "+37.5% Casting Speed",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveDamageBoost": "+10% Ability Damage on enemies affected by Corrosion Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveDamageBoostMythic": "+15% Ability Damage on enemies affected by Corrosion Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveStack": "Increase max stacks of Corrosion Status by +2",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCorrosiveStackMythic": "Increase max stacks of Corrosion Status by +3",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCritDamageBoost": "+25% Melee Critical Damage (Doubles over 500 Energy)",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeCritDamageBoostMythic": "+37% Melee Critical Damage (Doubles over 500 Energy)",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamage": "+30% Primary Electricity Damage (+10% per additional Shard)",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamageMythic": "+45% Primary Electricity Damage (+15% per additional Shard)",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamageBoost": "+10% Ability Damage on enemies affected by Electricity Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeElectricDamageBoostMythic": "+15% Ability Damage on enemies affected by Electricity Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeEnergyMax": "+50 Energy Max",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeEnergyMaxMythic": "+75 Energy Max",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectEnergy": "+50% Energy Orb Effectiveness",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectEnergyMythic": "+75% Energy Orb Effectiveness",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectHealth": "+100% Health Orb Effectiveness",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeGlobeEffectHealthMythic": "+150% Health Orb Effectiveness",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHealthMax": "+150 Health",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHealthMaxMythic": "+225 Health",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHPBoostFromImpact": "+1 Health per enemy killed with Blast Damage (Max 300 Health)",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeHPBoostFromImpactMythic": "+2 Health per enemy killed with Blast Damage (Max 450 Health)",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeParkourVelocity": "+15% Parkour Velocity",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeParkourVelocityMythic": "+22.5% Parkour Velocity",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRadiationDamageBoost": "+10% Ability Damage on enemies affected by Radiation Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRadiationDamageBoostMythic": "+15% Ability Damage on enemies affected by Radiation Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRegen": "+5 Health Regen/s",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeRegenMythic": "+7.5 Health Regen/s",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeShieldMax": "+150 Shield",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeShieldMaxMythic": "+225 Shield",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeStartingEnergy": "+30% Energy on Spawn",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeStartingEnergyMythic": "+45% Energy on Spawn",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinDamage": "+30% Toxin Status Effect Damage",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinDamageMythic": "+45% Toxin Status Effect Damage",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinHeal": "+2 Health on damaging enemies with Toxin Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeToxinHealMythic": "+3 Health on damaging enemies with Toxin Status",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWeaponCritBoostFromHeat": "+1% Secondary Critical Chance per Heat-affected enemy killed (Max 50%)",
 | 
			
		||||
  "/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWeaponCritBoostFromHeatMythic": "+1.5% Secondary Critical Chance per Heat-affected enemy killed (Max 75%)",
 | 
			
		||||
 | 
			
		||||
  "/Lotus/Upgrades/Mods/Warframe/AvatarEnergyRegenMod": "+0.5 Energy Regen/s",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/Warframe/AvatarEnemyRadarMod": "+5m Enemy Radar",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/Warframe/AvatarLootRadarMod": "+7m Loot Radar",
 | 
			
		||||
 | 
			
		||||
  "/Lotus/Upgrades/Mods/Rifle/WeaponAmmoMaxMod": "+15% Ammo Max",
 | 
			
		||||
 | 
			
		||||
  "/Lotus/Upgrades/Mods/Aura/EnemyArmorReductionAuraMod": "-3% Enemy Armor",
 | 
			
		||||
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionAmmoMod": "100% Primary and Secondary Magazine Refill on Mercy",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionHealthDropMod": "100% chance to drop a Health Orb on Mercy",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionEnergyDropMod": "50% chance to drop an Energy Orb on Mercy",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnFailHackResetMod": "+50% to retry on Hacking failure",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Cipher/DamageReductionOnHackMod": "75% Damage Reduction while Hacking",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionReviveCompanionMod": "Mercy Kills reduce Companion Recovery by 15s",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionParkourSpeedMod": "+60% Parkour Speed after a Mercy for 15s",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/Warframe/AvatarTimeLimitIncreaseMod": "+8s to Hacking",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Cipher/ElectrifyOnHackMod": "Shock enemies within 20m while Hacking",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionTerrifyMod": "50% chance for enemies within 15m to cower in fear for 8 seconds on Mercy",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnHackLockersMod": "Unlock 5 lockers within 20m after Hacking",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionBlindMod": "Blind enemies within 18m on Mercy",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Assassin/OnExecutionDrainPowerMod": "100% chance for next ability cast to gain +50% Ability Strength on Mercy",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnHackSprintSpeedMod": "+75% Sprint Speed for 15s after Hacking",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Assassin/SwiftExecuteMod": "Speed of Mercy Kills increased by 50%",
 | 
			
		||||
  "/Lotus/Upgrades/Mods/DataSpike/Cipher/OnHackInvisMod": "Invisible for 15 seconds after hacking"
 | 
			
		||||
}
 | 
			
		||||
@ -3,8 +3,8 @@
 | 
			
		||||
<head>
 | 
			
		||||
    <title>OpenWF WebUI</title>
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1" />
 | 
			
		||||
    <link rel="stylesheet" href="libs/bootstrap.min.css" />
 | 
			
		||||
    <link rel="stylesheet" href="style.css" />
 | 
			
		||||
    <link rel="stylesheet" href="/webui/libs/bootstrap.min.css" />
 | 
			
		||||
    <link rel="stylesheet" href="/webui/style.css" />
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <nav class="navbar sticky-top bg-body-tertiary">
 | 
			
		||||
@ -63,7 +63,7 @@
 | 
			
		||||
                </form>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div data-route="/webui/inventory" data-title="Inventory | OpenWF WebUI">
 | 
			
		||||
                <p id="refresh-note" class="mb-4">
 | 
			
		||||
                <p class="mb-4">
 | 
			
		||||
                    Note: Changes made here will only be reflected in-game when the game re-downloads your
 | 
			
		||||
                    inventory. Visiting the navigation should be the easiest way to trigger that.
 | 
			
		||||
                </p>
 | 
			
		||||
@ -106,8 +106,27 @@
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div id="powersuit-route" data-route="~ /webui/powersuit/(.+)" data-title="Inventory | OpenWF WebUI">
 | 
			
		||||
                <h3 class="mb-0"></h3>
 | 
			
		||||
                <p class="text-body-secondary"></p>
 | 
			
		||||
                <div class="card mb-4">
 | 
			
		||||
                    <h5 class="card-header">Archon Shard Slots</h5>
 | 
			
		||||
                    <div class="card-body">
 | 
			
		||||
                        <p>You can use these unlimited slots to apply a wide range of upgrades.</p>
 | 
			
		||||
                        <form class="input-group mb-3" onsubmit="doPushArchonCrystalUpgrade();return false;">
 | 
			
		||||
                            <input type="number" id="archon-crystal-add-count" min="1" value="1" class="form-control" style="max-width:100px" />
 | 
			
		||||
                            <span class="input-group-text">x</span>
 | 
			
		||||
                            <input class="form-control" list="datalist-archonCrystalUpgrades" />
 | 
			
		||||
                            <button class="btn btn-primary" type="submit">Add</button>
 | 
			
		||||
                        </form>
 | 
			
		||||
                        <table class="table table-hover w-100">
 | 
			
		||||
                            <tbody id="crystals-list"></tbody>
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div data-route="/webui/mods" data-title="Mods | OpenWF WebUI">
 | 
			
		||||
                <p id="refresh-note" class="mb-4">
 | 
			
		||||
                <p class="mb-4">
 | 
			
		||||
                    Note: Changes made here will only be reflected in-game when the game re-downloads your
 | 
			
		||||
                    inventory. Visiting the navigation should be the easiest way to trigger that.
 | 
			
		||||
                </p>
 | 
			
		||||
@ -259,11 +278,12 @@
 | 
			
		||||
    <datalist id="datalist-weapons"></datalist>
 | 
			
		||||
    <datalist id="datalist-miscitems"></datalist>
 | 
			
		||||
    <datalist id="datalist-mods"></datalist>
 | 
			
		||||
    <script src="libs/jquery-3.6.0.min.js"></script>
 | 
			
		||||
    <script src="libs/whirlpool-js.min.js"></script>
 | 
			
		||||
    <script src="libs/single.js"></script>
 | 
			
		||||
    <script src="riven-tool/RivenParser.js"></script>
 | 
			
		||||
    <script src="script.js"></script>
 | 
			
		||||
    <script src="libs/bootstrap.bundle.min.js"></script>
 | 
			
		||||
    <datalist id="datalist-archonCrystalUpgrades"></datalist>
 | 
			
		||||
    <script src="/webui/libs/jquery-3.6.0.min.js"></script>
 | 
			
		||||
    <script src="/webui/libs/whirlpool-js.min.js"></script>
 | 
			
		||||
    <script src="/webui/libs/single.js"></script>
 | 
			
		||||
    <script src="/webui/riven-tool/RivenParser.js"></script>
 | 
			
		||||
    <script src="/webui/script.js"></script>
 | 
			
		||||
    <script src="/webui/libs/bootstrap.bundle.min.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,6 @@ function loginFromLocalStorage() {
 | 
			
		||||
            window.accountId = data.id;
 | 
			
		||||
            window.authz = "accountId=" + data.id + "&nonce=" + data.Nonce;
 | 
			
		||||
            updateInventory();
 | 
			
		||||
            fetchSettings();
 | 
			
		||||
        },
 | 
			
		||||
        () => {
 | 
			
		||||
            logout();
 | 
			
		||||
@ -88,6 +87,8 @@ single.on("route_load", function (event) {
 | 
			
		||||
window.itemListPromise = new Promise(resolve => {
 | 
			
		||||
    const req = $.get("/custom/getItemLists");
 | 
			
		||||
    req.done(data => {
 | 
			
		||||
        window.archonCrystalUpgrades = data.archonCrystalUpgrades;
 | 
			
		||||
 | 
			
		||||
        const itemMap = {
 | 
			
		||||
            // Generics for rivens
 | 
			
		||||
            "/Lotus/Weapons/Tenno/Archwing/Primary/ArchGun": { name: "Archgun" },
 | 
			
		||||
@ -105,7 +106,14 @@ window.itemListPromise = new Promise(resolve => {
 | 
			
		||||
            "/Lotus/Upgrades/CosmeticEnhancers/Peculiars/CyoteMod": { name: "Traumatic Peculiar" }
 | 
			
		||||
        };
 | 
			
		||||
        for (const [type, items] of Object.entries(data)) {
 | 
			
		||||
            if (type != "badItems") {
 | 
			
		||||
            if (type == "archonCrystalUpgrades") {
 | 
			
		||||
                Object.entries(items).forEach(([uniqueName, name]) => {
 | 
			
		||||
                    const option = document.createElement("option");
 | 
			
		||||
                    option.setAttribute("data-key", uniqueName);
 | 
			
		||||
                    option.value = name;
 | 
			
		||||
                    document.getElementById("datalist-" + type).appendChild(option);
 | 
			
		||||
                });
 | 
			
		||||
            } else if (type != "badItems") {
 | 
			
		||||
                items.forEach(item => {
 | 
			
		||||
                    if (item.uniqueName in data.badItems) {
 | 
			
		||||
                        item.name += " (Imposter)";
 | 
			
		||||
@ -127,6 +135,9 @@ function updateInventory() {
 | 
			
		||||
    const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1");
 | 
			
		||||
    req.done(data => {
 | 
			
		||||
        window.itemListPromise.then(itemMap => {
 | 
			
		||||
            window.didInitialInventoryUpdate = true;
 | 
			
		||||
 | 
			
		||||
            // Populate inventory route
 | 
			
		||||
            document.getElementById("warframe-list").innerHTML = "";
 | 
			
		||||
            data.Suits.forEach(item => {
 | 
			
		||||
                const tr = document.createElement("tr");
 | 
			
		||||
@ -152,13 +163,21 @@ function updateInventory() {
 | 
			
		||||
                        a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M214.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 141.2V448c0 17.7 14.3 32 32 32s32-14.3 32-32V141.2L329.4 246.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160z"/></svg>`;
 | 
			
		||||
                        td.appendChild(a);
 | 
			
		||||
                    }
 | 
			
		||||
                    {
 | 
			
		||||
                        const a = document.createElement("a");
 | 
			
		||||
                        a.href = "/webui/powersuit/" + item.ItemId.$oid;
 | 
			
		||||
                        a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M278.5 215.6L23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41c11.1-7.2 5.5-23-7.8-23c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3l-32.2 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7C506.4 207.6 512 184.1 512 160c0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149C91 197 64 262.1 64 330v55.3L253.6 195.8c6.2-6.2 16.4-6.2 22.6 0c5.4 5.4 6.1 13.6 2.2 19.8z"/></svg>`;
 | 
			
		||||
                        td.appendChild(a);
 | 
			
		||||
                    }
 | 
			
		||||
                    {
 | 
			
		||||
                        const a = document.createElement("a");
 | 
			
		||||
                        a.href = "#";
 | 
			
		||||
                        a.onclick = function (event) {
 | 
			
		||||
                            event.preventDefault();
 | 
			
		||||
                            const name = prompt("Enter new custom name:");
 | 
			
		||||
                            renameGear("Suits", item.ItemId.$oid, name);
 | 
			
		||||
                            if (name !== null) {
 | 
			
		||||
                                renameGear("Suits", item.ItemId.$oid, name);
 | 
			
		||||
                            }
 | 
			
		||||
                        };
 | 
			
		||||
                        a.title = "Rename";
 | 
			
		||||
                        a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M0 80V229.5c0 17 6.7 33.3 18.7 45.3l176 176c25 25 65.5 25 90.5 0L418.7 317.3c25-25 25-65.5 0-90.5l-176-176c-12-12-28.3-18.7-45.3-18.7H48C21.5 32 0 53.5 0 80zm112 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>`;
 | 
			
		||||
@ -179,7 +198,6 @@ function updateInventory() {
 | 
			
		||||
                }
 | 
			
		||||
                document.getElementById("warframe-list").appendChild(tr);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            document.getElementById("weapon-list").innerHTML = "";
 | 
			
		||||
            ["LongGuns", "Pistols", "Melee"].forEach(category => {
 | 
			
		||||
                data[category].forEach(item => {
 | 
			
		||||
@ -212,7 +230,9 @@ function updateInventory() {
 | 
			
		||||
                            a.onclick = function (event) {
 | 
			
		||||
                                event.preventDefault();
 | 
			
		||||
                                const name = prompt("Enter new custom name:");
 | 
			
		||||
                                renameGear(category, item.ItemId.$oid, name);
 | 
			
		||||
                                if (name !== null) {
 | 
			
		||||
                                    renameGear(category, item.ItemId.$oid, name);
 | 
			
		||||
                                }
 | 
			
		||||
                            };
 | 
			
		||||
                            a.title = "Rename";
 | 
			
		||||
                            a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M0 80V229.5c0 17 6.7 33.3 18.7 45.3l176 176c25 25 65.5 25 90.5 0L418.7 317.3c25-25 25-65.5 0-90.5l-176-176c-12-12-28.3-18.7-45.3-18.7H48C21.5 32 0 53.5 0 80zm112 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>`;
 | 
			
		||||
@ -235,6 +255,7 @@ function updateInventory() {
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Populate mods route
 | 
			
		||||
            document.getElementById("riven-list").innerHTML = "";
 | 
			
		||||
            document.getElementById("mods-list").innerHTML = "";
 | 
			
		||||
            data.Upgrades.forEach(item => {
 | 
			
		||||
@ -369,6 +390,56 @@ function updateInventory() {
 | 
			
		||||
                    document.getElementById("mods-list").appendChild(tr);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Populate powersuit route
 | 
			
		||||
            if (single.getCurrentPath().substr(0, 17) == "/webui/powersuit/") {
 | 
			
		||||
                const oid = single.getCurrentPath().substr(17);
 | 
			
		||||
                const item = data.Suits.find(x => x.ItemId.$oid == oid);
 | 
			
		||||
                if (item) {
 | 
			
		||||
                    if (item.ItemName) {
 | 
			
		||||
                        $("#powersuit-route h3").text(item.ItemName);
 | 
			
		||||
                        $("#powersuit-route .text-body-secondary").text(itemMap[item.ItemType]?.name ?? item.ItemType);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        $("#powersuit-route h3").text(itemMap[item.ItemType]?.name ?? item.ItemType);
 | 
			
		||||
                        $("#powersuit-route .text-body-secondary").text("");
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    const uniqueUpgrades = {};
 | 
			
		||||
                    (item.ArchonCrystalUpgrades ?? []).forEach(upgrade => {
 | 
			
		||||
                        uniqueUpgrades[upgrade.UpgradeType] ??= 0;
 | 
			
		||||
                        uniqueUpgrades[upgrade.UpgradeType] += 1;
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    document.getElementById("crystals-list").innerHTML = "";
 | 
			
		||||
                    Object.entries(uniqueUpgrades).forEach(([upgradeType, count]) => {
 | 
			
		||||
                        const tr = document.createElement("tr");
 | 
			
		||||
                        {
 | 
			
		||||
                            const td = document.createElement("td");
 | 
			
		||||
                            td.textContent = count + "x " + (archonCrystalUpgrades[upgradeType] ?? upgradeType);
 | 
			
		||||
                            tr.appendChild(td);
 | 
			
		||||
                        }
 | 
			
		||||
                        {
 | 
			
		||||
                            const td = document.createElement("td");
 | 
			
		||||
                            td.classList = "text-end";
 | 
			
		||||
                            {
 | 
			
		||||
                                const a = document.createElement("a");
 | 
			
		||||
                                a.href = "#";
 | 
			
		||||
                                a.onclick = function (event) {
 | 
			
		||||
                                    event.preventDefault();
 | 
			
		||||
                                    doPopArchonCrystalUpgrade(upgradeType);
 | 
			
		||||
                                };
 | 
			
		||||
                                a.title = "Remove";
 | 
			
		||||
                                a.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z"/></svg>`;
 | 
			
		||||
                                td.appendChild(a);
 | 
			
		||||
                            }
 | 
			
		||||
                            tr.appendChild(td);
 | 
			
		||||
                        }
 | 
			
		||||
                        document.getElementById("crystals-list").appendChild(tr);
 | 
			
		||||
                    });
 | 
			
		||||
                } else {
 | 
			
		||||
                    single.loadRoute("/webui/inventory");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
@ -656,26 +727,6 @@ $("#mod-to-acquire").on("input", () => {
 | 
			
		||||
    $("#mod-to-acquire").removeClass("is-invalid");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function fetchSettings() {
 | 
			
		||||
    fetch("/custom/config")
 | 
			
		||||
        .then(response => response.json())
 | 
			
		||||
        .then(json =>
 | 
			
		||||
            Object.entries(json).forEach(entry => {
 | 
			
		||||
                const [key, value] = entry;
 | 
			
		||||
                var x = document.getElementById(`${key}`);
 | 
			
		||||
                if (x != null) {
 | 
			
		||||
                    if (x.type == "checkbox") {
 | 
			
		||||
                        if (value === true) {
 | 
			
		||||
                            x.setAttribute("checked", "checked");
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (x.type == "number") {
 | 
			
		||||
                        x.setAttribute("value", `${value}`);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uiConfigs = [
 | 
			
		||||
    "autoCreateAccount",
 | 
			
		||||
    "skipStoryModeChoice",
 | 
			
		||||
@ -721,27 +772,52 @@ function doChangeSettings() {
 | 
			
		||||
 | 
			
		||||
// Cheats route
 | 
			
		||||
 | 
			
		||||
fetch("http://localhost:61558/ping", { mode: "no-cors" }).then(() => {
 | 
			
		||||
    $("#client-cheats-nok").addClass("d-none");
 | 
			
		||||
    $("#client-cheats-ok").removeClass("d-none");
 | 
			
		||||
single.getRoute("/webui/cheats").on("beforeload", function () {
 | 
			
		||||
    fetch("/custom/config")
 | 
			
		||||
        .then(response => response.json())
 | 
			
		||||
        .then(json =>
 | 
			
		||||
            Object.entries(json).forEach(entry => {
 | 
			
		||||
                const [key, value] = entry;
 | 
			
		||||
                var x = document.getElementById(`${key}`);
 | 
			
		||||
                if (x != null) {
 | 
			
		||||
                    if (x.type == "checkbox") {
 | 
			
		||||
                        if (value === true) {
 | 
			
		||||
                            x.setAttribute("checked", "checked");
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (x.type == "number") {
 | 
			
		||||
                        x.setAttribute("value", `${value}`);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    fetch("http://localhost:61558/skip_mission_start_timer")
 | 
			
		||||
        .then(res => res.text())
 | 
			
		||||
        .then(res => {
 | 
			
		||||
            document.getElementById("skip_mission_start_timer").checked = res == "1";
 | 
			
		||||
        });
 | 
			
		||||
    document.getElementById("skip_mission_start_timer").onchange = function () {
 | 
			
		||||
        fetch("http://localhost:61558/skip_mission_start_timer?" + this.checked);
 | 
			
		||||
    };
 | 
			
		||||
    fetch("http://localhost:61558/ping", { mode: "no-cors" })
 | 
			
		||||
        .then(() => {
 | 
			
		||||
            $("#client-cheats-ok").removeClass("d-none");
 | 
			
		||||
            $("#client-cheats-nok").addClass("d-none");
 | 
			
		||||
 | 
			
		||||
    fetch("http://localhost:61558/fov_override")
 | 
			
		||||
        .then(res => res.text())
 | 
			
		||||
        .then(res => {
 | 
			
		||||
            document.getElementById("fov_override").value = parseFloat(res) * 10000;
 | 
			
		||||
            fetch("http://localhost:61558/skip_mission_start_timer")
 | 
			
		||||
                .then(res => res.text())
 | 
			
		||||
                .then(res => {
 | 
			
		||||
                    document.getElementById("skip_mission_start_timer").checked = res == "1";
 | 
			
		||||
                });
 | 
			
		||||
            document.getElementById("skip_mission_start_timer").onchange = function () {
 | 
			
		||||
                fetch("http://localhost:61558/skip_mission_start_timer?" + this.checked);
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            fetch("http://localhost:61558/fov_override")
 | 
			
		||||
                .then(res => res.text())
 | 
			
		||||
                .then(res => {
 | 
			
		||||
                    document.getElementById("fov_override").value = parseFloat(res) * 10000;
 | 
			
		||||
                });
 | 
			
		||||
            document.getElementById("fov_override").oninput = function () {
 | 
			
		||||
                fetch("http://localhost:61558/fov_override?" + this.value);
 | 
			
		||||
            };
 | 
			
		||||
        })
 | 
			
		||||
        .catch(function () {
 | 
			
		||||
            $("#client-cheats-nok").removeClass("d-none");
 | 
			
		||||
            $("#client-cheats-ok").addClass("d-none");
 | 
			
		||||
        });
 | 
			
		||||
    document.getElementById("fov_override").oninput = function () {
 | 
			
		||||
        fetch("http://localhost:61558/fov_override?" + this.value);
 | 
			
		||||
    };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function doUnlockAllFocusSchools() {
 | 
			
		||||
@ -798,3 +874,54 @@ function unlockFocusSchool(upgradeType) {
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Powersuit Route
 | 
			
		||||
 | 
			
		||||
single.getRoute("#powersuit-route").on("beforeload", function () {
 | 
			
		||||
    this.element.querySelector("h3").textContent = "Loading...";
 | 
			
		||||
    if (window.didInitialInventoryUpdate) {
 | 
			
		||||
        updateInventory();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function doPushArchonCrystalUpgrade() {
 | 
			
		||||
    const uniqueName = getKey(document.querySelector("[list='datalist-archonCrystalUpgrades']"));
 | 
			
		||||
    if (!uniqueName) {
 | 
			
		||||
        $("[list='datalist-archonCrystalUpgrades']").addClass("is-invalid").focus();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    revalidateAuthz(() => {
 | 
			
		||||
        $.get(
 | 
			
		||||
            "/custom/pushArchonCrystalUpgrade?" +
 | 
			
		||||
                window.authz +
 | 
			
		||||
                "&oid=" +
 | 
			
		||||
                single.getCurrentPath().substr(17) +
 | 
			
		||||
                "&type=" +
 | 
			
		||||
                uniqueName +
 | 
			
		||||
                "&count=" +
 | 
			
		||||
                $("#archon-crystal-add-count").val()
 | 
			
		||||
        ).done(function () {
 | 
			
		||||
            $("[list='datalist-archonCrystalUpgrades']").val("");
 | 
			
		||||
            updateInventory();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$("[list='datalist-archonCrystalUpgrades']").on("input", () => {
 | 
			
		||||
    $("[list='datalist-archonCrystalUpgrades']").removeClass("is-invalid");
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function doPopArchonCrystalUpgrade(type) {
 | 
			
		||||
    revalidateAuthz(() => {
 | 
			
		||||
        $.get(
 | 
			
		||||
            "/custom/popArchonCrystalUpgrade?" +
 | 
			
		||||
                window.authz +
 | 
			
		||||
                "&oid=" +
 | 
			
		||||
                single.getCurrentPath().substr(17) +
 | 
			
		||||
                "&type=" +
 | 
			
		||||
                type
 | 
			
		||||
        ).done(function () {
 | 
			
		||||
            updateInventory();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,6 @@
 | 
			
		||||
    body.logged-in #sidebar {
 | 
			
		||||
        position: sticky;
 | 
			
		||||
        top: 5rem;
 | 
			
		||||
        height: 100px;
 | 
			
		||||
        margin-right: 3rem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user