\n );\n }\n}\n","export default {\n ACTION_SKILL: 1,\n AUGMENT_CHEVRON: 2,\n AUGMENT_DIAMOND: 3,\n AUGMENT_ACTION_SKILL: 4,\n}\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"VaultHunter\":\"_2zgqJ\",\"header\":\"_1Jomm\",\"title\":\"_17kLY\",\"subtitle\":\"_3J3hw\",\"sidepanel\":\"_2UO55\",\"level\":\"xH9ts\",\"reset\":\"K9CBr\",\"trees\":\"_3ek45\",\"tier\":\"_3Ch4X\",\"treeName\":\"_1WAM2\",\"tree\":\"gRWZY\",\"skills\":\"_2Su0b\",\"green\":\"-Pl7G\",\"blue\":\"_1nm1I\",\"red\":\"_3T1pZ\",\"purple\":\"Fmsm1\"};","import { Link } from 'preact-router';\nimport Footer from '@components/Footer';\nimport style from './index.css';\n\nexport default function () {\n const pages = [\n { name: 'Zane', job: 'the Operative', path: '/operative' },\n { name: 'Amara', job: 'the Siren', path: '/siren' },\n { name: 'FL4K', job: 'the Beastmaster', path: '/beastmaster' },\n { name: 'Moze', job: 'the Gunner', path: '/gunner' },\n ];\n return (\n
\n
\n
\n
(Unofficial)
Borderlands 3 skill calculator
\n { pages.map(page => {\n return (\n \n
\n {page.name}\n
\n {page.job}\n
\n
\n \n );\n }) }\n
\n
\n \n
\n );\n}\n","import { h, render } from 'preact';\nimport App from '@components/App';\nimport './index.css';\n\nlet elem = document.querySelector('#app');\nlet root = render(, elem, elem.firstElementChild);\n\nif (process.env.NODE_ENV === 'development' && module.hot) {\n // enable preact devtools\n require('preact/debug');\n // respond to HMR updates\n module.hot.accept('@components/App', New => {\n New = require('@components/App').default;\n root = render(, elem, root);\n });\n} else if (process.env.NODE_ENV === 'production') {\n // Service Worker registration\n require('offline-plugin/runtime').install();\n}\n","import { Component, cloneElement, h } from 'preact';\n\nvar EMPTY$1 = {};\n\nfunction assign(obj, props) {\n\t// eslint-disable-next-line guard-for-in\n\tfor (var i in props) {\n\t\tobj[i] = props[i];\n\t}\n\treturn obj;\n}\n\nfunction exec(url, route, opts) {\n\tvar reg = /(?:\\?([^#]*))?(#.*)?$/,\n\t\tc = url.match(reg),\n\t\tmatches = {},\n\t\tret;\n\tif (c && c[1]) {\n\t\tvar p = c[1].split('&');\n\t\tfor (var i=0; i b.rank) ? -1 :\n\t\t(a.index - b.index)\n\t);\n}\n\n// filter out VNodes without attributes (which are unrankeable), and add `index`/`rank` properties to be used in sorting.\nfunction prepareVNodeForRanking(vnode, index) {\n\tvnode.index = index;\n\tvnode.rank = rankChild(vnode);\n\treturn vnode.attributes;\n}\n\nfunction segmentize(url) {\n\treturn url.replace(/(^\\/+|\\/+$)/g, '').split('/');\n}\n\nfunction rankSegment(segment) {\n\treturn segment.charAt(0)==':' ? (1 + '*+?'.indexOf(segment.charAt(segment.length-1))) || 4 : 5;\n}\n\nfunction rank(path) {\n\treturn segmentize(path).map(rankSegment).join('');\n}\n\nfunction rankChild(vnode) {\n\treturn vnode.attributes.default ? 0 : rank(vnode.attributes.path);\n}\n\nvar customHistory = null;\n\nvar ROUTERS = [];\n\nvar subscribers = [];\n\nvar EMPTY = {};\n\nfunction isPreactElement(node) {\n\treturn node.__preactattr_!=null || typeof Symbol!=='undefined' && node[Symbol.for('preactattr')]!=null;\n}\n\nfunction setUrl(url, type) {\n\tif ( type === void 0 ) type='push';\n\n\tif (customHistory && customHistory[type]) {\n\t\tcustomHistory[type](url);\n\t}\n\telse if (typeof history!=='undefined' && history[type+'State']) {\n\t\thistory[type+'State'](null, null, url);\n\t}\n}\n\n\nfunction getCurrentUrl() {\n\tvar url;\n\tif (customHistory && customHistory.location) {\n\t\turl = customHistory.location;\n\t}\n\telse if (customHistory && customHistory.getCurrentLocation) {\n\t\turl = customHistory.getCurrentLocation();\n\t}\n\telse {\n\t\turl = typeof location!=='undefined' ? location : EMPTY;\n\t}\n\treturn (\"\" + (url.pathname || '') + (url.search || ''));\n}\n\n\n\nfunction route(url, replace) {\n\tif ( replace === void 0 ) replace=false;\n\n\tif (typeof url!=='string' && url.url) {\n\t\treplace = url.replace;\n\t\turl = url.url;\n\t}\n\n\t// only push URL into history if we can handle it\n\tif (canRoute(url)) {\n\t\tsetUrl(url, replace ? 'replace' : 'push');\n\t}\n\n\treturn routeTo(url);\n}\n\n\n/** Check if the given URL can be handled by any router instances. */\nfunction canRoute(url) {\n\tfor (var i=ROUTERS.length; i--; ) {\n\t\tif (ROUTERS[i].canRoute(url)) { return true; }\n\t}\n\treturn false;\n}\n\n\n/** Tell all router instances to handle the given URL. */\nfunction routeTo(url) {\n\tvar didRoute = false;\n\tfor (var i=0; i 0;\n\t};\n\n\t/** Re-render children with a new URL to match against. */\n\tRouter.prototype.routeTo = function routeTo (url) {\n\t\tthis._didRoute = false;\n\t\tthis.setState({ url: url });\n\n\t\t// if we're in the middle of an update, don't synchronously re-route.\n\t\tif (this.updating) { return this.canRoute(url); }\n\n\t\tthis.forceUpdate();\n\t\treturn this._didRoute;\n\t};\n\n\tRouter.prototype.componentWillMount = function componentWillMount () {\n\t\tROUTERS.push(this);\n\t\tthis.updating = true;\n\t};\n\n\tRouter.prototype.componentDidMount = function componentDidMount () {\n\t\tvar this$1 = this;\n\n\t\tif (customHistory) {\n\t\t\tthis.unlisten = customHistory.listen(function (location) {\n\t\t\t\tthis$1.routeTo((\"\" + (location.pathname || '') + (location.search || '')));\n\t\t\t});\n\t\t}\n\t\tthis.updating = false;\n\t};\n\n\tRouter.prototype.componentWillUnmount = function componentWillUnmount () {\n\t\tif (typeof this.unlisten==='function') { this.unlisten(); }\n\t\tROUTERS.splice(ROUTERS.indexOf(this), 1);\n\t};\n\n\tRouter.prototype.componentWillUpdate = function componentWillUpdate () {\n\t\tthis.updating = true;\n\t};\n\n\tRouter.prototype.componentDidUpdate = function componentDidUpdate () {\n\t\tthis.updating = false;\n\t};\n\n\tRouter.prototype.getMatchingChildren = function getMatchingChildren (children, url, invoke) {\n\t\treturn children\n\t\t\t.filter(prepareVNodeForRanking)\n\t\t\t.sort(pathRankSort)\n\t\t\t.map( function (vnode) {\n\t\t\t\tvar matches = exec(url, vnode.attributes.path, vnode.attributes);\n\t\t\t\tif (matches) {\n\t\t\t\t\tif (invoke !== false) {\n\t\t\t\t\t\tvar newProps = { url: url, matches: matches };\n\t\t\t\t\t\tassign(newProps, matches);\n\t\t\t\t\t\tdelete newProps.ref;\n\t\t\t\t\t\tdelete newProps.key;\n\t\t\t\t\t\treturn cloneElement(vnode, newProps);\n\t\t\t\t\t}\n\t\t\t\t\treturn vnode;\n\t\t\t\t}\n\t\t\t}).filter(Boolean);\n\t};\n\n\tRouter.prototype.render = function render (ref, ref$1) {\n\t\tvar children = ref.children;\n\t\tvar onChange = ref.onChange;\n\t\tvar url = ref$1.url;\n\n\t\tvar active = this.getMatchingChildren(children, url, true);\n\n\t\tvar current = active[0] || null;\n\t\tthis._didRoute = !!current;\n\n\t\tvar previous = this.previousUrl;\n\t\tif (url!==previous) {\n\t\t\tthis.previousUrl = url;\n\t\t\tif (typeof onChange==='function') {\n\t\t\t\tonChange({\n\t\t\t\t\trouter: this,\n\t\t\t\t\turl: url,\n\t\t\t\t\tprevious: previous,\n\t\t\t\t\tactive: active,\n\t\t\t\t\tcurrent: current\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn current;\n\t};\n\n\treturn Router;\n}(Component));\n\nvar Link = function (props) { return (\n\th('a', assign({ onClick: handleLinkClick }, props))\n); };\n\nvar Route = function (props) { return h(props.component, props); };\n\nRouter.subscribers = subscribers;\nRouter.getCurrentUrl = getCurrentUrl;\nRouter.route = route;\nRouter.Router = Router;\nRouter.Route = Route;\nRouter.Link = Link;\n\nexport { subscribers, getCurrentUrl, route, Router, Route, Link };export default Router;\n//# sourceMappingURL=preact-router.es.js.map\n","/* eslint-disable space-before-function-paren */\nimport SKILLS from '@constants/skills';\n\nfunction percent (rank, unit) {\n return Math.round(rank * unit * 10) / 10;\n}\n\n/* These three skills dont follow a linear patch for some increases. Data came from official builder.\nhttps://borderlands.com/en-US/characters/fl4k/#-\nMight be different in game but I haven't played FL4K yet!\nThere are probably diminishing return algorithms for these but this was quicker than figuring that out. */\n\n// Hunter's Eye Damage Resistance\nfunction getHuntersEyeDamageResistance(rank) {\n switch (rank) {\n case 1:\n return 5.3;\n case 2:\n return 10.1;\n case 3:\n return 14.4;\n case 4:\n return 18.3;\n case 5:\n return 21.9;\n default:\n return 0;\n }\n}\n\n// Ambush Predator Handling\nfunction getAmbushPredatorHandling(rank) {\n switch (rank) {\n case 1:\n return 17;\n case 2:\n return 29;\n case 3:\n return 38;\n case 4:\n return 44;\n case 5:\n return 50;\n default:\n return 0;\n }\n}\n\n// The Most Dangerous Game Handling\nfunction getMostDangerousGameHandling(rank) {\n switch (rank) {\n case 1:\n return 14.3;\n case 2:\n return 25.0;\n case 3:\n return 33.3;\n default:\n return 0;\n }\n}\n\n// Furious Attack Handling\nfunction getFuriousAttackHandling(rank) {\n switch (rank) {\n case 1:\n return 1;\n case 2:\n return 2;\n case 3:\n return 2.9;\n case 4:\n return 3.8;\n case 5:\n return 4.8;\n default:\n return 0;\n }\n}\n\n// Turn Tail And Run Damage Resistance\nfunction getTurnTailAndRunDamageResistance(rank) {\n switch (rank) {\n case 1:\n return 6.5;\n case 2:\n return 12.3;\n case 3:\n return 17.4;\n default:\n return 0;\n }\n}\n\n// Interplanetary Stalker Beast Movement Speed\nfunction getInterplanetaryStalkerBeastMovementSpeed(rank) {\n switch (rank) {\n case 1:\n return 2;\n case 2:\n return 3;\n case 3:\n return 5;\n case 4:\n return 6;\n case 5:\n return 7;\n default:\n return 0;\n }\n}\n\n// Second Intention Critical Kill Reload Speed\nfunction getSecondIntentionCriticalKillReloadSpeed(rank) {\n switch (rank) {\n case 1:\n return 6;\n case 2:\n return 11;\n case 3:\n return 15;\n case 4:\n return 19;\n case 5:\n return 23;\n default:\n return 0;\n }\n}\n\n// Success Imminent Damage\nfunction getSuccessImminetDamage(rank) {\n switch (rank) {\n case 1:\n return 6;\n case 2:\n return 11;\n case 3:\n return 17;\n case 4:\n return 22;\n case 5:\n return 28;\n default:\n return 0;\n }\n}\n\n/* eslint-disable quotes */\nconst skills = {\n \"Stalker\": {\n \"0\": {\n \"Jabber Sidekick\": {\n text: \"FL4K is joined by a loyal Jabber companion, armed with a Pistol. While accompanied by the Jabber, FL4K's Movement Speed is increased.\\n\\nHold [Pet Skill key] to issue an Attack Command, which will cause the Jabber to throw a Radiation Barrel at enemies.\",\n type: SKILLS.AUGMENT_DIAMOND,\n ranks: 0,\n effect: (rank, level) => `Movement Speed: +5.0%`,\n },\n \"Fade Away\": {\n text: \"FL4K cloaks, turning invisible. FL4K can fire 3 shots while cloaked, and each shot is automatically a Critical Hit. While cloaked, FL4K has increased Movement Speed and Health Regeneration.\",\n type: SKILLS.ACTION_SKILL,\n ranks: 0,\n effect: (rank, level) => `Fade Away Bonus Damage: 200% of damage dealt\\nCloaked Movement Speed: +25%\\nHealth Regeneration: +3% of Max Health per second\\nCooldown: 45 seconds\\nDuration: 15 seconds`,\n },\n },\n \"1\": {\n \"Self-Repairing System\": {\n text: \"FL4K's Maximum Health is increased, and they constantly regenerate health.\",\n ranks: 5,\n effect: (rank, level) => `Health Regeneration: ${percent(rank, 0.3)}% of Max Health/sec\\nMaximum Health: +${percent(rank, 6)}%`,\n },\n \"Sic'Em\": {\n text: \"Attack Command has lowered Cooldown and increased Damage.\",\n ranks: 3,\n effect: (rank, level) => `Attack Command Damage: +${percent(rank, 10)}%\\nAttack Command Cooldown: -${percent(rank, 10)}%`,\n },\n \"Furious Attack\": {\n text: \"Hunter Skill. After shooting an enemy, FL4K gains a stack of Furious Attack.\\n\\nFor each stack of Furious Attack, FL4K's Handling and Gun Damage are increased, and their pet gains increased Damage per stack. Stacks decay after a few seconds.\",\n ranks: 5,\n effect: (rank, level) => `Gun Damage: +${percent(rank, 0.4)}% per stack\\nHandling: +${getFuriousAttackHandling(rank)}% per stack\\nPet Damage: +${percent(rank, 0.6)}% per stack\\nMaximum Stacks: 10\\nDuration: 4 seconds`,\n },\n },\n \"2\": {\n \"Guerrillas In The Mist\": {\n text: \"Fade Away no longer ends after FL4K attacks, at the cost of Critical Hit Damage and Fade Away duration being reduced.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Critical Hit Damage: 25% of damage dealt\\nFade Away Duration: 5 seconds`,\n },\n \"Eager To Impress\": {\n text: \"Kill Skill. Whenever FL4K kills an enemy, Action Skill Cooldown Time is reduced.\\n\\nWhenever FL4K's pet kills an enemy, Action Skill Cooldown Time is reduced even more and Attack Command's duration is refreshed.\",\n ranks: 5,\n effect: (rank, level) => `FL4K Kill Action Skill Cooldown: -${percent(rank, 0.25)} seconds\\nPet Kill Action Skill Cooldown: -${percent(rank, 0.5)} seconds`,\n },\n \"All My BFF's\": {\n text: \"Allies share a portion of FL4K's total Health Regeneration. FL4K's pet shares twice the amount of Health Regeneration.\",\n ranks: 3,\n effect: (rank, level) => `Allies' Health Regen: +${Math.round(percent(rank, 16.666))}% of FL4K's Health Regen\\nPet Health Regen: +${Math.round(percent(rank, 33.333))}% of FL4K's Health Regen`,\n },\n \"Overclocked\": {\n text: \"FL4K gains increased Fire Rate. FL4K gains even more Fire Rate after reloading.\",\n ranks: 5,\n effect: (rank, level) => `Fire Rate after Reloading: +${percent(rank, 2)}%\\nFire Rate : +${percent(rank, 2)}%\\nDuration: 4 seconds`,\n },\n },\n \"3\": {\n \"Not My Circus\": {\n text: \"After Fade Away ends, FL4K's pet will Taunt, drawing the attention of all enemies in a huge radius.\\nFor a few seconds after Taunting, the pet gains powerful Damage Resistance.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Pet Damage Resistance: +80%\\nPet Taunt Duration: 6 seconds`,\n },\n \"Lick The Wounds\": {\n text: \"When FL4K is in Fight For Your Life, their pet will attempt to revive them. If it does, it gains increased Damage for a short time.\",\n ranks: 1,\n effect: (rank, level) => `Pet Damage: +30%\\nDuration: 60 seconds`,\n },\n \"Turn Tail And Run\": {\n text: \"While moving, FL4K constantly regenerates health and gains Damage Resistance.\\n\\nWhile still, FL4K gains Gun Damage and Fire Rate.\",\n ranks: 3,\n effect: (rank, level) => `Health Regen While Moving: +${percent(rank, 0.3)}% Max Health/sec\\nDamage Resistance: +${getTurnTailAndRunDamageResistance(rank)}% while moving\\nGun Damage While Still: +${percent(rank, 8.333)}%\\nFire Rate While Still: +${percent(rank, 4)}%`,\n },\n \"Beefcake Jabber\": {\n text: \"FL4K's Jabber evolves into a Beefcake, discarding its pistol and equipping a Shotgun. While accompanied by the Beefcake, FL4K gains increased Movement Speed and Maximum Health. When FL4K issues an Attack Command, the Beefcake will summon a melee weapon to deliver a powerful attack that knocks enemies back.\",\n type: SKILLS.AUGMENT_DIAMOND,\n ranks: 0,\n effect: (rank, level) => `Movement Speed: +5%\\nMaximum Health: +10%`,\n },\n },\n \"4\": {\n \"Until You Are Dead\": {\n text: \"The Health Regeneration and Movement Speed of Fade Away persists for a short time after the skill has ended.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Post Cloak Duration: 10 seconds`,\n },\n \"The Fast And The Furryous\": {\n text: \"While above half health, FL4K's Gun Damage and Movement Speed are increased, and their pet gains increased Damage.\",\n ranks: 3,\n effect: (rank, level) => `Gun Damage: +${Math.round(percent(rank, 8.333))}%\\nPet Damage: +${percent(rank, 10)}%\\nMovement Speed: +${percent(rank, 3.333)}%e`,\n },\n \"Hidden Machine\": {\n text: \"When an enemy has no target or is attacking a different target, FL4K deals increased damage against them.\",\n ranks: 5,\n effect: (rank, level) => `Damage: +${percent(rank, 6)}%`,\n },\n \"Gunslinger Jabber\": {\n text: \"FL4K's Jabber upgrades his gear and equips an SMG. While accompanied by the Gunslinger, FL4K gains increased Movement Speed and Critical Hit Damage. When FL4K issues an Attack Command, the Gunslinger equips a Rocket Launcher to attack the target.\",\n type: SKILLS.AUGMENT_DIAMOND,\n ranks: 0,\n effect: (rank, level) => `Movement Speed: +5%\\nCritical Hit Damage: +5%`,\n },\n },\n \"5\": {\n \"Unblinking Eye\": {\n text: \"During Fade Away, successive hits on the same target increase FL4K's Critical Damage per hit. Unblinking Eye resets every 3 hits.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Additional Fade Away Bonus Damage: +75% of damage dealt per hit`,\n },\n \"Rage And Recover\": {\n text: \"Kill Skill. After killing an enemy, FL4K and FL4K's pet regenerate health for a few seconds.\",\n ranks: 5,\n effect: (rank, level) => `Health Regeneration: +${percent(rank, 1.6)}% of Missing Health/sec\\nDuration: 3 seconds`,\n },\n },\n \"6\": {\n \"The Power Inside\": {\n text: \"FL4K and FL4K's pet gain increased Damage when FL4K activates an Action Skill. If FL4K is at full health, the increased Damage is doubled.\",\n ranks: 1,\n effect: (rank, level) => `Damage: +25%\\nDuration: 15 seconds`,\n },\n },\n },\n \"Master\": {\n \"0\": {\n \"Guard Skag\": {\n text: \"FL4K is joined by a loyal Skag companion, which will increase FL4K's Damage. Hold [Pet Skill key] to issue an Attack Command, which will cause the Skag to vomit acid onto enemies.\",\n type: SKILLS.AUGMENT_DIAMOND,\n ranks: 0,\n effect: (rank, level) => `Damage: +5%`,\n },\n \"Gamma Burst\": {\n text: \"FL4K creates a Rift at a target location, teleporting their pet through the Rift and dealing Radiation Damage to nearby enemies. Additionally, FL4K's pet becomes irradiated, growing in size and dealing bonus Radiation Damage when it attacks. Using Gamma Burst while FL4K's pet is downed or dead will revive the pet at the targeted location with 30% of its health, but will double Action Skill Cooldown Time.\",\n type: SKILLS.ACTION_SKILL,\n ranks: 0,\n effect: (rank, level) => `Damage 56: (increases with character level)\\nDuration: 20 seconds\\nCooldown: 30 seconds`,\n },\n },\n \"1\": {\n \"Ferocity\": {\n text: \"FL4K's Pet deals increased damage.\",\n ranks: 5,\n effect: (rank, level) => `Pet Damage: +${percent(rank, 10)}%`,\n },\n \"Persistence Hunter\": {\n text: \"Increases FL4K's Gun Damage and Action Skill Duration.\",\n ranks: 3,\n effect: (rank, level) => `Gun Damage: +${percent(rank, 4)}%\\nAction Skill Duration: +${percent(rank, 15)}%`,\n },\n \"Go For The Eyes!\": {\n text: \"When FL4K's pet attacks an enemy, the first melee attack is an automatic Critical Hit that deals increased damage.\",\n ranks: 5,\n effect: (rank, level) => `Pet Critical Hit Damage: ${percent(rank, 15)}%`,\n },\n },\n \"2\": {\n \"Atomic Aroma\": {\n text: \"While Gamma Burst is active, FL4K's pet is surrounded by a Radiation Aura, constantly damaging all nearby enemies.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Radiation Damage: 4 per second (increases with character level)`,\n },\n \"Who Rescued Who?\": {\n text: \"Whenever FL4K's Pet deals damage, FL4K regenerates health for a few seconds. Whenever FL4K deals damage to an enemy, their Pet's health is restored for a portion of the damage dealt.\",\n ranks: 5,\n effect: (rank, level) => `Health Regeneration: +${percent(rank, 0.4)}% of Max Health/sec\\nPet Health Restored: +${percent(rank, 1)}% of damage dealt`,\n },\n \"He Bites!\": {\n text: \"When FL4K's pet takes damage, the pet returns some of that damage to the attacker.\",\n ranks: 3,\n effect: (rank, level) => `Damage Returned: ${percent(rank, 5)}% of damage received`,\n },\n \"Frenzy\": {\n text: \"Hunter Skill. When FL4K's pet deals damage, FL4K and their pet gain a stack of Frenzy. Each stack of Frenzy increases Damage. The stacks decay after a few seconds.\",\n ranks: 5,\n effect: (rank, level) => `Damage: +${percent(rank, 0.8)}% per stack\\nMaximum Stacks: 10`,\n },\n },\n \"3\": {\n \"Empathic Rage\": {\n text: \"For the duration of Gamma Burst, Damage dealt by FL4K is increased.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Damage: +20%`,\n },\n \"Psycho Head On A Stick\": {\n text: \"Hunter Kill Skill. Whenever FL4K kills an enemy, their pet gains increased Movement Speed and Damage for a few seconds.\",\n ranks: 1,\n effect: (rank, level) => `Pet Damage: +20%\\nPet Movement Speed: +12%\\nDuration: 8 seconds`,\n },\n \"Hive Mind\": {\n text: \"When FL4K takes damage, a portion of all damage they take is inflicted on their pet instead and their pet deals Bonus Damage for a short time.\",\n ranks: 3,\n effect: (rank, level) => `Damage Shared: ${percent(rank, 5)}%\\nPet Bonus Damage: +${percent(rank, 7.5)}%`,\n },\n \"Great Horned Skag\": {\n text: \"FL4K's Skag evolves into a larger Great Horned Skag, which will increase FL4K's Damage and Gun Damage.\\n\\nWhen FL4K issues an Attack Command, the Great Horned Skag will charge at enemies and knock them into the air.\",\n type: SKILLS.AUGMENT_DIAMOND,\n ranks: 0,\n effect: (rank, level) => `Damage: +5%\\nGun Damage: +10%`,\n },\n },\n \"4\": {\n \"Endurance\": {\n text: \"When FL4K or FL4K's pet kills an enemy while Gamma Burst is active, the duration of Gamma Burst is extended and pet damage is increased. These effects can stack up to 5 times.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Gamma Burst Duration: +3 seconds per kill\\nPet Damage: +10% per kill`,\n },\n \"Barbaric Yawp\": {\n text: \"Increases the power of Pet Bonuses granted to FL4K.\",\n ranks: 5,\n effect: (rank, level) => `Pet Bonuses: +${percent(rank, 40)}%`,\n },\n \"Mutated Defenses\": {\n text: \"When FL4K's pet is at low health, it gains Damage Reduction and regenerates health. This skill has a long cooldown.\",\n ranks: 1,\n effect: (rank, level) => `Health Regeneration: +40% of Max Health Pet Health over 6 seconds\\nPet Damage Resistance: +30% for 6s\\nCooldown: 15 seconds`,\n },\n \"Eridian Skag\": {\n text: \"FL4K's Skag evolves into an Eridian Skag, which will increase FL4K's Damage and Fire Rate.\\n\\nWhen FL4K issues an Attack Command, their Eridian Skag pulls nearby enemies in by generating a Singularity.\",\n type: SKILLS.AUGMENT_DIAMOND,\n ranks: 0,\n effect: (rank, level) => `Damage: +5%\\nFire Rate: +5%`,\n },\n },\n \"5\": {\n \"Burst Aid\": {\n text: \"After using Gamma Burst, the Rift remains for the duration of the skill. While standing near the Rift, FL4K and their allies rapidly Regenerate Health.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Health Regeneration: +20% of Max Health/sec`,\n },\n \"Pack Tactics\": {\n text: \"All damage dealt by FL4K and their pet is increased.\\n\\nAdditionally, the Maximum Health of both FL4K and their pet is increased.\",\n ranks: 3,\n effect: (rank, level) => `Pet and FL4K Damage: +${percent(rank, 7)}%\\nPet and FL4K Maximum Health: +${percent(rank, 5)}%`,\n },\n \"Shared Spirit\": {\n text: \"While FL4K is at low health, a portion of all damage they take is converted into healing for their pet instead.\",\n ranks: 1,\n effect: (rank, level) => `Damage Converted: 50%`,\n },\n },\n \"6\": {\n \"Dominance\": {\n text: \"Whenever FL4K attacks an enemy with a melee attack or scores a Critical Hit with a weapon while aiming down sights they establish Dominance over that enemy turning it into an ally for a short time. if the enemy is a Beast, the duration is doubled.\\n\\nWhile under the effect of Dominance, other enemies are more likely to attack it and it constantly loses health until it dies or the effect ends. Once Dominance ends, a Radiation Nova is created centered around that enemy. Only one enemy can be under the effect of Dominance at a time and an enemy may only be affected once.\",\n ranks: 1,\n effect: (rank, level) => `Duration: 12 seconds\\nTarget Loses 2% of Maximum Health per second\\nNova Damage: 12 (scales with level)`,\n },\n },\n },\n \"Hunter\": {\n \"0\": {\n \"Spiderant Centurion\": {\n text: \"FL4K is joined by a loyal Spiderant companion, which will cause FL4K to constant regenerate health.\\n\\nHold [Pet Skill key] to issue an Attack Command, which will cause the Spiderant to charge into enemies.\",\n type: SKILLS.AUGMENT_DIAMOND,\n ranks: 0,\n effect: (rank, level) => `Health Regeneration: 1% of Max Health per second`,\n },\n \"Rakk Attack!\": {\n text: \"FL4K sends forward 2 Rakk to dive-bomb enemies. This skill has multiple charges. Element: Incendiary.\",\n type: SKILLS.ACTION_SKILL,\n ranks: 0,\n effect: (rank, level) => `Damage: 35 (increases with character level)\\nCooldown: 18 seconds\\nSkill Charges: 2\\nDeals Incendiary Elemental Damage`,\n },\n },\n \"1\": {\n \"Interplanetary Stalker\": {\n text: \"Hunter Kill Skill. Whenever FL4K kills an enemy, they gain a stack of Interplanetary Stalker. For each stack of Interplanetary Stalker, they and their pet gain a bonus to all damage dealt\\n\\nAdditionally, they gain a unique stacking bonus depending on the type of enemy killed. Each unique bonus can stack up to 3 times. Each stack decays after a short time.\",\n ranks: 5,\n effect: (rank, level) => `Damage: +${percent(rank, 2)}% per stack\\nPet Damage: +${percent(rank, 1)}% per stack\\nRobot Bonus: +${percent(rank, 1.5)}% Corrosive Damage per stack\\nHuman Bonus: +${percent(rank, 3)}% Action Skill Damage per stack\\nBeast Bonus: +${getInterplanetaryStalkerBeastMovementSpeed(rank)}% Movement Speed per stack\\nMaximum Stacks: 3`,\n },\n \"Leave No Trace\": {\n text: \"When FL4K scores a Critical Hit, there is a chance for 1 ammo to be added to their magazine.\",\n ranks: 3,\n effect: (rank, level) => `Ammo Chance: +${percent(rank, 12)}%\\nCooldown: 0.3 seconds`,\n },\n \"Second Intention\": {\n text: \"Hunter Kill Skill. Whenever FL4K kills an enemy, they gain increased Reload Speed. This bonus is increased if FL4K scores a Critical Kill.\",\n ranks: 5,\n effect: (rank, level) => `Reload Speed: +${Math.ceil(percent(rank, 2.6))}%\\nCritical Kill Reload Speed: +${getSecondIntentionCriticalKillReloadSpeed(rank)}%\\nDuration: 5 seconds`,\n },\n },\n \"2\": {\n \"Rakk Open A Cold One\": {\n text: \"Converts FL4K's Rakk to Cryo Damage.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Rakk Attack! Element: Cryo`,\n },\n \"Hunter's Eye\": {\n text: \"FL4K gains bonuses when fighting different types of enemies.\",\n ranks: 5,\n effect: (rank, level) => `Human Bonus: +${percent(rank, 2.48)}% Critical Hit Damage\\nRobot Bonus: +${percent(rank, 6)}% Armor Damage\\nBeast Bonus: +${getHuntersEyeDamageResistance(rank)}% Damage Resistance`,\n },\n \"Head Count\": {\n text: \"Whenever FL4K scores a Critical Hit, there is a chance their Action Skill Cooldown is reduced.\",\n ranks: 3,\n effect: (rank, level) => `Cooldown Reduction Chance: +${percent(rank, 10)}%\\nAction Skill Cooldown: -2 seconds`,\n },\n \"Ambush Predator\": {\n text: \"While there are no enemies nearby, FL4K's Weapon Handling and Critical Hit Damage are increased.\",\n ranks: 5,\n effect: (rank, level) => `Handling: +${getAmbushPredatorHandling(rank)}%\\nCritical Hit Damage: +${percent(rank, 4)}%`,\n },\n },\n \"3\": {\n \"Falconer's Feast\": {\n text: \"When FL4K's Rakk damage an enemy, a portion of FL4K's health is restored.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Health Restored: 7% of Maximum Health`,\n },\n \"Two F4ng\": {\n text: \"FL4K has a chance to fire an extra projectile per shot.\",\n ranks: 5,\n effect: (rank, level) => `Extra Projectile Chance: +${percent(rank, 5)}%`,\n },\n \"Spiderant Scorcher\": {\n text: \"FL4K's Spiderant evolves into a Scorcher, occasionally dealing Incendiary Damage to all enemies nearby. While accompanied by the Scorcher, FL4K constantly regenerates health and deals increased Elemental Damage.\\n\\nWhen FL4K issues an Attack Command, the Scorcher will charge enemies.\",\n type: SKILLS.AUGMENT_DIAMOND,\n ranks: 0,\n effect: (rank, level) => `Health Regeneration: +1% of Max Health per second\\nElemental Damage: +10%`,\n },\n },\n \"4\": {\n \"Flock'N'Load\": {\n text: \"FL4K sends forward additional Rakk.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Additional Rakk: +2`,\n },\n \"Big Game\": {\n text: \"FL4K's Hunter Skills become much more effective and have a longer duration.\",\n ranks: 3,\n effect: (rank, level) => `Hunter Skill Duration: +${Math.round(percent(rank, 33.333))}%\\nHunter Skill Effects: +${percent(rank, 10)}%`,\n },\n \"The Most Dangerous Game\": {\n text: \"Hunter Kill Skill. Whenever FL4K kills a Badass or stronger enemy, they gain increased Critical Hit Damage, Gun Damage, and Handling for a long time and their pet receives increased Damage for a long time.\\n\\nAdditionally, they receive a cash reward from the Intergalactic Bureau of Bounty Hunting.\",\n ranks: 3,\n effect: (rank, level) => `Gun Damage: +${percent(rank, 8.33)}%\\nCritical Hit Damage: +${Math.round(percent(rank, 3.333))}%\\nHandling: +${getMostDangerousGameHandling(rank)}%\\nPet Damage: +${percent(rank, 9)}%\\nDuration: 120 seconds`,\n },\n \"Spiderant Countess\": {\n text: \"FL4K's Spiderant evolves into a Countess, which will cause FL4K to constantly regenerate health and gain Damage Resistance.\\n\\nWhen FL4K issues an Attack Command, the Countess will burrow underground and then emerge dealing Corrosive Damage in an area.\",\n type: SKILLS.AUGMENT_DIAMOND,\n ranks: 0,\n effect: (rank, level) => `Health Regeneration: +1% of Max Health per second\\nDamage Resistance: +5%`,\n },\n },\n \"5\": {\n \"Rakkcelerate\": {\n text: \"FL4K's Rakk have increased Cooldown Rate and gain an Additional Charge.\",\n type: SKILLS.AUGMENT_CHEVRON,\n ranks: 0,\n effect: (rank, level) => `Skill Charges: +1\\nCooldown Rate: +20%`,\n },\n \"Galactic Shadow\": {\n text: \"FL4K deals increased Critical Hit Damage, and enemies are less likely to attack them.\",\n ranks: 1,\n effect: (rank, level) => `Critical Hit Damage: +15%`,\n },\n \"Grim Harvest\": {\n text: \"FL4K gains increased Gun Damage and Action Skill Damage. FL4K's pet gains increased Damage.\",\n ranks: 5,\n effect: (rank, level) => `Gun Damage: +${percent(rank, 3)}%\\nAction Skill Damage: +${percent(rank, 10)}%\\nPet Damage: +${percent(rank, 7)}%`,\n },\n },\n \"6\": {\n \"Megavore\": {\n text: \"FL4K gains a chance to score a Critical Hit with weapons against any part of enemies.\",\n ranks: 1,\n effect: (rank, level) => `Critical Hit Chance: +20%`,\n },\n },\n },\n \"Trapper\": {\n \"0\": {\n \"Pet Ion Loader\": {\n ranks: 0,\n text: \"FL4K is joined by a loyal Mini ION Loader Bot companion, armed with a Shock Sniper Rifle and Homing Shock Orbs that can be shot to trigger a Shock Nova. While accompanied by the ION Loader, FL4K gains increased Elemental Damage Resistance.\\nHold [Pet Skill key] to issue an Attack Command, which causes the ION Loader to fire a powerful Eye Laser at the enemy.\",\n effect: (rank, level) => `Elemental Resistance: +30%`,\n type: SKILLS.AUGMENT_DIAMOND,\n },\n \"Gravity Snare\": {\n ranks: 0,\n text: \"FL4K tosses out a Trap that Knocks Up and temporarily Stuns nearby enemies. After being deployed, the Trap periodically continues to Knock Up and Stun enemies for the duration. While standing near the Trap, pressing [Action Skill key] will pick up the Trap, ending the action skill early and refunding a portion of the remaining duration.\",\n effect: (rank, level) => `Duration: 16 seconds\\nCooldown: 36 seconds`,\n type: SKILLS.ACTION_SKILL,\n }\n },\n \"1\": {\n \"Gotta Go Fast\": {\n ranks: 5,\n text: \"FL4K's pet gains increased Movement Speed and Damage.\",\n effect: (rank, level) => `Pet Damage: +${percent(rank, 7)}%\\nPet Movement Speed: +${percent(rank, 8)}%`\n },\n \"Success Imminent\": {\n ranks: 5,\n text: \"Whenever FL4K's or their pet's shield breaks or is filled, they and their pet create a Radation Nova. This skill has a short cooldown.\",\n effect: (rank, level) => `Nova Damage: ${percent(rank, 6)} (scales with level)\\nCooldown: 3 seconds`\n },\n \"Agility Training\": {\n ranks: 5,\n text: \"FL4K and their pet gain increased Reload Speed.\",\n effect: (rank, level) => `Reload Speed: +${percent(rank, 8)}%`\n },\n },\n \"2\": {\n \"Forage\": {\n ranks: 0,\n text: \"Whenever an enemy trapped by FL4K is knocked into the air, they drop ammo, health boosters, and shield boosters.\",\n effect: (rank, level) => ``,\n type: SKILLS.AUGMENT_CHEVRON,\n },\n \"Better Toys\": {\n ranks: 3,\n text: \"FL4K and their pet gain increased Shield Recharge Rate and improved Shield Recharge Delay.\",\n effect: (rank, level) => `Shield Recharge Rate: +${percent(rank, 6)}%\\nShield Recharge Delay: -${percent(rank, 8)}%`\n },\n \"Combat Veterinarian\": {\n ranks: 1,\n text: \"Whenever FL4K shoots the same enemy their pet is attacking, FL4K's Pet gains a portion of the damage dealt back as health.\",\n effect: (rank, level) => `Life Steal: 30% of damage dealt`\n },\n \"Throatripper\": {\n ranks: 3,\n text: \"Hunter Skill. FL4K's pet's acttacks have a chance to score a Critical Hit, dealing increased damage.\",\n effect: (rank, level) => `Critical Chance: +${percent(rank, 5)}%`\n },\n },\n \"3\": {\n \"Wide Net\": {\n ranks: 0,\n text: \"FL4K's Trap gains increased Duration and increased Radius.\",\n effect: (rank, level) => `Trap Duration: +25%\\nTrap Radius: +100%`,\n type: SKILLS.AUGMENT_CHEVRON,\n },\n \"Lethal Force Authorized\": {\n ranks: 1,\n text: \"Whenever Fl4K's Loader Bot pet would go into Fight For Your Life, it turns into an EXP Loader instead and seeks out a nearby enemy before self-destructing, dealing damage to all nearby enemies.\\nFL4K's pet's respawn time is reduced.\",\n effect: (rank, level) => `Pet Respawn Time: -50%\\nEXP Loader Damage: 89 (scales with level)`\n },\n \"Take This!\": {\n ranks: 1,\n text: \"FL4K's pet gains a copy of FL4K's shield.\",\n effect: (rank, level) => ``\n },\n \"Bul Loader\": {\n ranks: 0,\n text: \"FL4K's ION Loader upgrades into a BUL Loader, discarding it's sniper rifle and equipping a Shotgun. FL4K's BUL Loader also gains increased Damage Resistance and a powerful Roundhouse Melee Attack. While accompanies by the BUL Loader, FL4K's Shield Capacity is increased.\\n\\nWhen FL4K issues an Attack Command, the BUL Loader Briefly turns into a BullDozer to charge at enemies and knocks them up.\",\n effect: (rank, level) => `Shield Capacity: +20.0%`,\n type: SKILLS.AUGMENT_DIAMOND,\n },\n },\n \"4\": {\n \"Trap Card\": {\n ranks: 0,\n text: \"If FL4K would go into Fight For Your Life while their Trap is readied, they automatically throw a Trap at the enemy that downed them.\",\n effect: (rank, level) => `Duration: 16 seconds`,\n type: SKILLS.AUGMENT_CHEVRON,\n },\n \"Monkey Do!\": {\n ranks: 5,\n text: \"FL4K's pet gains increased Critical Hit Damage.\\n\\nWhenever FL4K's Pet scores a Critical Hit, FL4K's next shot deals Bonus Damage based on their weapon's damage.\",\n effect: (rank, level) => `Pet Critical Hit Damage: +${percent(rank, 14)}%\\nBonus Damage: ${percent(rank, 14)}% of weapon damage`\n },\n \"Wooly Armor\": {\n ranks: 1,\n text: \"While FL4K's shields are full, their pet gains Damage Reduction.\",\n effect: (rank, level) => `Pet Damage Reduction: +75%`\n },\n \"Not Even A Challenge\": {\n ranks: 5,\n text: \"Whenever FL4K's pet kills an enemy, FL4K gains increased Action Skill Duration and Action Skill Cooldown Rate for a short time. This effect stacks.\",\n effect: (rank, level) => `Cooldown Rate: +${percent(rank, 7)}%\\nAction Skill Duration: +${percent(rank, 7)}%\\nDuration: 12 seconds\\nMax Stacks: 10`\n },\n \"War Loader\": {\n ranks: 0,\n text: \"FL4K's ION Loader Upgrades into a WAR Loader, discarding it's sniper rifle and equipping an Incendiary Shotgun and Grenades. While accompanied by the WAR Loader, FL4K gains increased Fire Rate.\\n\\nWhen FL4K issues an Attack Command, the WAR loader unleashes a barrage of missles at the target.\",\n effect: (rank, level) => `Fire Rate: +12.0%`,\n type: SKILLS.AUGMENT_DIAMOND,\n },\n },\n \"5\": {\n \"Blind With Anger\": {\n ranks: 0,\n text: \"FL4K's Trap no longer Knocks Up or Stuns enemies. Instead, the Trap confuses nearby enemies, causing them to attack their allies for a short time. Once deployed, the Trap continues to periodically confuse enemies for the duration.\",\n effect: (rank, level) => `Confuse Duration: 8 seconds`,\n type: SKILLS.AUGMENT_CHEVRON,\n },\n \"Fuzzy Math\": {\n ranks: 5,\n text: \"Whenever FL4K or their pet scores a Critical Hit, a portion of FL4K's and their pet's shields are restored.\",\n effect: (rank, level) => `Shield REstore: +${percent(rank, 3)}% of Max Shields`\n },\n \"Keep Them Safe\": {\n ranks: 5,\n text: \"Whenever FL4K issues an Attack Command, if FL4K's or their pet's shield is less than half full a portion of FL4K's and their pet's shields are restored. This has a short cooldown.\",\n effect: (rank, level) => `Shield Restore: ${percent(rank, 10)}% of Max Shields\\nCooldown: 12 seconds`\n },\n },\n \"6\": {\n \"Capacitance\": {\n ranks: 1,\n text: \"Whenever FL4K activiates their Action Skill, they gain greatly increased Shield Capacity for a short time and immediately begin rechargin their shields. This skill has a short cooldown.\",\n effect: (rank, level) => `Shield Capacity: +100%\\nDuration: 16 seconds\\nCooldown: 16 seconds`\n },\n\n }\n }\n};\n\nexport default skills;\n","import VaultHunter from '@components/VaultHunter';\n\nimport skills from './skills.js';\n\nexport default function Gunner ({ path }) {\n return (\n \n );\n}\n","import VaultHunter from '@components/VaultHunter';\n\nimport skills from './skills.js';\n\nexport default function Operative ({ path }) {\n return (\n \n );\n}\n","export function getLevel (state) {\n return state.invested.reduce((total, current) => total + current, 2);\n};\n","import SKILLS from '@constants/skills';\n\nfunction percent (rank, unit) {\n return Math.round(rank * unit * 10) / 10;\n}\n\nfunction percentTwoDecimals (rank, unit) {\n return Math.round(rank * unit * 100) / 100;\n}\n\n// Matched Set Heat Per Shot\nfunction getMatchedSetHeatPerShot(rank) {\n switch (rank) {\n case 1:\n return 2;\n case 2:\n return 4;\n case 3:\n return 6;\n case 4:\n return 9;\n case 5:\n return 11;\n default:\n return 0;\n }\n}\n\n// Scrappy Handling\nfunction getScrappyHandling(rank) {\n switch (rank) {\n case 1:\n return 10.7;\n case 2:\n return 19.4;\n case 3:\n return 26.5;\n case 4:\n return 32.4;\n case 5:\n return 37.5;\n default:\n return 0;\n }\n}\n\n// Scrappy Weapon Swap Speed\nfunction getScrappyWeaponSwapSpeed(rank) {\n switch (rank) {\n case 1:\n return 16;\n case 2:\n return 27.5;\n case 3:\n return 36.3;\n case 4:\n return 43.2;\n case 5:\n return 48.7;\n default:\n return 0;\n }\n}\n\n// Scrappy Mode Switch Speed\nfunction getScrappyModeSwitchSpeed(rank) {\n switch (rank) {\n case 1:\n return 16;\n case 2:\n return 27.5;\n case 3:\n return 36.3;\n case 4:\n return 43.2;\n case 5:\n return 48.7;\n default:\n return 0;\n }\n}\n\n// Armored Infantry Damage Resistance\nfunction getArmoredInfantryDamageResistance(rank) {\n switch (rank) {\n case 1:\n return 3;\n case 2:\n return 6;\n case 3:\n return 8;\n case 4:\n return 11;\n case 5:\n return 13;\n default:\n return 0;\n }\n}\n\n// Vladof Ingenuity Shock Damage Resistance\nfunction getVladofIngenuityShockDamageResistance(rank) {\n switch (rank) {\n case 1:\n return 15;\n case 2:\n return 26;\n case 3:\n return 35;\n case 4:\n return 42;\n case 5:\n return 47;\n default:\n return 0;\n }\n}\n\n// Behind the Iron Curtain Shield Recharge Delay\nfunction getBehindTheIronCurtainShieldRechargeDelay(rank) {\n switch (rank) {\n case 1:\n return 12;\n case 2:\n return 21;\n case 3:\n return 28;\n default:\n return 0;\n }\n}\n\n// Deadlines Fuel Drain Modifier\nfunction getDeadlinesFuelDrain(rank) {\n switch (rank) {\n case 1:\n return 11;\n case 2:\n return 22;\n case 3:\n return 30;\n default:\n return 0;\n }\n}\n\n/* eslint-disable quotes */\nconst skills = {\n \"Bottomless Mags\": {\n \"0\": {\n \"Minigun\": {\n text: \"The Minigun is capable of sustained rapid fire. Firing for long periods causes the Minigun to overheat, rendering it inoperable for a few seconds. Element: Non-Elemental.\",\n type: SKILLS.ACTION_SKILL,\n effect: (rank, level) => `Put a little lead in the air and see what falls over.`,\n },\n },\n \"1\": {\n \"Cloud of Lead\": {\n text: \"Occasionally, Moze's and Iron Bear's shots will deal additional Incendiary Damage and won't consume ammo.\",\n ranks: 5,\n effect: (rank, level) => `Effects are triggered every ${9 - rank} shots\\nBonus Incendiary Damage: +${percentTwoDecimals(rank, 2.25)}%`,\n },\n \"Dakka Bear\": {\n text: \"Adds a manned turret to the back of Iron Bear. While manned, Iron Bear and its rider gain increased damage.\",\n ranks: 1,\n effect: (rank, level) => `Iron Bear Damage: +50%\\nIron Cub Damage: +20%`,\n },\n \"Matched Set\": {\n text: \"Moze's currently equipped weapon gains a stacking bonus to Magazine Size and Decreased Heat Per Shot for every piece of equipped gear that has a matching manufacturer.\",\n ranks: 5,\n effect: (rank, level) => `Magazine Size: +${percent(rank, 2)}% per matched gear\\nHeat Per Shot: -${getMatchedSetHeatPerShot(rank)}% per matched gear`,\n },\n },\n \"2\": {\n \"Let Off Some Steam\": {\n text: \"Minigun deals more damage as heat increases, and can be fired for longer before overheating.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Minigun Damage: Up to +80%\\nMinigun Heat Capacity: +35%`,\n },\n \"Stoke the Embers\": {\n text: \"Increases Moze and Iron Bear's Incendiary Damage.\",\n ranks: 3,\n effect: (rank, level) => `Incendiary Damage: +${percent(rank, 10)}%`,\n },\n \"Redistribution\": {\n text: \"After Moze scores a Critical Hit, she regenerates ammo and health for a few seconds.The lower her health, the more powerful the regeneration.\",\n ranks: 1,\n effect: (rank, level) => `Ammo Regeneration: +5% of Magazine Size/sec\\nHealth Regen: Up to +2.5% of Missing Health/sec\\nDuration: 3 seconds`,\n },\n \"Scrappy\": {\n text: \"While moving, Moze's Weapon Damage, Handling, Weapon Swap, and Mode Switch Speed are increased.\",\n ranks: 5,\n effect: (rank, level) => `Weapon Damage: +${percent(rank, 6)}%\\nHandling: +${getScrappyHandling(rank)}%\\nWeapon Swap Speed: +${getScrappyWeaponSwapSpeed(rank)}%\\nMode Switch Speed: +${getScrappyModeSwitchSpeed(rank)}%`,\n },\n \"Salamander\": {\n text: \"The Salamander is a flamethrower that deals Incendiary Damage to enemies at close range. Though the Salamander has infinite ammo, it drains Fuel with use.\",\n type: SKILLS.AUGMENT_ACTION_SKILL,\n effect: (rank, level) => `Fire... for effect.`,\n },\n },\n \"3\": {\n \"General Winter\": {\n text: \"Minigun fires Cryo rounds which reduce Heat Gain and Fuel Drain.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Minigun Fuel Drain: -40%\\nCryo Efficiency: +20%\\nMinigun Element: Cryo`,\n },\n \"Rushin' Offensive\": {\n text: \"Moze can sprint and shoot at the same time. While sprinting, Moze's weapons gain Life Steal.\",\n ranks: 1,\n effect: (rank, level) => `Life Steal: 8% of damage dealt`,\n },\n \"Scorching RPM's\": {\n text: \"Moze gains increased Fire Rate and Critical Hit Damage. Iron Bear gains increased Hard Point damage.\",\n ranks: 5,\n effect: (rank, level) => `Fire Rate: +${percent(rank, 3)}%\\nCritical Hit Damage: +${percent(rank, 4)}%\\nIron Bear Damage: +${percent(rank, 5)}%`,\n },\n \"Fuel Economy\": {\n text: \"Reduces Salamander's Fuel Drain. Additionally, Iron Bear's Movement Speed is increased after damaging an enemy with Salamander.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Salamander Fuel Drain: -25%\\nIron Bear Movement Speed: +50%\\nMovement Speed Duration: 3 seconds`,\n },\n },\n \"4\": {\n \"Exploding. Bullets.\": {\n text: \"Minigun fires Explosive Rounds that deal increased Splash Damage, but its Fire Rate is decreased.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Minigun Damage: +232%\\nMinigun Fire Rate: -75%`,\n },\n \"The Iron Bank\": {\n text: \"Increases Moze's Magazine Size.\",\n ranks: 5,\n effect: (rank, level) => `Magazine Size: +${percent(rank, 7)}%`,\n },\n \"Specialist Bear\": {\n text: \"Equipping two of the same Weapons on Iron Bear increases the damage they deal.\",\n ranks: 1,\n effect: (rank, level) => `Iron Bear Damage: +${percent(rank, 60)}%`,\n },\n \"Chemical Warfare\": {\n text: \"Salamander now deals Corrosive Damage. Additionally, Salamander's Melt Damage is increased.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Salamander Element: Corrosive\\nSalamander Melt Damage: +125%`,\n },\n },\n \"5\": {\n \"Some for the Road\": {\n text: \"Moze gains infinite ammo for a few seconds after exiting Iron Bear.\",\n ranks: 1,\n effect: (rank, level) => `Duration: 5 seconds`,\n },\n \"Click, Click...\": {\n text: \"Moze gains increased Gun Damage as her magazine empties. The less ammo there is remaining, the greater the increase. If Moze has a COV gun equipped, she gains Gun Damage as her gun's heat increases.\",\n ranks: 3,\n effect: (rank, level) => `Gun Damage: Up to +${percent(rank, 20)}%`,\n },\n \"Molten Roar\": {\n text: \"The Salamander burst-fires 3 projectiles with increased Damage, the first of which leaves a large Incendiary area.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Damage: +100%`,\n },\n },\n \"6\": {\n \"Forge\": {\n text: \"Moze constantly regenerates ammo for her currently equipped weapon.\",\n ranks: 1,\n effect: (rank, level) => `Ammo Regeneration: +5% of Magazine Size/sec`,\n },\n },\n },\n \"Demolition Woman\": {\n \"0\": {\n \"V-35 Grenade Launcher\": {\n text: \"The V-35 is a semi-automatic grenade launcher. Its grenades are not affected by Moze's equipped grenade mod. Element: Non-Elemental.\",\n type: SKILLS.ACTION_SKILL,\n ranks: 0,\n effect: (rank, level) => `For when the V-34 just isn't enough`,\n },\n },\n \"1\": {\n \"Fire in the Skag Den\": {\n text: \"Whenever Moze and Iron Bear deal Splash Damage, they deal bonus Incendiary Damage.\",\n ranks: 5,\n effect: (rank, level) => `Bonus Incendiary Damage: +${percent(rank, 3)}% of damage dealt`,\n },\n \"Deadlines\": {\n text: \"Firing Iron Bear Weapons drains less Fuel. Killing an enemy while Iron Bear is active increases Fuel. This skill has diminishing returns.\",\n ranks: 3,\n effect: (rank, level) => `Fuel Returned: Up to ${percent(rank, 2)}%\\nFuel Drain: -${getDeadlinesFuelDrain(rank)}%`,\n },\n \"Grizzled\": {\n text: \"Kill Skill. Killing an enemy reduces Moze's remaining Action Skill Cooldown Time. This skill has diminishing returns.\",\n ranks: 5,\n effect: (rank, level) => `Iron Bear Cooldown: -${rank * 1} seconds`,\n },\n },\n \"2\": {\n \"Shaped Charge\": {\n text: \"Direct hits with the V-35 deal increased damage.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `V-35 Direct Hit Damage: +35%`,\n },\n \"Means of Destruction\": {\n text: \"Whenever Moze deals Splash Damage, there is a chance to add ammo to her currently equipped weapon's magazine, with a smaller chance to return a grenade.\",\n ranks: 3,\n effect: (rank, level) => `Ammo Chance: +${percent(rank, 3.333)}%\\nGrenade Chance: +${percent(rank, 2)}%\\nCooldown: 0.3 seconds`,\n },\n \"Torgue Cross-Promotion\": {\n text: \"All Splash Damage dealt by Moze has a chance to double in size. Additionally, Moze and Iron Bear deal increased Splash Damage.\",\n ranks: 5,\n effect: (rank, level) => `Splash Damage: +${percent(rank, 6)}%\\nChance to Double Splash Radius: +${percent(rank, 3)}%`,\n },\n \"Stainless Steel Bear\": {\n text: \"Iron Bear gains additional armor, increased Maximum Fuel, and increased Damage.\",\n ranks: 5,\n effect: (rank, level) => `Maximum Fuel: +${percent(rank, 4)}%\\nIron Bear Armor: +${percent(rank, 6)}%\\nIron Bear Damage: +${percent(rank, 4)}%`,\n },\n \"Vanquisher Rocket Pod\": {\n text: \"The Vanquisher Rocket Pod is a rocket launcher capable of rapid-firing volleys of unguided explosive rockets. Element: Non-Elemental.\",\n type: SKILLS.AUGMENT_ACTION_SKILL,\n effect: (rank, level) => `If you want guidance, get a sherpa. If you want explosions, get a Vladof.`,\n },\n },\n \"3\": {\n \"Musical Chairs\": {\n text: \"Occasionally, the V-35 fires a Singularity Grenade that pulls in nearby enemies before exploding.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `V-35 Singularity: Every 7th grenade`,\n },\n \"Pull the Holy Pin\": {\n text: \"Moze's grenades have a chance to score a Critical Hit, dealing greatly increased damage. Sources of Critical Hit Damage do not affect grenade Critical Hits.\",\n ranks: 3,\n effect: (rank, level) => `Grenade Critical Hit Chance: +${percent(rank, 10)}%`,\n },\n \"Auto Bear\": {\n text: \"After Moze exits Iron Bear, it will remain deployed in place for a short time. While Auto Bear remains active, it will target and attack nearby enemies until its duration ends, then it will charge at an enemy and self-destruct.\",\n ranks: 1,\n effect: (rank, level) => `Auto Bear Duration: 15 seconds`,\n },\n \"Active Tracking\": {\n text: \"The Vanquisher Rocket Pod now fires homing rockets and has increased Reload Speed. Hold down [Action Skill key] and aim at enemies to designate up to 6 targets. Releasing Fire Button launches a volley of homing rockets at the designated targets.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Vanquisher Reload Speed: +25%`,\n },\n },\n \"4\": {\n \"Lock and Speedload\": {\n text: \"The V-35's Reload Speed is greatly increased and it now fires a 5-round burst.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `V-35 Reload Speed: +25%`,\n },\n \"Vampyr\": {\n text: \"Whenever Moze damages an enemy with a thrown grenade, for every enemy hit, she restores a portion of her missing health. Iron Bear restores armor for every enemy it deals Splash Damage to.\",\n ranks: 5,\n effect: (rank, level) => `Moze Health Restored: ${percent(rank, 4)}% of Missing Health per enemy hit\\nIron Bear Health Restored: ${percent(rank, 2)}% of Missing Armor per enemy hit`,\n },\n \"Why Can't I Carry All These Grenades\": {\n text: \"Increases Moze's grenade carrying capacity.\",\n ranks: 3,\n effect: (rank, level) => `Grenade Capacity: +${rank}`,\n },\n \"Target Softening\": {\n text: \"The Vanquisher Rocket Pod deals greatly reduced damage per rocket, but fires in a 6-rocket spread. Additionally, enemies hit by Vanquisher Rocket Pod rockets take increased damage from all sources.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Vanquisher Damage: -74%\\nEnemy Damage Taken: +15%`,\n },\n },\n \"5\": {\n \"To the Last\": {\n text: \"Moze gains the ability to throw grenades while in Fight For Your Life. If she threw a grenade before gaining a Second Wind, a grenade is refunded.\",\n ranks: 1,\n effect: (rank, level) => `The greatest enemy is one with nothing to lose... and a grenade.`,\n },\n \"Explosive Punctuation\": {\n text: \"When Moze deals Splash Damage, her Action Skill Cooldown Rate is briefly increased.\",\n ranks: 5,\n effect: (rank, level) => `Action Skill Cooldown Rate: +${percent(rank, 8)}%`,\n },\n \"Hammerdown Protocol\": {\n text: \"Instead of a volley of conventional rockets, the Vanquisher Rocket Pod launches a single rocket with a nuclear warhead, dealing massive Radiation Damage.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Vanquisher Damage: +600%\\nVanquisher Magazine Size: 1\\nVanquisher Element: Raditation\\n`,\n },\n },\n \"6\": {\n \"Short Fuse\": {\n text: \"Whenever Moze deals Gun Damage, there is a chance of a secondary explosion centered on the target.\",\n ranks: 1,\n effect: (rank, level) => `Secondary Explosion Chance: 20%\\nSecondary Explosion Damage: 75% of Gun Damage`,\n },\n },\n },\n \"Shield of Retribution\": {\n \"0\": {\n \"Railgun\": {\n text: \"The Railgun fires electrified high-velocity projectiles that deal Shock Damage.\",\n type: SKILLS.ACTION_SKILL,\n effect: (rank, level) => `It's like a bullet, only bigger. And faster. And wrapped in lightning.`,\n },\n },\n \"1\": {\n \"Selfless Vengeance\": {\n text: \"Whenever Moze reloads, she loses a small portion of her health and grants additional Incendiary Damage to her and her allies' rounds for a few seconds.\",\n ranks: 5,\n effect: (rank, level) => `Bonus Incendiary Damage: +${percent(rank, 3)}% of gun damage dealt\\nCurrent Health Removed: ${percent(rank, 1)}\\nDuration: ${rank + 5} seconds`,\n },\n \"Security Bear\": {\n text: \"Iron Bear gains a bubble shield that reduces damage taken. The shield deactivates if it sustains too much damage, reactivating after a short cooldown.\\nIf Iron Cub is equipped, it gains Damage Reduction instead.\",\n ranks: 1,\n effect: (rank, level) => `Bubble Recharge Delay: 5 seconds\\n50% of Iron Bear Maximum Armor added as Shields\\nIron Cub Damage Reduction: +50%`,\n },\n \"Armored Infantry\": {\n text: \"While Moze's shields are active, she gains Damage Resistance and increased Gun Damage.\",\n ranks: 5,\n effect: (rank, level) => `Gun Damage: +${percent(rank, 3)}%\\nDamage Resistance: +${getArmoredInfantryDamageResistance(rank)}%`,\n },\n },\n \"2\": {\n \"Hell on Rails\": {\n text: \"Railgun now fires superheated rounds that deal Incendiary Damge, but have increased Fuel Drain per shot.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Railgun Fuel Drain: +8%\\nRailgun Element: Incendiary`,\n },\n \"Drowning in Brass\": {\n text: \"Kill Skill. Killing an enemy grants Moze a stack of Drowning in Brass.\\n\\nFor each stack of Drowning in Brass, Moze's Fire Rate is reduced, but Gun Damage is increased for both her and her allies.\",\n ranks: 5,\n effect: (rank, level) => `Gun Damage: +${percent(rank, 4)}% per stack\\nMoze Fire Rate: -${percent(rank, 0.5)}% per stack\\nMaximum Stacks: 3\\nDuration: 15 seconds`,\n },\n \"Thin Red Line\": {\n text: \"A portion of Moze's health is Reserved and cannot be restored, but her Maximum Shield is increased by the same amount.\",\n ranks: 3,\n effect: (rank, level) => `${percent(rank, 20)}% Max Health Reserved and Added to Max Shield`,\n },\n \"Vladof Ingenuity\": {\n text: \"Moze's Maximum Shield and Shield Recharge Rate are increased, and she gains resistance to Shock Damage.\",\n ranks: 5,\n effect: (rank, level) => `Shield Recharge Rate: +${percent(rank, 4)}%Maximum Shield: +${percent(rank, 6)}%\\n\\nShock Damage Resistance: +${getVladofIngenuityShockDamageResistance(rank)}%`,\n },\n \"Bear Fist\": {\n text: \"The Bear Fist is a pneumatic-driven fist that deals massive damage to a single target at close range. Element: Non-Elemental.\",\n type: SKILLS.AUGMENT_ACTION_SKILL,\n effect: (rank, level) => `Vladof supports the right to bear armored bear arms.`,\n },\n },\n \"3\": {\n \"Capacitive Armature\": {\n text: \"When Railgun hits an enemy, it chains to nearby enemies, dealing reduced Shock Damage to more targets.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Splinter Damage: -30%`,\n },\n \"Full Can of Whoop-Ass\": {\n text: \"Entering Iron Bear causes Moze's and her allies' shields to immediately begin recharging at an increased Shield Recharge Rate.\",\n ranks: 1,\n effect: (rank, level) => `Shield Recharge Rate: +25%`,\n },\n \"Experimental Munitions\": {\n text: \"Whenever Moze and Iron Bear score a Critical Hit, they deal bonus Incendiary Damage.\",\n ranks: 1,\n effect: (rank, level) => `Bonus Incendiary Damage: +${percent(rank, 15)}% of damage dealt`,\n },\n \"Wild Swing\": {\n text: \"Whenever Bear Fist hits an enemy, it deals random Bonus Elemental Damage to that enemy and all enemies nearby.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Bear Fist Bonus Elemental Damage: +35% of damage dealt`,\n },\n },\n \"4\": {\n \"Corrosive Sabot Round\": {\n text: \"Railgun now fires a specialty round that deals reduced damage and explodes after a short delay.\\nRailgun shots have reduced Fuel Drain and the Magazine Size is increased.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Railgun Fuel Drain: -50%\\nRailgun Damage: -15%\\nRailgun Magazine Size: +2\\nRailgun Element:Corrosive`,\n },\n \"Behind the Iron Curtain\": {\n text: \"Moze's Shield Recharge Delay is reduced, and her Shield Recharge Rate is increased.\",\n ranks: 3,\n effect: (rank, level) => `Shield Recharge Rate: +${percent(rank, 11)}%\\nShield Recharge Delay: -${getBehindTheIronCurtainShieldRechargeDelay(rank)}%`,\n },\n \"Desperate Measures\": {\n text: \"Moze's Gun Damage and Iron Bear's Damage is increased depending on how low their health is. The lower their health, the greater the increase.\",\n ranks: 3,\n effect: (rank, level) => `Damage: Up to +${Math.round(percent(rank, 16.5))}%`,\n },\n \"Close the Distance\": {\n text: \"Instead of punching, Iron Bear now launches its Bear Fist forward and grabs enemies at greatly increased range, dealing Shock Damage and pulling them back to Iron Bear.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Step into my office.`,\n },\n },\n \"5\": {\n \"Phalanx Doctrine\": {\n text: \"Kill Skill. After killing an enemy, Moze gains a stack of Phalanx Doctrine. For every stack of Phalanx Doctrine, Moze's Maximum Shield and Gun Damage are increased. Each stack lasts 30 seconds.\\n\\nThere is no stack limit.\",\n ranks: 5,\n effect: (rank, level) => `Gun Damage: +${percent(rank, 2)}% per stack\\nMax Shields: +${percent(rank, 3)}% per stack\\nDuration: 30 seconds`,\n },\n \"Force Feedback\": {\n text: \"Whenever Moze scores a Critical Kill, her shields immediately begin recharging and she instantly regains a portion of her shield.\",\n ranks: 1,\n effect: (rank, level) => `Shields Restored: 10% of Maximum Shield`,\n },\n \"Shockhammer\": {\n text: \"Bear Fist is now capable of sustained rapid fire punching. Additionally, Bear Fist has reduced Fuel Drain and deals Bonus Shock Damage with each hit.\",\n type: SKILLS.AUGMENT_CHEVRON,\n effect: (rank, level) => `Bonus Shock Damage: +60% of damage dealt\\nFuel Drain: -40%`,\n },\n },\n \"6\": {\n \"Tenacious Defense\": {\n text: \"Whenever Moze's shield is fully depleted, she instantly restores a portion of her shield, and her Gun Damage is increased for a short time. This skill can only trigger after Moze's shields have fully recharged.\",\n ranks: 1,\n effect: (rank, level) => `Gun Damage: +30%\\nShields Restored: 40% of Maximum Shield\\nDuration: 30 seconds`,\n },\n },\n },\n \"Bear Mother\": {\n \"0\": {\n \"Iron Cub\": {\n ranks: 0,\n text: \"Moze Summons Iron Cub in place of Iron Bear. Iron Cub equips two of whatever weapon is equipped in the remaining Action Skill slot. While deployed, Iron Cub follows Moze and will target and attack enemies for the duration.\\nSkills that affect Iron Bear affect Iron Cub. Iron Cub still uses Fuel, but usses less of it and deals less damage (because it's smaller).\", \n effect: (rank, level) => ``\n },\n },\n \"1\": {\n \"Biofuel\": {\n ranks: 5,\n text: \"Whenever Moze or Iron Bear ignites an enemy, they both regenerate health for a short time.\", \n effect: (rank, level) => `Health Regen: Up to +${percent(rank, 0.7)}% per sec\\nIron Bear Armor Regen: Up to +${percent(rank, 0.5)}% per sec\\nDuration: 8 seconds`\n },\n \"Big Surplus\": {\n ranks: 3,\n text: \"While Moze's Action Skill is cooling down, she deals bonus Incendiary Damage.\", \n effect: (rank, level) => `Bonus Damage: ${percent(rank, 5)}% of Gun Damage`\n },\n \"Really Big Guns\": {\n ranks: 5,\n text: \"Iron Bear gains increased Damage.\", \n effect: (rank, level) => `Iron Bear Damage: +${percent(rank, 4)}%`\n }, \n },\n \"2\": {\n \"Double Time\": {\n ranks: 3,\n text: \"While Moze's Action Skill is active, she and Iron Bear gain increased Movement Speed.\", \n effect: (rank, level) => `Movement Speed: +${percent(rank, 12)}%`\n },\n \"Harmonious Havoc\": {\n ranks: 5,\n text: \"Moze gains increased Gun Damage for each weapon, shield, and grenade that matches the element of her gun.\", \n effect: (rank, level) => `Gun Damage: +${percent(rank, 2)}% per matching item`\n },\n \"Explosive Fury\": {\n ranks: 3,\n text: \"Moze and Iron Bear gain increased Status Effect Damage and Status Effect Chance.\", \n effect: (rank, level) => `Status Effect Chance: +${percent(rank, 9)}%\\nStatus Effect Damage: +${percent(rank, 5)}%`\n },\n \"Fuel For The Fire\": {\n ranks: 0,\n text: \"Whenever Moze or Iron Cub inflicts a Status Effect on an enemy, Iron Cub's armor is restored.\", \n effect: (rank, level) => `12% of Max Armor`,\n type: SKILLS.AUGMENT_CHEVRON,\n },\n },\n \"3\": {\n \"Baby Nukes\": {\n ranks: 0,\n text: \"Whenever Iron Cub is deployed or destroyed, it triggers a nuclear explosion, dealing massive Radation Damage.\", \n effect: (rank, level) => `Damage: 123 (scales with level)`,\n type: SKILLS.AUGMENT_CHEVRON,\n },\n \"Fired Up\": {\n ranks: 1,\n text: \"Whenever Moze or Iron Bear applies a Status Effect to an enemy, she gains increased Fire Rate for a short time. This effect stacks.\", \n effect: (rank, level) => `Fire Rate: +5%\\nDuration: 12 seconds\\nMax Stacks: 5`,\n }, \n },\n \"4\": {\n \"Nitrotrinadium Engines\": {\n ranks: 5,\n text: \"Iron Bear gains increased Maximum Fuel and Action Skill Cooldown Rate.\", \n effect: (rank, level) => `Maximum Fuel: +${percent(rank, 5)}%\\nAction Skill Cooldown Rate: +${percent(rank, 4)}%`\n },\n \"Never Going To Give You Up\": {\n ranks: 5,\n text: \"Whenever Moze or Iron Bear applies a Status Effect to an enemy, Iron Bear gains Fuel. This skill had diminishing returns.\", \n effect: (rank, level) => `Fuel Returned: Up to 15%`\n },\n \"My Little Friend\": {\n ranks: 0,\n text: \"Iron Cub spawns with Incendiary Vladof Assault Riffle in addition to Iron Cub's other weapons.\", \n effect: (rank, level) => ``,\n type: SKILLS.AUGMENT_CHEVRON,\n },\n },\n \"5\": {\n \"Efficiency Engine\": {\n ranks: 0,\n text: \"Moze gains increased Gun Damage. The longer Iron Cub has been active, the greater the bonus.\", \n effect: (rank, level) => `Gun Damage: +${percent(rank, 0.5)}% per second`,\n type: SKILLS.AUGMENT_CHEVRON,\n },\n \"Feature Creep\": {\n ranks: 1,\n text: \"Iron Bear gains increased Damage and Damage Resistance.\", \n effect: (rank, level) => `Iron Bear Damage: +18%\\nIron Bear Damage Resistance: +45%`\n },\n \"Limit Break\": {\n ranks: 3,\n text: \"Moze gains increased Action Skill Cooldown Rate whenever she or Iron Bear inflicts a Status Effect on an enemy. This effect stacks.\", \n effect: (rank, level) => `Cooldown Rate: +${percent(rank, 4)}%\\nDuration: 12 seconds\\nMax Stacks: 10`\n },\n \"Superior Firepower\": {\n ranks: 1,\n text: \"Whenever Moze or Iron Bear inflicts a Status Effect on an enemy, they gain increased Status Effect Damage.\", \n effect: (rank, level) => `Status Effect Damage: +20%\\nDuration: 8 seconds\\nMax Stacks: 5`\n },\n },\n \"6\": {\n \"Running On Fumes\": {\n ranks: 1,\n text: \"Whenever Moze or Iron Bear ignites an enemy, Iron Bear does not consume fuel for a short time.\", \n effect: (rank, level) => `Duration: 6 seconds`\n },\n },\n }\n};\n\nexport default skills;\n","!function(){\"use strict\";function e(e,t){var n,o,r,i,l=W;for(i=arguments.length;i-- >2;)P.push(arguments[i]);t&&null!=t.children&&(P.length||P.push(t.children),delete t.children);while(P.length)if((o=P.pop())&&void 0!==o.pop)for(i=o.length;i--;)P.push(o[i]);else\"boolean\"==typeof o&&(o=null),(r=\"function\"!=typeof e)&&(null==o?o=\"\":\"number\"==typeof o?o+=\"\":\"string\"!=typeof o&&(r=!1)),r&&n?l[l.length-1]+=o:l===W?l=[o]:l.push(o),n=r;var a=new T;return a.nodeName=e,a.children=l,a.attributes=null==t?void 0:t,a.key=null==t?void 0:t.key,void 0!==M.vnode&&M.vnode(a),a}function t(e,t){for(var n in t)e[n]=t[n];return e}function n(e,t){null!=e&&(\"function\"==typeof e?e(t):e.current=t)}function o(n,o){return e(n.nodeName,t(t({},n.attributes),o),arguments.length>2?[].slice.call(arguments,2):n.children)}function r(e){!e.__d&&(e.__d=!0)&&1==V.push(e)&&(M.debounceRendering||D)(i)}function i(){var e;while(e=V.pop())e.__d&&x(e)}function l(e,t,n){return\"string\"==typeof t||\"number\"==typeof t?void 0!==e.splitText:\"string\"==typeof t.nodeName?!e._componentConstructor&&a(e,t.nodeName):n||e._componentConstructor===t.nodeName}function a(e,t){return e.__n===t||e.nodeName.toLowerCase()===t.toLowerCase()}function u(e){var n=t({},e.attributes);n.children=e.children;var o=e.nodeName.defaultProps;if(void 0!==o)for(var r in o)void 0===n[r]&&(n[r]=o[r]);return n}function c(e,t){var n=t?document.createElementNS(\"http://www.w3.org/2000/svg\",e):document.createElement(e);return n.__n=e,n}function p(e){var t=e.parentNode;t&&t.removeChild(e)}function s(e,t,o,r,i){if(\"className\"===t&&(t=\"class\"),\"key\"===t);else if(\"ref\"===t)n(o,null),n(r,e);else if(\"class\"!==t||i)if(\"style\"===t){if(r&&\"string\"!=typeof r&&\"string\"!=typeof o||(e.style.cssText=r||\"\"),r&&\"object\"==typeof r){if(\"string\"!=typeof o)for(var l in o)l in r||(e.style[l]=\"\");for(var l in r)e.style[l]=\"number\"==typeof r[l]&&!1===E.test(l)?r[l]+\"px\":r[l]}}else if(\"dangerouslySetInnerHTML\"===t)r&&(e.innerHTML=r.__html||\"\");else if(\"o\"==t[0]&&\"n\"==t[1]){var a=t!==(t=t.replace(/Capture$/,\"\"));t=t.toLowerCase().substring(2),r?o||e.addEventListener(t,_,a):e.removeEventListener(t,_,a),(e.__l||(e.__l={}))[t]=r}else if(\"list\"!==t&&\"type\"!==t&&!i&&t in e){try{e[t]=null==r?\"\":r}catch(e){}null!=r&&!1!==r||\"spellcheck\"==t||e.removeAttribute(t)}else{var u=i&&t!==(t=t.replace(/^xlink:?/,\"\"));null==r||!1===r?u?e.removeAttributeNS(\"http://www.w3.org/1999/xlink\",t.toLowerCase()):e.removeAttribute(t):\"function\"!=typeof r&&(u?e.setAttributeNS(\"http://www.w3.org/1999/xlink\",t.toLowerCase(),r):e.setAttribute(t,r))}else e.className=r||\"\"}function _(e){return this.__l[e.type](M.event&&M.event(e)||e)}function f(){var e;while(e=A.shift())M.afterMount&&M.afterMount(e),e.componentDidMount&&e.componentDidMount()}function d(e,t,n,o,r,i){H++||(R=null!=r&&void 0!==r.ownerSVGElement,B=null!=e&&!(\"__preactattr_\"in e));var l=h(e,t,n,o,i);return r&&l.parentNode!==r&&r.appendChild(l),--H||(B=!1,i||f()),l}function h(e,t,n,o,r){var i=e,l=R;if(null!=t&&\"boolean\"!=typeof t||(t=\"\"),\"string\"==typeof t||\"number\"==typeof t)return e&&void 0!==e.splitText&&e.parentNode&&(!e._component||r)?e.nodeValue!=t&&(e.nodeValue=t):(i=document.createTextNode(t),e&&(e.parentNode&&e.parentNode.replaceChild(i,e),v(e,!0))),i.__preactattr_=!0,i;var u=t.nodeName;if(\"function\"==typeof u)return N(e,t,n,o);if(R=\"svg\"===u||\"foreignObject\"!==u&&R,u+=\"\",(!e||!a(e,u))&&(i=c(u,R),e)){while(e.firstChild)i.appendChild(e.firstChild);e.parentNode&&e.parentNode.replaceChild(i,e),v(e,!0)}var p=i.firstChild,s=i.__preactattr_,_=t.children;if(null==s){s=i.__preactattr_={};for(var f=i.attributes,d=f.length;d--;)s[f[d].name]=f[d].value}return!B&&_&&1===_.length&&\"string\"==typeof _[0]&&null!=p&&void 0!==p.splitText&&null==p.nextSibling?p.nodeValue!=_[0]&&(p.nodeValue=_[0]):(_&&_.length||null!=p)&&m(i,_,n,o,B||null!=s.dangerouslySetInnerHTML),y(i,t.attributes,s),R=l,i}function m(e,t,n,o,r){var i,a,u,c,s,_=e.childNodes,f=[],d={},m=0,b=0,y=_.length,g=0,w=t?t.length:0;if(0!==y)for(var C=0;C skill.ranks) { return false; }\n tierTotal += skill.invested || 0;\n };\n if (tierTotal > 0 && treeTotal + 5 < tierIndex * 5) { return false; }\n treeTotal += tierTotal;\n tierIndex += 1;\n };\n treeTotals[treeIndex] = treeTotal;\n totalSpent += treeTotal;\n treeIndex += 1;\n };\n if (totalSpent > (50 - 3) + 11 + 11) { return false; }\n return treeTotals;\n}\n","import deepmerge from 'deepmerge';\nimport investmentValidator from './investmentValidator';\nimport { setHash } from './hashHandler';\n\nexport default function reducer (state, action) {\n switch (action.type) {\n case 'skillChange':\n var newSkills = deepmerge(state.skills, {\n [action.treeName]: {\n [action.tierIndex + '']: {\n [action.skillName]: {\n invested: action.newValue,\n }\n }\n }\n });\n const skillChangeTotals = investmentValidator(newSkills);\n if (skillChangeTotals) {\n setHash(newSkills);\n return {\n ...state,\n invested: skillChangeTotals,\n skills: newSkills,\n };\n } else {\n return state;\n }\n case 'loadSkills':\n const loadSkillsTotals = investmentValidator(action.skills);\n if (loadSkillsTotals) {\n return {\n ...state,\n invested: loadSkillsTotals,\n skills: deepmerge(state.skills, action.skills),\n };\n } else {\n return state;\n }\n }\n}\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"footer\":\"Eq4mJ\",\"heart\":\"_37Gl6\",\"moveHeart\":\"_34mPq\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"splash\":\"_2_d3x\",\"wrapper\":\"vMurv\",\"link\":\"_3lx8i\",\"name\":\"_1SiOU\",\"job\":\"_3chgr\",\"disclaimer\":\"_3RIFV\"};","(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n\ttypeof define === 'function' && define.amd ? define(factory) :\n\t(global.deepmerge = factory());\n}(this, (function () { 'use strict';\n\nvar isMergeableObject = function isMergeableObject(value) {\n\treturn isNonNullObject(value)\n\t\t&& !isSpecial(value)\n};\n\nfunction isNonNullObject(value) {\n\treturn !!value && typeof value === 'object'\n}\n\nfunction isSpecial(value) {\n\tvar stringValue = Object.prototype.toString.call(value);\n\n\treturn stringValue === '[object RegExp]'\n\t\t|| stringValue === '[object Date]'\n\t\t|| isReactElement(value)\n}\n\n// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25\nvar canUseSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;\n\nfunction isReactElement(value) {\n\treturn value.$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction emptyTarget(val) {\n\treturn Array.isArray(val) ? [] : {}\n}\n\nfunction cloneUnlessOtherwiseSpecified(value, options) {\n\treturn (options.clone !== false && options.isMergeableObject(value))\n\t\t? deepmerge(emptyTarget(value), value, options)\n\t\t: value\n}\n\nfunction defaultArrayMerge(target, source, options) {\n\treturn target.concat(source).map(function(element) {\n\t\treturn cloneUnlessOtherwiseSpecified(element, options)\n\t})\n}\n\nfunction getMergeFunction(key, options) {\n\tif (!options.customMerge) {\n\t\treturn deepmerge\n\t}\n\tvar customMerge = options.customMerge(key);\n\treturn typeof customMerge === 'function' ? customMerge : deepmerge\n}\n\nfunction mergeObject(target, source, options) {\n\tvar destination = {};\n\tif (options.isMergeableObject(target)) {\n\t\tObject.keys(target).forEach(function(key) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(target[key], options);\n\t\t});\n\t}\n\tObject.keys(source).forEach(function(key) {\n\t\tif (!options.isMergeableObject(source[key]) || !target[key]) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(source[key], options);\n\t\t} else {\n\t\t\tdestination[key] = getMergeFunction(key, options)(target[key], source[key], options);\n\t\t}\n\t});\n\treturn destination\n}\n\nfunction deepmerge(target, source, options) {\n\toptions = options || {};\n\toptions.arrayMerge = options.arrayMerge || defaultArrayMerge;\n\toptions.isMergeableObject = options.isMergeableObject || isMergeableObject;\n\n\tvar sourceIsArray = Array.isArray(source);\n\tvar targetIsArray = Array.isArray(target);\n\tvar sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;\n\n\tif (!sourceAndTargetTypesMatch) {\n\t\treturn cloneUnlessOtherwiseSpecified(source, options)\n\t} else if (sourceIsArray) {\n\t\treturn options.arrayMerge(target, source, options)\n\t} else {\n\t\treturn mergeObject(target, source, options)\n\t}\n}\n\ndeepmerge.all = function deepmergeAll(array, options) {\n\tif (!Array.isArray(array)) {\n\t\tthrow new Error('first argument should be an array')\n\t}\n\n\treturn array.reduce(function(prev, next) {\n\t\treturn deepmerge(prev, next, options)\n\t}, {})\n};\n\nvar deepmerge_1 = deepmerge;\n\nreturn deepmerge_1;\n\n})));\n","import SKILLS from '@constants/skills';\nimport style from './index.css';\n\nfunction getInitials (string) {\n const numWords = (string.match(/\\s/g) || []).length + 1;\n switch (numWords) {\n case 1:\n return string.slice(0, 3);\n case 2:\n return (string.match(/^\\w{1,2}|\\s\\w{1,2}/g) || []).join('').replace(/\\s/g, '');\n default:\n return (string.match(/^\\w|\\s\\w/g) || []).join('').replace(/\\s/g, '');\n }\n}\n\nexport default function Skill ({\n name = '?',\n text = 'Long description',\n ranks = 0,\n invested = 0,\n tier = 0,\n level = 1,\n effect = (rank, level) => `Rank ${rank} effect`,\n type = null,\n enabled = true,\n image = null,\n onChange = (oldValue, newValue) => null,\n}) {\n const isAugment = [\n SKILLS.AUGMENT_CHEVRON,\n SKILLS.AUGMENT_DIAMOND,\n SKILLS.AUGMENT_ACTION_SKILL,\n ].includes(type);\n let shapeStyle = null;\n if (type === SKILLS.ACTION_SKILL) { shapeStyle = style.actionSkill; }\n if (type === SKILLS.AUGMENT_CHEVRON) { shapeStyle = style.chevron; }\n if (type === SKILLS.AUGMENT_DIAMOND) { shapeStyle = style.diamond; }\n if (type === SKILLS.AUGMENT_ACTION_SKILL) { shapeStyle = style.actionSkill; }\n function clickListener (event) {\n var newValue;\n if (event.type === 'click') {\n newValue = Math.min(invested + 1, ranks);\n } else { // (event.type === 'contextmenu')\n newValue = Math.max(invested - 1, 0);\n }\n if (enabled && invested !== newValue) {\n onChange(invested, newValue);\n }\n event.preventDefault();\n return false;\n }\n return (\n