diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..a6700a9
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,34 @@
+{
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "jsx": true,
+ "useJSXTextNode": true,
+ "ecmaVersion": 2018,
+ "sourceType": "module",
+ "project": "./tsconfig.json"
+ },
+ "plugins": [
+ "@typescript-eslint",
+ "roblox-ts",
+ "prettier"
+ ],
+ "extends": [
+ "plugin:@typescript-eslint/recommended",
+ "plugin:roblox-ts/recommended",
+ "plugin:prettier/recommended"
+ ],
+ "rules": {
+ "prettier/prettier": [
+ "warn",
+ {
+ "semi": true,
+ "endOfLine": "auto",
+ "trailingComma": "all",
+ "singleQuote": false,
+ "printWidth": 120,
+ "tabWidth": 4,
+ "useTabs": true
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fe46883
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+/node_modules
+/out
+/include
+/models
+*.tsbuildinfo
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..c544019
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,6 @@
+{
+ "recommendations": [
+ "roblox-ts.vscode-roblox-ts",
+ "dbaeumer.vscode-eslint"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..b0d6f91
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,13 @@
+{
+ "[typescript]": {
+ "editor.defaultFormatter": "dbaeumer.vscode-eslint",
+ "editor.formatOnSave": true
+ },
+ "[typescriptreact]": {
+ "editor.defaultFormatter": "dbaeumer.vscode-eslint",
+ "editor.formatOnSave": true
+ },
+ "eslint.run": "onType",
+ "eslint.format.enable": true,
+ "typescript.tsdk": "node_modules/typescript/lib"
+}
\ No newline at end of file
diff --git a/default.project.json b/default.project.json
new file mode 100644
index 0000000..84ec99c
--- /dev/null
+++ b/default.project.json
@@ -0,0 +1,184 @@
+{
+ "name": "roblox-ts-game",
+ "globIgnorePaths": [
+ "**/package.json",
+ "**/tsconfig.json"
+ ],
+ "tree": {
+ "$className": "DataModel",
+ "ServerScriptService": {
+ "$className": "ServerScriptService",
+ "TS": {
+ "$path": "out/server"
+ }
+ },
+ "StarterPlayer": {
+ "$className": "StarterPlayer",
+ "StarterPlayerScripts": {
+ "$className": "StarterPlayerScripts",
+ "Client": {
+ "$path": "out/client"
+ }
+ }
+ },
+ "Players": {
+ "$className": "Players",
+ "$properties": {
+ "CharacterAutoLoads": false
+ }
+ },
+ "Workspace": {
+ "$className": "Workspace",
+ "$properties": {
+ "FilteringEnabled": true
+ },
+ "Enemies": {
+ "$className": "Folder"
+ },
+ "Effects": {
+ "$className": "Folder"
+ },
+ "Projectiles": {
+ "$className": "Folder"
+ },
+ "Map": {
+ "$className": "Folder"
+ }
+ },
+ "ReplicatedStorage": {
+ "$className": "ReplicatedStorage",
+ "rbxts_include": {
+ "$path": "include",
+ "node_modules": {
+ "$path": "node_modules/@rbxts"
+ }
+ },
+ "TS": {
+ "$path": "out/shared"
+ },
+ "Remotes": {
+ "$className": "Folder",
+ "Input": {
+ "$className": "RemoteEvent"
+ },
+ "Output": {
+ "$className": "RemoteEvent"
+ },
+ "Dialog": {
+ "$className": "RemoteEvent"
+ }
+ },
+ "Meshpile": {
+ "$className": "Folder",
+ "SlashM": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://5718206850"
+ }
+ },
+ "SlashS": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://5718207735"
+ }
+ },
+ "BallEffect": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://5718227062"
+ }
+ },
+ "SphereFHD": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://888904946"
+ }
+ },
+ "SphereQHD": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://1005510660"
+ }
+ },
+ "SphereUHD": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://1221611042"
+ }
+ },
+ "CylinderUHD": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://563974169"
+ }
+ },
+ "CylinderFHD": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://442130733"
+ }
+ },
+ "CylinderQHD": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://465435723"
+ }
+ },
+ "10smash": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://489415286"
+ }
+ },
+ "GroundWave": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://863344136"
+ }
+ },
+ "InvertedSphere": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://4729380505"
+ }
+ },
+ "FlatSlash1": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://6355336640"
+ }
+ },
+ "CylinderShockwave1": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://6386165479"
+ }
+ },
+ "SphereShockwave1": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://6355255043"
+ }
+ },
+ "diamond": {
+ "$className": "MeshPart",
+ "$properties": {
+ "MeshId": "rbxassetid://2570899763"
+ }
+ }
+ }
+ },
+ "HttpService": {
+ "$className": "HttpService",
+ "$properties": {
+ "HttpEnabled": true
+ }
+ },
+ "SoundService": {
+ "$className": "SoundService",
+ "$properties": {
+ "RespectFilteringEnabled": true
+ }
+ }
+ }
+}
diff --git a/init.client.lua b/init.client.lua
new file mode 100644
index 0000000..99a0827
--- /dev/null
+++ b/init.client.lua
@@ -0,0 +1,1122 @@
+
+--Setup and Variables
+
+--Constant variables
+local plrs = game:GetService("Players")
+local wS = game.Workspace
+local twS = game:GetService("TweenService")
+local runService = game:GetService("RunService")
+
+local paris = ipairs
+local tn = tonumber
+local tSt = tostring
+local unpack = unpack -- you can thank b1ooq for this one
+local pcall = pcall
+
+local rgb = Color3.fromRGB
+local hsv = Color3.fromHSV
+
+local sub = string.sub
+
+local tFind = table.find
+local insert = table.insert
+
+local new = Instance.new
+local uD2 = UDim2.new
+local v3 = Vector3.new
+local cF = CFrame.new
+--local nSK = NumberSequenceKeypoint.new
+
+local tweenServiceCreate = twS.Create
+local play = new("Tween").Play
+local destroy = game.Destroy
+
+local xyz = CFrame.fromEulerAnglesXYZ
+local wrap = coroutine.wrap
+
+local floor = math.floor
+local ceil = math.ceil
+local abs = math.abs
+local cos = math.cos
+local sin = math.sin
+local rad = math.rad
+local rand = math.random
+local clamp = math.clamp
+
+local zF = cF(0,0,0)
+
+--End of universal constant variables
+
+local uIS = game:GetService("UserInputService")
+--local uISLockedCenter = Enum.MouseBehavior.LockCenter
+--local uISDefault = Enum.MouseBehavior.Default
+
+local rid = "rbxassetid://"
+local clock = os.clock
+local sequence = NumberSequence.new
+local upper = string.upper
+local len = string.len
+local Plr = plrs.LocalPlayer
+local plrGui = Plr.PlayerGui
+local Cam = game.Workspace.CurrentCamera
+local efFolder = game.Workspace.Effects
+local repS = game:GetService("ReplicatedStorage").Common
+local Rems = repS.Remotes
+local Input = Rems.Input
+local Output = Rems.Output
+local ModeEvent = script.ModeEvent
+
+local camera = wS.CurrentCamera
+local camCustom = Enum.CameraType.Custom
+local camScriptable = Enum.CameraType.Scriptable
+
+local DialogEvent = Rems.Dialog
+local isDialog = false
+--local DialogList = require(script.Parent.Dialog)
+--local enemyCEs = require(script.EnemyClientEvents)
+local eLM = repS.EnemyLocalModules
+local enemyModules = {}
+warn("Amount of enemy modules: " .. tSt(#eLM:GetChildren()))
+for i, v in pairs(eLM:GetChildren()) do
+ enemyModules[v.Name] = require(v)
+ warn("Required " .. v.Name)
+end
+
+local v3Lerp = Vector3.new().Lerp
+
+function ara(v) --NOT A JOJO REFERENCE SHUT UP
+ return rand(-100,100)/100*v
+end
+
+function GetDist(one,two)
+ return (two-one).Magnitude
+end
+
+local function floorToBase(number,base)
+ return floor(number*base)/base
+end
+
+--music
+local Music = Instance.new("Sound",game.Workspace)
+Music.Name = "Music"
+Music.Looped = true
+Music.SoundId = rid .. "564466195"
+Music:Play()
+local SendPlaybackLoudness = false
+Music.PlaybackSpeed = 1
+local coolUpdateCycle = 0
+
+local function omniWait(waitTime)
+ local sum = 0
+ while sum < waitTime do
+ local t, step = runService.Stepped:Wait()
+ sum += step
+ end
+end
+
+------------------------
+-- Decorative Set GUI --
+------------------------
+
+local Gui = nil
+local Title = nil
+local TitleShadow = nil
+local Vis = nil
+local VisTable = {}
+local MusicLabel = nil
+function makeGui(whichGui)
+ Gui = script[whichGui .. "Gui"]:Clone()
+ Gui.Parent = plrGui
+ Title = Gui.Title
+ TitleShadow = Gui:FindFirstChild("TitleShadow")
+ Vis = Gui.Visualizer
+ local absSize = Vis.AbsoluteSize
+ Vis.Position = Vis.Position + uD2(0,absSize.Y-absSize.X,0,0)
+ Vis.Size = Vis.Size + uD2(0,absSize.Y-absSize.X,0,0)
+ VisTable = {}
+ MusicLabel = Gui.Top.Music
+ for i = 1, #Vis:GetChildren() do
+ local bar = Vis["Bar" .. tSt(i)]
+ insert(VisTable,{bar,bar.Position,bar.Size})
+ end
+end
+makeGui("Star")
+
+function changeGuiMode(name,color1,color2,font,artist,track)
+ Title.Text = upper(name)
+ Title.Font = font
+ Title.TextColor3 = color1
+ Title.TextStrokeColor3 = color2
+ MusicLabel.Text = artist .. " - " .. track
+ if TitleShadow then
+ TitleShadow.Text = upper(name)
+ TitleShadow.Font = font
+ end
+ for i, v in pairs(VisTable) do
+ v[1].BackgroundColor3 = color1
+ end
+ --adapt to aspect ratio
+ local absSize = Vis.AbsoluteSize
+ Vis.Position = Vis.Position + uD2(0,absSize.Y-absSize.X,0,0)
+ Vis.Size = Vis.Size + uD2(0,absSize.Y-absSize.X,0,0)
+end
+
+--Miscellaneous
+function CamShake(ins,reps)
+ local Hum = Plr.Character.Humanoid
+ for i = 1, reps do
+ local mult = 1-i/reps
+ local goal = v3(ara(ins)*mult,ara(ins)*mult,ara(ins)*mult)
+ for j = 1,2 do
+ local mult = 1-i/reps
+ Hum.CameraOffset = v3Lerp(Hum.CameraOffset,goal,0.5)
+ omniWait(0.016)
+ end
+ end
+ local goal = v3(0,0,0)
+ for j = 1,2 do
+ Hum.CameraOffset = v3Lerp(Hum.CameraOffset,goal,0.5)
+ omniWait(0.016)
+ end
+ Hum.CameraOffset = goal
+end
+
+local Notifier = plrGui:WaitForChild("Help")
+
+local tim = nil
+local NotifyTinfo1 = TweenInfo.new(0.25,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
+local NotifyTinfo2 = TweenInfo.new(0.5,Enum.EasingStyle.Linear)
+local goal1 = {TextTransparency = 0}
+local goal2 = {TextTransparency = 1}
+function Notify(message)
+ tim = os.time()
+ local tim2 = tim
+ Notifier.Label.Text = message
+ if not Notifier.Enabled then
+ Notifier.Enabled = true
+ twS:Create(Notifier.Label,NotifyTinfo1,goal1):Play()
+ end
+ wait(2)
+ if tim == tim2 then
+ twS:Create(Notifier.Label,NotifyTinfo2,goal2):Play()
+ wait(1)
+ Notifier.Enabled = false
+ end
+end
+
+local modeKeys = {"Q","E","R","F"}
+local abilityKeys = {"Z","X","C","V"}
+local otherModeKeys = {"B","N","M","1","2","3","4"}
+
+--------------------
+-- Main interface --
+--------------------
+
+local mainInterface = plrGui:WaitForChild("MainInterface")
+local interfaceCooldowns = mainInterface.Cooldowns
+local interfaceDiamond = mainInterface.Diamond
+local interfaceMenu = mainInterface.Menu
+interfaceDiamond.Visible = false
+interfaceMenu.Visible = false
+
+--------------------
+-- Cooldown stuff --
+--------------------
+
+local coolDown = {}
+local movesExist = {Z = nil,X = nil,C = nil,V = nil}
+
+function getCoolTime(tab)
+ if not tab then
+ return 0
+ end
+ local t = tab[2]-(clock()-tab[1])
+ return t > 0 and floorToBase(t,10) or 0
+end
+
+local currentCoolCycle = 0
+
+function updateCooldownGui(Set,Side,Mode,Color)
+ --Stop any other cooldown loops currently occurring
+ local thisCycle = clock()
+ currentCoolCycle = thisCycle
+ for i, inp in pairs(abilityKeys) do
+ local part = interfaceCooldowns[inp]
+ if movesExist[inp] then
+ part.Visible = true
+ if Color then
+ part.Star1.BackgroundColor3 = Color
+ part.Star1.Star12.BackgroundColor3 = Color
+ end
+
+ --Show the counter
+ part.Gradient.Transparency = sequence(1,0.7)
+ part.WhiteBarBottom.Visible = true
+ part.WhiteBarTop.Visible = true
+ part.FramePart.Visible = true
+ part.WhiteBarDiagonal.Visible = true
+ part.Time.Visible = true
+
+ --Get potential cooldowns
+ local cool = nil
+ local coolTime = 0
+
+ local cools = {coolDown.Main,coolDown[inp],coolDown[Set .. Side .. Mode .. inp]}
+
+ --Determine the greatest cooldown
+ for i, v in pairs(cools) do
+ local t = getCoolTime(v)
+ if t > coolTime then
+ cool = v
+ coolTime = t
+ end
+ end
+
+ coroutine.wrap(function() -- Cool down
+ while currentCoolCycle == thisCycle and coolTime > 0 do --Update the cooltime and GUI while it exists
+ coolTime = getCoolTime(cool)
+ part.Time.Text = coolTime
+ wait(0.1)
+ end
+
+ if coolTime <= 0 then --Remove the counter (only) once done cooling
+ part.Gradient.Transparency = sequence(1)
+ part.WhiteBarBottom.Visible = false
+ part.WhiteBarTop.Visible = false
+ part.FramePart.Visible = false
+ part.WhiteBarDiagonal.Visible = false
+ part.Time.Visible = false
+ end
+ end)()
+ else
+ part.Visible = false
+ end
+ end
+end
+
+
+function handleCooldown(cool,inp,Set,Side,Mode)
+ local now = floorToBase(clock(),10)
+ coolDown.Main = {now,cool}
+ coolDown[inp] = {now,cool*3}
+ coolDown[Set .. Side .. Mode .. inp] = {now,cool*9}
+ updateCooldownGui(Set,Side,Mode)
+end
+
+
+----------------------------------
+-- Mode switching diamond stuff --
+----------------------------------
+
+local storedModeKey = ""
+
+function resizeDiamond()
+ local diamondAbs = interfaceDiamond.AbsoluteSize
+ local sizeDiff = diamondAbs.Y-diamondAbs.X
+ interfaceDiamond.Size = uD2(0.281,sizeDiff,0.5,0)
+ interfaceDiamond.Position = uD2(0.359,sizeDiff/(-2),0.25,0)
+ local strokeSize = ceil(diamondAbs.Y*0.00926)
+ for i = 1, 4 do
+ interfaceDiamond["Box" .. tSt(i)].Inside.UIStroke.Thickness = strokeSize
+ end
+end
+resizeDiamond()
+
+function updateDiamond(data)
+ for j = 1, 4 do
+ local thisBox = interfaceDiamond["Box" .. tSt(j)].Inside
+ for i = 1, 4 do
+ local thisStar = thisBox["Star" .. tSt(i)]
+ --print("Trying to obtain " .. tSt(modeKeys[j]) .. tSt(modeKeys[i]))
+ local thisColor = data[modeKeys[j]][modeKeys[i]]
+ if thisColor then
+ thisStar.BackgroundColor3 = thisColor
+ thisStar.Piece1.BackgroundColor3 = thisColor
+ thisStar.Visible = true
+ else
+ thisStar.Visible = false
+ end
+ end
+ end
+end
+
+local normalPositions = {uD2(0,0,0,0),uD2(0.5,0,0,0),uD2(0.5,0,0.5,0),uD2(0,0,0.5,0)}
+local boxResizes = {{1,1},{0,1},{0,0},{1,0}}
+local boxMajorOffsets = {{0,-1},{1,0},{0,1},{-1,0}}
+local diamondOffsets = {0.12,0.2}
+
+function resizeBoxes(mainBox,bigSize,smallSize)
+ for i = 1, 4 do
+ local object = interfaceDiamond["Box" .. tSt(i)]
+ local size = (i == mainBox and bigSize) or smallSize --Use the big box size if the box is the main one
+ local offset = 0.5-size
+ local boxFactors = boxResizes[i]
+ object.Size = uD2(size,0,size,0)
+ object.Position = normalPositions[i]+uD2(boxFactors[1]*offset,0,boxFactors[2]*offset,0)
+ end
+ local mainOffsets = boxMajorOffsets[mainBox]
+ interfaceDiamond.Position = uD2(0.359-diamondOffsets[1]*mainOffsets[1],0,0.25-diamondOffsets[2]*mainOffsets[2],0) --Offset the main diamond
+end
+
+--------------
+-- The Menu --
+--------------
+local menuIsOpen = false
+local currentPage = 2 -- 1 is forms, 2 is equips, 3 is summons, 4 is settings/info
+local menuInTransit = false
+local buttonMouseIsOn = ""
+local pages = interfaceMenu.Pages
+local mainStar = mainInterface.FatStar
+local lineR, lineB = interfaceMenu.RightLine, interfaceMenu.BottomLine
+local starR, starB = interfaceMenu.StarTR, interfaceMenu.StarBL
+local buttonParent = interfaceMenu.NavButtons
+local buttons = {buttonParent.Forms,buttonParent.Equips,buttonParent.Summons,buttonParent.Other}
+local buttonTags = {"Forms","Equipment","Enemies","Information and Settings"}
+local pageFolder = interfaceMenu.Pages
+local pages = {nil,pageFolder.Equipment,nil,nil}
+local selectName, selectDetails = interfaceMenu.SelectName, interfaceMenu.SelectDetails
+local pageName, nameDecoration = interfaceMenu.PageName, interfaceMenu.NameDecoration
+local hoverLabel = mainInterface.HoverLabel
+hoverLabel.Visible = false
+
+-----------------------
+-- Page 2: Equipment --
+-----------------------
+local equipModule = require(repS.EquipModule)
+local equipDisplay = pages[2].Display
+local displaySortType, displaySortDirection = pages[2].SortType, pages[2].SortDirection
+local tabWeapons, tabArmor = pages[2].TabWeapons, pages[2].TabArmor
+local equipFolder = repS.Equipment
+local sEquipName = pages[2].WeaponName -- sEquip is shorthand for "selected equip"
+local sEquipDescription = pages[2].WeaponDescription
+local sEquipType = pages[2].WeaponType
+local sEquipTraits = {pages[2].WeaponTrait1,pages[2].WeaponTrait2,pages[2].WeaponTrait3,pages[2].WeaponTrait4}
+local sEquipFrame = pages[2].ItemSelected.ViewportFrame
+local sEquipCam = new("Camera")
+sEquipCam.CameraType = Enum.CameraType.Scriptable
+sEquipCam.Parent = sEquipFrame
+sEquipCam.CFrame = CFrame.new(0,10,-10)
+sEquipFrame.CurrentCamera = sEquipCam
+
+local spinning = false
+local spinAngle = 0
+local spinMagnitude = 0
+local spinY = 0
+
+local currentEquipCategory = 1
+local sEquip = 0
+
+local equipRarityColors = {rgb(255,255,255),rgb(255,246,124),rgb(255,36,50),rgb(216,58,255),rgb(101,59,255),rgb(64,182,255)}
+local equipRarityNames = {"Regular", "Advanced", "Elite", "Extraordinary", "Transcendent", "Exalted"}
+local equipTraitNames = {"%attack", "defense", "%health", "%resistance", "speed"}
+local equipTraitColors = {"ff0e0e", "7db4f3", "5aee7d", "3155f5", "eeea5b"}
+
+local currentSortOrder = 1
+local sortReverse = false
+
+local function flipArray(array)
+ local n = #array
+ for i = 1, floor(n/2) do
+ local a, b = array[i], array[n + 1 - i]
+ array[i] = b
+ array[n + 1 - i] = a
+ end
+end
+
+local function sortRarity(one,two,fallbackSort,fallbackFallback)
+ local a, b = one[2], two[2]
+ if a < b then
+ return false
+ elseif a > b or not fallbackSort then
+ return true
+ else
+ return fallbackSort(one,two,fallbackFallback)
+ end
+end
+
+
+local function sortClass(one,two,fallbackSort,fallbackFallback)
+ local a, b = tn(sub(tSt(one[7]),1,1)), tn(sub(tSt(two[7]),1,1))
+ if a > b then
+ return false
+ elseif a < b or not fallbackSort then
+ return true
+ else
+ return fallbackSort(one,two,fallbackFallback)
+ end
+end
+
+local function sortAlpabetically(one,two,fallbackSort,fallbackFallback)
+ local a, b = one[1], two[1]
+ local aN, bN = len(a), len(b)
+ local n = (aN <= bN and aN) or bN
+ for i = 1, n do
+ local A, B = upper(sub(a,i,i)), upper(sub(b,i,i))
+ if A < B then
+ return true
+ elseif A > B then
+ return false
+ end
+ end --At this point, the names are entirely identical until the shortest one ends
+ if aN == bN and fallbackSort then
+ return fallbackSort(one,two,fallbackFallback)
+ elseif n == aN then -- If a is the shorter one (n), we return it. If the strings are identical, we return a (true) to keep them in their previous order (stable sorting).
+ return true
+ else
+ return false
+ end
+end
+
+local sortOrders = {
+ {"Rarity", {sortRarity, sortClass, sortAlpabetically}},
+ {"Class", {sortClass, sortRarity, sortAlpabetically}},
+ {"Name", {sortAlpabetically, sortRarity, sortClass}}
+}
+
+ -----------------------------------------------
+--| leftSorter -> leftEnd | rightSorter -> last |--
+ -----------------------------------------------
+local function merge(array,first,last,sorter1,sorter2,sorter3)
+ local leftEnd = floor((first + last)/2) --1
+ local leftSorter = first --1
+ local rightSorter = leftEnd + 1 -- 2
+ local sorted = {unpack(array)}
+ for i = first, last do
+ if rightSorter > last or (leftSorter <= leftEnd and sorter1(array[leftSorter],array[rightSorter],sorter2,sorter3)) then --Switch last to < to reverse order
+ sorted[i] = array[leftSorter]
+ leftSorter += 1
+ else
+ sorted[i] = array[rightSorter]
+ rightSorter += 1
+ end
+ end
+ for i = first, last do
+ array[i] = sorted[i]
+ --print(sorted[i][1])
+ end
+end
+
+function mergeSort(array,first,last,sorter1,sorter2,sorter3)
+ first = first or 1
+ last = last or #array
+
+ if first < last then
+ local middle = floor((first + last)/2)
+ mergeSort(array,first,middle,sorter1,sorter2,sorter3) -- Sort left (recursively)
+ mergeSort(array,middle + 1,last,sorter1,sorter2,sorter3) -- Sort right (recursively)
+
+ merge(array,first,last,sorter1,sorter2,sorter3)
+ end
+end
+
+local format = string.format
+
+function refreshEquips(ownedWeapons)
+ local equips = {unpack(equipModule[currentEquipCategory])} --Later this will be only the equips you have unlocked
+ local count = #equips
+ local rows = ceil(count/4)
+ -- Sort the equips
+ mergeSort(equips,nil,nil,unpack(sortOrders[currentSortOrder][2]))
+ if sortReverse then
+ flipArray(equips)
+ end
+ -- Adjust the canvas size to make all of the frames perfectly square
+ local pixelWidth = equipDisplay.Frame.AbsoluteSize.X
+ local displayY = (pixelWidth/5)*(rows*6 + 1)
+ local displayAbsY = equipDisplay.AbsoluteSize.Y
+ equipDisplay.CanvasSize = uD2(0,0,0,displayY)
+ --Adjust if there are < 4 rows
+ local practicalCanvas = 1
+ local offset
+ if rows < 4 and displayY <= displayAbsY then
+ offset = pixelWidth/5/displayAbsY--offset = 0.0467289
+ else
+ offset = 1/(rows*6 + 1)
+ end
+ -- Adjust the frame sizes to make them take up the right amounts of the canvas
+ --local offset = practicalCanvas/(rows*6 + 1)
+ local height = offset*5
+ local diff = offset*6
+
+ for i, v in pairs(equipDisplay:GetChildren()) do
+ if v.Name ~= "Frame" then
+ v:Destroy()
+ end
+ end
+
+ local frameName = "WeaponFrame"
+ if currentEquipCategory == 2 then
+ frameName = "ArmorFrame"
+ end
+
+ for i, equip in paris(equips) do
+ local row = ceil(i/4) - 1
+ local column = i - row*4 - 1
+
+ local f = new("Frame")
+ f.Name = frameName
+ f.Size = uD2(0.2,0,height,0)
+ f.Position = uD2(0.04 + column*0.24,0,offset + row*diff,0)
+ f.BorderSizePixel = 0
+
+ local vF = new("ViewportFrame")
+ vF.Name = equip[8]
+ vF.Size = uD2(1,0,1,0)
+ vF.BackgroundTransparency = 1
+ vF.Position = uD2(0,0,0,0)
+ local w = equipFolder[equip[1]]:Clone()
+ w.Parent = vF
+ local c = new("Camera")
+ c.CFrame = equip[4]
+ c.Parent = vF
+ vF.CurrentCamera = c
+ vF.Parent = f
+
+ local g = new("UIGradient")
+ g.Rotation = -45
+ g.Transparency = NumberSequence.new(0,1)
+ g.Parent = f
+ if equip[2] == 6 then
+ f.BackgroundColor3 = equipRarityColors[equip[2]]
+ else
+ f.BackgroundColor3 = equipRarityColors[equip[2]]
+ end
+
+ f.Parent = equipDisplay
+ end
+end
+
+local uv = v3(0,1,0)
+function lookAt(start,ende)
+ local fv = (ende-start).Unit
+ local rv = fv:Cross(uv)
+ local uv2 = rv:Cross(fv)
+ return CFrame.fromMatrix(start,rv,uv2)
+end
+
+function handleEquipClick(equipId,equipCategory,keepSpin)
+ local equip = equipModule[equipCategory][equipId]
+ local rarityColor = equipRarityColors[equip[2]]
+ local hexColor = format("%02X%02X%02X",rarityColor.R*255,rarityColor.G*255,rarityColor.B*255)
+ -- Change the information
+ sEquipName.Text = equip[1]
+ sEquipType.Text = '' .. equipRarityNames[equip[2]] .. ' ' .. equip[3]
+ sEquipDescription.Text = equip[5]
+ local traits = equip[6]
+ for i = 1, 4 do -- Show the traits
+ local traitId = traits[i*2 - 1]
+ if traitId then
+ local amount = traits[i*2]
+ local traitName = equipTraitNames[traitId]
+ -- Add the sign based on positivity or negativity
+ amount = (amount >= 0 and "+ " .. tSt(amount)) or "- " .. tSt(amount)
+ -- Add the % if the trait uses % as the measure
+ if sub(traitName,1,1) == "%" then
+ amount = amount .. "%"
+ traitName = sub(traitName,2,len(traitName))
+ end
+ sEquipTraits[i].Text = '' .. amount .. ' ' .. traitName
+ else
+ sEquipTraits[i].Text = ""
+ end
+ end
+ -- Replace the existing model
+ local model = sEquipFrame:FindFirstChildOfClass("Model")
+ if model then
+ model:Destroy()
+ end
+ model = equipFolder:FindFirstChild(equip[1])
+ if model then
+ model:Clone().Parent = sEquipFrame
+ end
+ -- Adjust spin values
+ if not keepSpin then
+ spinAngle = 0
+ end
+ spinY = equip[4].Position.Y
+ spinMagnitude = v3(equip[4].Position.X,0,equip[4].Position.Z).Magnitude
+end
+
+local mTInfo1 = TweenInfo.new(0.25,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
+local mTInfo2 = TweenInfo.new(0.25,Enum.EasingStyle.Quad,Enum.EasingDirection.In)
+function openMenu()
+ refreshEquips()
+ handleEquipClick(1,1,true)
+ menuInTransit = true
+
+ interfaceMenu.BackgroundTransparency = 1 --Set the stage
+ lineB.Position = uD2(1,0,0.998,0) --Push the stars and lines to the corner
+ lineB.Size = uD2(0,0,0.005,0)
+ lineR.Position = uD2(0.998,0,1,0)
+ lineR.Size = uD2(0.003,0,0,0)
+ starB.Position = uD2(0.994,0,0.989,0)
+ starR.Position = uD2(0.994,0,0.989,0)
+ for i, v in pairs(buttons) do
+ v.BackgroundTransparency = 1
+ v.NavButton.ImageTransparency = 1
+ end
+ selectName.TextTransparency = 1
+ selectName.TextStrokeTransparency = 1
+ selectDetails.TextTransparency = 1
+ selectDetails.TextStrokeTransparency = 1
+
+ pageName.TextTransparency = 1
+ pageName.TextStrokeTransparency = 1
+ nameDecoration.ImageTransparency = 1
+ nameDecoration.Frame.BackgroundTransparency = 1
+ nameDecoration.Frame.Image.ImageTransparency = 1
+
+ local children = pages[currentPage]:GetChildren()
+ for i, v in pairs(children) do
+ v.Visible = false
+ end
+
+ twS:Create(mainStar,mTInfo1,{Position = uD2(0.854,0,0.803,0), Size = uD2(0.042,0,0.075,0)}):Play()
+ wait(0.25)
+
+ interfaceMenu.Visible = true --The curtain rises
+
+ twS:Create(lineB,mTInfo1,{Position = uD2(0,0,0.998,0), Size = uD2(1,0,0.005,0)}):Play()
+ twS:Create(lineR,mTInfo1,{Position = uD2(0.998,0,0,0), Size = uD2(0.003,0,1,0)}):Play()
+ twS:Create(starB,mTInfo1,{Position = uD2(-0.006,0,0.989,0)}):Play()
+ twS:Create(starR,mTInfo1,{Position = uD2(0.994,0,-0.01,0)}):Play()
+ wait(0.25)
+ twS:Create(interfaceMenu,mTInfo1,{BackgroundTransparency = 0.5}):Play()
+ for i, v in pairs(buttons) do
+ twS:Create(v,mTInfo1,{BackgroundTransparency = 0.5}):Play()
+ twS:Create(v.NavButton,mTInfo1,{ImageTransparency = 0}):Play()
+ end
+ twS:Create(pageName,mTInfo1,{TextTransparency = 0, TextStrokeTransparency = 0.85}):Play()
+ twS:Create(nameDecoration,mTInfo1,{ImageTransparency = 0.5}):Play()
+ twS:Create(nameDecoration.Frame,mTInfo1,{BackgroundTransparency = 0.5}):Play()
+ twS:Create(nameDecoration.Frame.Image,mTInfo1,{ImageTransparency = 0.5}):Play()
+ for i, v in pairs(children) do --Show the page elements
+ v.Visible = true
+ wait()
+ end
+ menuIsOpen = true
+ menuInTransit = false
+ while menuIsOpen do -- MAJOR SPOT FOR CLEANUP
+ if currentPage == 2 then
+ local x, y = sin(rad(spinAngle)), cos(rad(spinAngle))
+ sEquipCam.CFrame = lookAt(v3(x*spinMagnitude,spinY,y*spinMagnitude),v3(0,0,0))
+ spinAngle += 2
+ wait()
+ end
+ local mPos = uIS:GetMouseLocation() - Vector2.new(0,26)
+ --print(mPos.Y)
+ local gObjects = plrGui:GetGuiObjectsAtPosition(mPos.X,mPos.Y)
+ local thisButton = ""
+ local sawWeaponFrame = false
+ for i, v in pairs(gObjects) do
+ --print(v.Name)
+ --print(v.Name == "NavButton")
+ --hoverLabel.Visible = false
+ if v.Name == "NavButton" then
+ thisButton = v.Parent
+ print(thisButton.Name)
+ elseif v.Name == "WeaponFrame" then
+ hoverLabel.Text = equipModule[currentEquipCategory][tn(v:FindFirstChildOfClass("ViewportFrame").Name)][1]
+ hoverLabel.Position = uD2(0,mPos.X+5,0,mPos.Y)
+ hoverLabel.Visible = true
+ sawWeaponFrame = true
+ end
+ end
+ if not sawWeaponFrame then
+ hoverLabel.Visible = false
+ end
+ if thisButton ~= buttonMouseIsOn then
+ -- Shrink formerly emphasized button
+ if buttonMouseIsOn ~= "" then
+ local size = buttonMouseIsOn.Size
+ local position = buttonMouseIsOn.Position
+ local sX, sY = size.X.Scale, size.Y.Scale
+ --local pX, pY = position.X.Scale+sX*0.1, position.Y.Scale+sY*0.1
+ twS:Create(buttonMouseIsOn,mTInfo1,{Position = uD2(-0.25 + tFind(buttons,buttonMouseIsOn)*0.25,0,0,0), Size = uD2(0.21,0,1,0)}):Play()
+ else
+ selectName.Text = buttonTags[tFind(buttons,thisButton)]
+ twS:Create(selectName,mTInfo1,{TextTransparency = 0, TextStrokeTransparency = 0.85}):Play()
+ end
+ buttonMouseIsOn = thisButton
+ -- Enlarge newly emphasized button
+ if buttonMouseIsOn ~= "" then
+ local size = buttonMouseIsOn.Size
+ local position = buttonMouseIsOn.Position
+ local sX, sY = size.X.Scale, size.Y.Scale
+ --local pX, pY = position.X.Scale-sX*0.125, position.Y.Scale-sY*0.125
+ twS:Create(buttonMouseIsOn,mTInfo1,{Position = uD2(-0.271 + tFind(buttons,buttonMouseIsOn)*0.25,0,0,0), Size = uD2(0.252,0,1.2,0)}):Play()
+ else
+ twS:Create(selectName,mTInfo1,{TextTransparency = 1, TextStrokeTransparency = 1}):Play()
+ end
+ end
+ wait()
+ end
+end
+
+function closeMenu()
+ menuInTransit = true
+ twS:Create(interfaceMenu,mTInfo2,{BackgroundTransparency = 1}):Play()
+ for i, v in pairs(buttons) do
+ twS:Create(v,mTInfo2,{BackgroundTransparency = 1}):Play()
+ twS:Create(v.NavButton,mTInfo2,{ImageTransparency = 1}):Play()
+ end
+ twS:Create(pageName,mTInfo2,{TextTransparency = 1, TextStrokeTransparency = 1}):Play()
+ twS:Create(nameDecoration,mTInfo2,{ImageTransparency = 1}):Play()
+ twS:Create(nameDecoration.Frame,mTInfo2,{BackgroundTransparency = 1}):Play()
+ twS:Create(nameDecoration.Frame.Image,mTInfo2,{ImageTransparency = 1}):Play()
+ local children = pages[currentPage]:GetChildren() --Hide the page elements
+ local when = clock() + 0.25
+ for i, v in pairs(children) do
+ v.Visible = false
+ wait()
+ end
+ wait(when-clock())
+ twS:Create(lineB,mTInfo2,{Position = uD2(1,0,0.998,0), Size = uD2(0,0,0.005,0)}):Play()
+ twS:Create(lineR,mTInfo2,{Position = uD2(0.998,0,1,0), Size = uD2(0.003,0,0,0)}):Play()
+ twS:Create(starB,mTInfo2,{Position = uD2(0.994,0,0.989,0)}):Play()
+ twS:Create(starR,mTInfo2,{Position = uD2(0.994,0,0.989,0)}):Play()
+ wait(0.25)
+ twS:Create(mainStar,mTInfo2,{Position = uD2(0,106,0,7), Size = uD2(0,26,0,26)}):Play()
+ wait(0.25)
+ interfaceMenu.Visible = false --The curtain falls
+ menuIsOpen = false
+ menuInTransit = false
+end
+
+function changeSortType()
+ currentSortOrder = (currentSortOrder == 3 and 1) or currentSortOrder + 1
+ displaySortType.Text = "Sort by: " .. sortOrders[currentSortOrder][1]
+ refreshEquips()
+end
+
+function changeSortDirection()
+ if sortReverse then
+ sortReverse = false
+ displaySortDirection.Rotation = 0
+ else
+ sortReverse = true
+ displaySortDirection.Rotation = 180
+ end
+ refreshEquips()
+end
+
+function changeEquipCategory(armor)
+ if armor and currentEquipCategory ~= 2 then
+ currentEquipCategory = 2
+ tabArmor.BackgroundTransparency = 0.7
+ tabArmor.TextColor3 = rgb(255,255,255)
+ tabWeapons.BackgroundTransparency = 0.6
+ tabWeapons.TextColor3 = rgb(171,171,171)
+ refreshEquips()
+ elseif not armor and currentEquipCategory ~= 1 then
+ currentEquipCategory = 1
+ tabWeapons.BackgroundTransparency = 0.7
+ tabWeapons.TextColor3 = rgb(255,255,255)
+ tabArmor.BackgroundTransparency = 0.6
+ tabArmor.TextColor3 = rgb(171,171,171)
+ refreshEquips()
+ end
+end
+
+function handleMenuClick()
+ local mPos = uIS:GetMouseLocation() - Vector2.new(0,26)
+ local gObjects = plrGui:GetGuiObjectsAtPosition(mPos.X,mPos.Y)
+ for i, v in pairs(gObjects) do
+ if v.Name == "WeaponFrame" then
+ handleEquipClick(tn(v:FindFirstChildOfClass("ViewportFrame").Name),1)
+ elseif v.Name == "ArmorFrame" then
+ handleEquipClick(tn(v:FindFirstChildOfClass("ViewportFrame").Name),2)
+ elseif v == displaySortType then
+ changeSortType()
+ elseif v == displaySortDirection then
+ changeSortDirection()
+ elseif v == tabWeapons then
+ changeEquipCategory()
+ elseif v == tabArmor then
+ changeEquipCategory(true)
+ end
+ end
+end
+
+
+--Camera stuff
+--camera.CameraType = camScriptable
+--uIS.MouseBehavior = uISLockedCenter
+
+--Dialog stuff that's here from the SG:RPG, planning to rewrite it ~~if~~ WHEN we add NPCs to the map
+
+--[[
+diaCache = {}
+function createDialog(f,tab)
+ if tab.Fire then
+ DialogEvent:FireServer(tab.Fire)
+ end
+ if tab.c ~= 0 then
+ f.SF.CanvasSize = UDim2.new(0,0,0,80+(tab.c-1)*90)
+ for i = 1, tab.c do
+ local c = f.SF["0"]:Clone()
+ c.TB.Text = tab[i].Choice
+ c.Visible = true
+ c.Name = i
+ c.Position = UDim2.new(0,0,0,90*(i-1))
+ c.Parent = f.SF
+ --Make the box show the cool gradient when the mouse enters it.
+ diaCache[#diaCache+1] = c.TB.MouseEnter:Connect(function()
+ for i = 1, 8 do
+ c.BackgroundTransparency = c.BackgroundTransparency/2
+ runService.Heartbeat:Wait()
+ end
+ c.BackgroundTransparency = 0
+ end)
+ --Make the box fade out when the mouse leaves.
+ diaCache[#diaCache+1] = c.TB.MouseLeave:Connect(function()
+ for i = 1, 8 do
+ c.BackgroundTransparency = (c.BackgroundTransparency+1)/2
+ runService.Heartbeat:Wait()
+ end
+ c.BackgroundTransparency = 1
+ end)
+ --Handle button click transitions.
+ diaCache[#diaCache+1] = c.TB.Activated:Connect(function()
+
+ f.Words.Text = tab[i].Resp
+ if string.len(tab[i].Resp) > 100 then
+ f.Words.TextScaled = true
+ else
+ f.Words.TextScaled = false
+ end
+
+ for i, v in pairs(f.SF:GetChildren()) do
+ if v.Name ~= "0" then
+ v:Destroy()
+ end
+ end
+ for i, v in pairs(diaCache) do
+ v:Disconnect()
+ end
+ diaCache = {}
+ createDialog(f,tab[i])
+ end)
+ end
+ else
+ wait(1+string.len(f.Words.Text)*0.03)
+ for i = 1, 20 do
+ pcall(function()
+ f.Position = f.Position:Lerp(UDim2.new(0,100,1,0),0.3)
+ runService.Heartbeat:Wait()
+ end)
+ end
+ pcall(function() f.Parent:Destroy() end)
+ isDialog = false
+ end
+end
+
+function Dialog(strin,model)
+ isDialog = true
+ local g = script.Dialog:Clone()
+ g.Parent = Plr.PlayerGui
+ local f = g.Frame
+
+ f.NPC.Text = strin.NPC
+ f.Words.Text = strin.FT
+ if string.len(strin.FT) > 100 then
+ f.Words.TextScaled = true
+ end
+
+ createDialog(f,strin)
+
+ local c = model:Clone()
+ c.Parent = f.VF
+ local cam = Instance.new("Camera",f.VF)
+ f.VF.CurrentCamera = cam
+ cam.CFrame = c.ClickBox.CFrame*strin.C
+
+ g.Frame.Position = UDim2.new(0,100,1,0)
+ g.Enabled = true
+ for i = 1, 20 do
+ f.Position =f.Position:Lerp(UDim2.new(0,100,0.6,0),0.3)
+ runService.Heartbeat:Wait()
+ end
+ g.Frame.Position = UDim2.new(0,100,0.6,0)
+end
+]]
+local shouldStartPBLLoop = true
+local connectionTable = {}
+
+local ngh = script.sgAnimate
+function giveScript(plr,mode)
+ if not script:FindFirstChild(plr.Name) then
+ local c = ngh:Clone()
+ c.Name = plr.Name
+ c.Parent = script
+ c.Disabled = false
+ if mode then
+ local uId = plr.UserId
+ local thisOne = rand(1,99999)
+ while connectionTable[thisOne] do
+ thisOne = rand(1,99999)
+ end
+ connectionTable[thisOne] = ModeEvent.Event:Connect(function(typ,aUId)
+ if typ == "Request" and aUId == uId then
+ connectionTable[thisOne]:Disconnect()
+ ModeEvent:Fire("Reply",uId,mode)
+ end
+ end)
+ end
+ end
+end
+
+local hitParams = RaycastParams.new()
+hitParams.FilterDescendantsInstances = {efFolder,Plr.Character}
+hitParams.FilterType = Enum.RaycastFilterType.Blacklist
+local function mouse()
+ hitParams.FilterDescendantsInstances = {efFolder,Plr.Character}
+ local mouseLocation = uIS:GetMouseLocation()
+ local unitRay = Cam:ViewportPointToRay(mouseLocation.X,mouseLocation.Y)
+ local cast = workspace:Raycast(unitRay.Origin,unitRay.Direction*1000,hitParams)
+ if cast then
+ return cast.Position,cast.Normal,cast.Instance
+ else
+ return unitRay.Origin+unitRay.Direction*1000,v3(0,0,0), nil
+
+ end
+end
+
+Output.OnClientEvent:Connect(function(event,arg1,arg2,arg3,arg4,arg5,arg6)
+ if event == "GiveScript" then
+ giveScript(arg1,arg2)
+ elseif event == "ModeChange" and arg1 == Plr.UserId then
+ Music.SoundId = rid .. arg2.music[1]
+ changeGuiMode(arg2.name,arg2.main,arg2.sec,arg2.font,arg2.music[2],arg2.music[3])
+ if arg2.sendpbl and shouldStartPBLLoop then
+ shouldStartPBLLoop = false
+ SendPlaybackLoudness = true
+ while SendPlaybackLoudness do
+ wait(0.1)
+ Input:FireServer("PBL",Music.PlaybackLoudness)
+ end
+ shouldStartPBLLoop = true --This makes it so that multiple loops are not created if a player switches from one PBL mode to another
+ else
+ SendPlaybackLoudness = false
+ end
+ --elseif event == "Shake" then
+ --CamShake(arg1,arg2)
+ elseif event == "Notify" then
+ Notify(arg1)
+ elseif event == "Cooldown" then
+ handleCooldown(arg1,arg2,arg3,arg4,arg5,arg6)
+ elseif event == "MovesExist" then
+ movesExist = arg1
+ updateCooldownGui(arg2,arg3,arg4,arg5)
+ elseif event == "SideColors" then
+ updateDiamond(arg1)
+ elseif event == "EnemyInit" then
+ warn("Got enemy init message: " .. arg1)
+ enemyModules[arg1]["Init"](arg2)
+ elseif event == "EnemyClientEvent" then
+ --print("Got enemy client event of " .. arg1 .. " " .. arg2)
+ enemyModules[arg1][arg2](arg3,arg4,arg5)
+ elseif event == "MouseRequest" or (event == "ClientEvent" and arg2 == "BeamUpdate" and arg1 == Plr.UserId) then
+ --print("Client got mouserequest, updating")
+ Input:FireServer("Input",nil,mouse())
+ end
+end)
+
+
+
+--Inputs
+function handleModeInput(key)
+ storedModeKey = storedModeKey .. key
+ if len(storedModeKey) >= 2 then
+ --print("Firing server with " .. storedModeKey)
+ Input:FireServer("Input",storedModeKey,mouse())
+ storedModeKey = ""
+ interfaceDiamond.Visible = false
+ else
+ interfaceDiamond.Visible = true
+ for i = 1, 4 do
+ local thisBox = interfaceDiamond["Box" .. tSt(i)].Inside
+ if i == tFind(modeKeys,key) then
+ thisBox.Key.TextTransparency = 0
+ else
+ thisBox.Key.TextTransparency = 0.75
+ end
+ end
+ resizeBoxes(tFind(modeKeys,key),0.6,0.4)
+ end
+end
+uIS.InputBegan:Connect(function(k,object)
+ local keyCode = k.KeyCode
+ if --[[not object and]] k.UserInputType == Enum.UserInputType.MouseButton1 and not menuInTransit then
+ if menuIsOpen then
+ handleMenuClick()
+ else
+ Input:FireServer("Input","click",mouse())
+ end
+ elseif not object and keyCode and not menuInTransit then
+ keyCode = sub(tSt(keyCode),14)
+ --print("Got key " .. keyCode)
+ if keyCode == "G" then
+ if menuIsOpen then
+ closeMenu()
+ else
+ openMenu()
+ end
+ elseif tFind(modeKeys,keyCode) and not menuIsOpen then
+ --print("Got mode key")
+ handleModeInput(keyCode)
+ elseif tFind(abilityKeys,keyCode) or tFind(otherModeKeys,keyCode) and not menuIsOpen then
+ Input:FireServer("Input",keyCode,mouse())
+ end
+ end
+end)
+
+
+wait()
+--[[
+for i, v in pairs (plrs:GetChildren()) do
+ giveScript(v.Name)
+end
+
+plrs.PlayerAdded:Connect(function(plr)
+ giveScript(plr.Name)
+end)
+]]
+
+--hey
+Input:FireServer("Message",Plr.Name.."'s local script has loaded.")
+
+--More legacy stuff from the SG:RPG
+--[[
+Plr.CharacterAdded:Connect(function() --Handle the health bar (it has to get the humanoid every time the character respawns
+ isDialog = false
+ wait(0.5)
+ hum = Plr.Character.Humanoid
+ G.Box.HP.L.Text = tostring(hum.MaxHealth) .. "/" .. tostring(hum.MaxHealth)
+ pcall(function() conch:Disconnect() end)
+ conch = hum.HealthChanged:Connect(function()
+ print(tostring(math.floor(hum.Health)))
+ G.Box.HP.L.Text = tostring(math.floor(hum.Health)) .. "/" .. tostring(hum.MaxHealth)
+ repeat
+ G.Box.HP.B.Size = G.Box.HP.B.Size:Lerp(UDim2.new(hum.Health/hum.MaxHealth,0,0,13),0.1)
+ runService.Heartbeat:Wait()
+ until G.Box.HP.B.Size == UDim2.new(hum.Health/hum.MaxHealth,0,0,13) or not hum
+ end)
+end)
+
+repeat ---Get the gosh darn humanoid already
+ pcall(function() hum = Plr.Character.Humanoid end)
+ wait()
+until hum
+
+if not conch then --The script's not fast enough to detect the initial spawn so I'm just leaving this here
+ conch = hum.HealthChanged:Connect(function()
+ print(tostring(math.floor(hum.Health)))
+ G.Box.HP.L.Text = tostring(math.floor(hum.Health)) .. "/" .. tostring(hum.MaxHealth)
+ repeat
+ G.Box.HP.B.Size = G.Box.HP.B.Size:Lerp(UDim2.new(hum.Health/hum.MaxHealth,0,0,13),0.1)
+ runService.Heartbeat:Wait()
+ until G.Box.HP.B.Size == UDim2.new(hum.Health/hum.MaxHealth,0,0,13) or not hum
+ end)
+end
+]]
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..210a10f
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,3133 @@
+{
+ "name": "help",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "help",
+ "version": "1.0.0",
+ "license": "ISC",
+ "devDependencies": {
+ "@rbxts/compiler-types": "^1.2.3-types.0",
+ "@rbxts/types": "^1.0.523",
+ "@typescript-eslint/eslint-plugin": "^4.30.0",
+ "@typescript-eslint/parser": "^4.30.0",
+ "eslint": "^7.32.0",
+ "eslint-config-prettier": "^8.3.0",
+ "eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-roblox-ts": "^0.0.31",
+ "prettier": "^2.3.2",
+ "typescript": "^4.4.2"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
+ "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz",
+ "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
+ "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.1.1",
+ "espree": "^7.3.0",
+ "globals": "^13.9.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^3.13.1",
+ "minimatch": "^3.0.4",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
+ "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+ "dev": true,
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^1.2.0",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
+ "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
+ "dev": true
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@rbxts/compiler-types": {
+ "version": "1.2.3-types.0",
+ "resolved": "https://registry.npmjs.org/@rbxts/compiler-types/-/compiler-types-1.2.3-types.0.tgz",
+ "integrity": "sha512-8dpU2CJjlinesUdWHdzhtt4oif9VkWgZzPQ61BIN+244CO7EfRBZ4tCEdNrmFjKiba2LZWOsDaMKn6Ui40tpTQ==",
+ "dev": true
+ },
+ "node_modules/@rbxts/types": {
+ "version": "1.0.523",
+ "resolved": "https://registry.npmjs.org/@rbxts/types/-/types-1.0.523.tgz",
+ "integrity": "sha512-vBHFgHxZajuLe7vvKgFv6DwJROdi8olkJrr294vvA4VR6OujKvEVxpAtpKcQTF9mT10Ff2IAUs50RIU21untDw==",
+ "dev": true
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
+ "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "14.17.14",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.14.tgz",
+ "integrity": "sha512-rsAj2u8Xkqfc332iXV12SqIsjVi07H479bOP4q94NAcjzmAvapumEhuVIt53koEf7JFrpjgNKjBga5Pnn/GL8A==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.30.0.tgz",
+ "integrity": "sha512-NgAnqk55RQ/SD+tZFD9aPwNSeHmDHHe5rtUyhIq0ZeCWZEvo4DK9rYz7v9HDuQZFvn320Ot+AikaCKMFKLlD0g==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/experimental-utils": "4.30.0",
+ "@typescript-eslint/scope-manager": "4.30.0",
+ "debug": "^4.3.1",
+ "functional-red-black-tree": "^1.0.1",
+ "regexpp": "^3.1.0",
+ "semver": "^7.3.5",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^4.0.0",
+ "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/experimental-utils": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.30.0.tgz",
+ "integrity": "sha512-K8RNIX9GnBsv5v4TjtwkKtqMSzYpjqAQg/oSphtxf3xxdt6T0owqnpojztjjTcatSteH3hLj3t/kklKx87NPqw==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.7",
+ "@typescript-eslint/scope-manager": "4.30.0",
+ "@typescript-eslint/types": "4.30.0",
+ "@typescript-eslint/typescript-estree": "4.30.0",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^3.0.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "*"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.30.0.tgz",
+ "integrity": "sha512-HJ0XuluSZSxeboLU7Q2VQ6eLlCwXPBOGnA7CqgBnz2Db3JRQYyBDJgQnop6TZ+rsbSx5gEdWhw4rE4mDa1FnZg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "4.30.0",
+ "@typescript-eslint/types": "4.30.0",
+ "@typescript-eslint/typescript-estree": "4.30.0",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.30.0.tgz",
+ "integrity": "sha512-VJ/jAXovxNh7rIXCQbYhkyV2Y3Ac/0cVHP/FruTJSAUUm4Oacmn/nkN5zfWmWFEanN4ggP0vJSHOeajtHq3f8A==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "4.30.0",
+ "@typescript-eslint/visitor-keys": "4.30.0"
+ },
+ "engines": {
+ "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.30.0.tgz",
+ "integrity": "sha512-YKldqbNU9K4WpTNwBqtAerQKLLW/X2A/j4yw92e3ZJYLx+BpKLeheyzoPfzIXHfM8BXfoleTdiYwpsvVPvHrDw==",
+ "dev": true,
+ "engines": {
+ "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.30.0.tgz",
+ "integrity": "sha512-6WN7UFYvykr/U0Qgy4kz48iGPWILvYL34xXJxvDQeiRE018B7POspNRVtAZscWntEPZpFCx4hcz/XBT+erenfg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "4.30.0",
+ "@typescript-eslint/visitor-keys": "4.30.0",
+ "debug": "^4.3.1",
+ "globby": "^11.0.3",
+ "is-glob": "^4.0.1",
+ "semver": "^7.3.5",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.30.0.tgz",
+ "integrity": "sha512-pNaaxDt/Ol/+JZwzP7MqWc8PJQTUhZwoee/PVlQ+iYoYhagccvoHnC9e4l+C/krQYYkENxznhVSDwClIbZVxRw==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "4.30.0",
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/astral-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/enquirer": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-colors": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "7.32.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
+ "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "7.12.11",
+ "@eslint/eslintrc": "^0.4.3",
+ "@humanwhocodes/config-array": "^0.5.0",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "enquirer": "^2.3.5",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^2.1.0",
+ "eslint-visitor-keys": "^2.0.0",
+ "espree": "^7.3.1",
+ "esquery": "^1.4.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.1.2",
+ "globals": "^13.6.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.0.4",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "progress": "^2.0.0",
+ "regexpp": "^3.1.0",
+ "semver": "^7.2.1",
+ "strip-ansi": "^6.0.0",
+ "strip-json-comments": "^3.1.0",
+ "table": "^6.0.9",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz",
+ "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==",
+ "dev": true,
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz",
+ "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==",
+ "dev": true,
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.28.0",
+ "prettier": ">=2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-roblox-ts": {
+ "version": "0.0.31",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-roblox-ts/-/eslint-plugin-roblox-ts-0.0.31.tgz",
+ "integrity": "sha512-/n/yl3q1ZLU/dQSfKVX9BPydBQr863NMWLH+Oge2B2lTs31+sxGJfm0PQlPqSaS5seK219Qj4R8JRGX1sJLjCA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "^14.14.32",
+ "@typescript-eslint/experimental-utils": "^4.16.1",
+ "typescript": "^4.2.3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-utils": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+ "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=5"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/espree": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
+ "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^7.4.0",
+ "acorn-jsx": "^5.3.1",
+ "eslint-visitor-keys": "^1.3.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esquery/node_modules/estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "node_modules/fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
+ "node_modules/fast-glob": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
+ "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "node_modules/fastq": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz",
+ "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+ "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "dev": true,
+ "dependencies": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz",
+ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
+ "dev": true
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "node_modules/functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "node_modules/glob": {
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.11.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz",
+ "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.0.4",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz",
+ "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==",
+ "dev": true,
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.1.1",
+ "ignore": "^5.1.4",
+ "merge2": "^1.3.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby/node_modules/ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+ "dev": true
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "node_modules/lodash.truncate": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+ "dev": true
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+ "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+ "dev": true,
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
+ "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/regexpp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "node_modules/string-width": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+ "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/table": {
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz",
+ "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^8.0.1",
+ "lodash.clonedeep": "^4.5.0",
+ "lodash.truncate": "^4.4.2",
+ "slice-ansi": "^4.0.0",
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/table/node_modules/ajv": {
+ "version": "8.6.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
+ "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/table/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ },
+ "node_modules/tsutils": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+ "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^1.8.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "peerDependencies": {
+ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
+ "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/v8-compile-cache": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+ "dev": true
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
+ },
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
+ "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.14.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz",
+ "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==",
+ "dev": true
+ },
+ "@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "@eslint/eslintrc": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
+ "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.12.4",
+ "debug": "^4.1.1",
+ "espree": "^7.3.0",
+ "globals": "^13.9.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^3.13.1",
+ "minimatch": "^3.0.4",
+ "strip-json-comments": "^3.1.1"
+ }
+ },
+ "@humanwhocodes/config-array": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
+ "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+ "dev": true,
+ "requires": {
+ "@humanwhocodes/object-schema": "^1.2.0",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "@humanwhocodes/object-schema": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
+ "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
+ "dev": true
+ },
+ "@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ }
+ },
+ "@rbxts/compiler-types": {
+ "version": "1.2.3-types.0",
+ "resolved": "https://registry.npmjs.org/@rbxts/compiler-types/-/compiler-types-1.2.3-types.0.tgz",
+ "integrity": "sha512-8dpU2CJjlinesUdWHdzhtt4oif9VkWgZzPQ61BIN+244CO7EfRBZ4tCEdNrmFjKiba2LZWOsDaMKn6Ui40tpTQ==",
+ "dev": true
+ },
+ "@rbxts/types": {
+ "version": "1.0.523",
+ "resolved": "https://registry.npmjs.org/@rbxts/types/-/types-1.0.523.tgz",
+ "integrity": "sha512-vBHFgHxZajuLe7vvKgFv6DwJROdi8olkJrr294vvA4VR6OujKvEVxpAtpKcQTF9mT10Ff2IAUs50RIU21untDw==",
+ "dev": true
+ },
+ "@types/json-schema": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
+ "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "14.17.14",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.14.tgz",
+ "integrity": "sha512-rsAj2u8Xkqfc332iXV12SqIsjVi07H479bOP4q94NAcjzmAvapumEhuVIt53koEf7JFrpjgNKjBga5Pnn/GL8A==",
+ "dev": true
+ },
+ "@typescript-eslint/eslint-plugin": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.30.0.tgz",
+ "integrity": "sha512-NgAnqk55RQ/SD+tZFD9aPwNSeHmDHHe5rtUyhIq0ZeCWZEvo4DK9rYz7v9HDuQZFvn320Ot+AikaCKMFKLlD0g==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/experimental-utils": "4.30.0",
+ "@typescript-eslint/scope-manager": "4.30.0",
+ "debug": "^4.3.1",
+ "functional-red-black-tree": "^1.0.1",
+ "regexpp": "^3.1.0",
+ "semver": "^7.3.5",
+ "tsutils": "^3.21.0"
+ }
+ },
+ "@typescript-eslint/experimental-utils": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.30.0.tgz",
+ "integrity": "sha512-K8RNIX9GnBsv5v4TjtwkKtqMSzYpjqAQg/oSphtxf3xxdt6T0owqnpojztjjTcatSteH3hLj3t/kklKx87NPqw==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.7",
+ "@typescript-eslint/scope-manager": "4.30.0",
+ "@typescript-eslint/types": "4.30.0",
+ "@typescript-eslint/typescript-estree": "4.30.0",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^3.0.0"
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.30.0.tgz",
+ "integrity": "sha512-HJ0XuluSZSxeboLU7Q2VQ6eLlCwXPBOGnA7CqgBnz2Db3JRQYyBDJgQnop6TZ+rsbSx5gEdWhw4rE4mDa1FnZg==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/scope-manager": "4.30.0",
+ "@typescript-eslint/types": "4.30.0",
+ "@typescript-eslint/typescript-estree": "4.30.0",
+ "debug": "^4.3.1"
+ }
+ },
+ "@typescript-eslint/scope-manager": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.30.0.tgz",
+ "integrity": "sha512-VJ/jAXovxNh7rIXCQbYhkyV2Y3Ac/0cVHP/FruTJSAUUm4Oacmn/nkN5zfWmWFEanN4ggP0vJSHOeajtHq3f8A==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.30.0",
+ "@typescript-eslint/visitor-keys": "4.30.0"
+ }
+ },
+ "@typescript-eslint/types": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.30.0.tgz",
+ "integrity": "sha512-YKldqbNU9K4WpTNwBqtAerQKLLW/X2A/j4yw92e3ZJYLx+BpKLeheyzoPfzIXHfM8BXfoleTdiYwpsvVPvHrDw==",
+ "dev": true
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.30.0.tgz",
+ "integrity": "sha512-6WN7UFYvykr/U0Qgy4kz48iGPWILvYL34xXJxvDQeiRE018B7POspNRVtAZscWntEPZpFCx4hcz/XBT+erenfg==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.30.0",
+ "@typescript-eslint/visitor-keys": "4.30.0",
+ "debug": "^4.3.1",
+ "globby": "^11.0.3",
+ "is-glob": "^4.0.1",
+ "semver": "^7.3.5",
+ "tsutils": "^3.21.0"
+ }
+ },
+ "@typescript-eslint/visitor-keys": {
+ "version": "4.30.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.30.0.tgz",
+ "integrity": "sha512-pNaaxDt/Ol/+JZwzP7MqWc8PJQTUhZwoee/PVlQ+iYoYhagccvoHnC9e4l+C/krQYYkENxznhVSDwClIbZVxRw==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "4.30.0",
+ "eslint-visitor-keys": "^2.0.0"
+ }
+ },
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "requires": {}
+ },
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ },
+ "astral-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true
+ },
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "requires": {
+ "path-type": "^4.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "enquirer": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^4.1.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true
+ },
+ "eslint": {
+ "version": "7.32.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
+ "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "7.12.11",
+ "@eslint/eslintrc": "^0.4.3",
+ "@humanwhocodes/config-array": "^0.5.0",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "enquirer": "^2.3.5",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^2.1.0",
+ "eslint-visitor-keys": "^2.0.0",
+ "espree": "^7.3.1",
+ "esquery": "^1.4.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.1.2",
+ "globals": "^13.6.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.0.4",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "progress": "^2.0.0",
+ "regexpp": "^3.1.0",
+ "semver": "^7.2.1",
+ "strip-ansi": "^6.0.0",
+ "strip-json-comments": "^3.1.0",
+ "table": "^6.0.9",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "dependencies": {
+ "eslint-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "dependencies": {
+ "eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "eslint-config-prettier": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz",
+ "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==",
+ "dev": true,
+ "requires": {}
+ },
+ "eslint-plugin-prettier": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz",
+ "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==",
+ "dev": true,
+ "requires": {
+ "prettier-linter-helpers": "^1.0.0"
+ }
+ },
+ "eslint-plugin-roblox-ts": {
+ "version": "0.0.31",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-roblox-ts/-/eslint-plugin-roblox-ts-0.0.31.tgz",
+ "integrity": "sha512-/n/yl3q1ZLU/dQSfKVX9BPydBQr863NMWLH+Oge2B2lTs31+sxGJfm0PQlPqSaS5seK219Qj4R8JRGX1sJLjCA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "^14.14.32",
+ "@typescript-eslint/experimental-utils": "^4.16.1",
+ "typescript": "^4.2.3"
+ }
+ },
+ "eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+ "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^2.0.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true
+ },
+ "espree": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
+ "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.4.0",
+ "acorn-jsx": "^5.3.1",
+ "eslint-visitor-keys": "^1.3.0"
+ },
+ "dependencies": {
+ "eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true
+ }
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.1.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.2.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true
+ },
+ "fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
+ "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ }
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "fastq": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz",
+ "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^3.0.4"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "flat-cache": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+ "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "dev": true,
+ "requires": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ }
+ },
+ "flatted": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz",
+ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
+ "dev": true
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "globals": {
+ "version": "13.11.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz",
+ "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.20.2"
+ }
+ },
+ "globby": {
+ "version": "11.0.4",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz",
+ "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==",
+ "dev": true,
+ "requires": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.1.1",
+ "ignore": "^5.1.4",
+ "merge2": "^1.3.0",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true
+ }
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ }
+ },
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+ "dev": true
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "lodash.truncate": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "optionator": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+ "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+ "dev": true,
+ "requires": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.3"
+ }
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true
+ },
+ "prettier": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
+ "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
+ "dev": true
+ },
+ "prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "requires": {
+ "fast-diff": "^1.1.2"
+ }
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
+ },
+ "regexpp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+ "dev": true
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "requires": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+ "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "table": {
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz",
+ "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==",
+ "dev": true,
+ "requires": {
+ "ajv": "^8.0.1",
+ "lodash.clonedeep": "^4.5.0",
+ "lodash.truncate": "^4.4.2",
+ "slice-ansi": "^4.0.0",
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "8.6.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
+ "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ }
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ },
+ "tsutils": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+ "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ },
+ "type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "^1.2.1"
+ }
+ },
+ "type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true
+ },
+ "typescript": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz",
+ "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==",
+ "dev": true
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "v8-compile-cache": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..806b9aa
--- /dev/null
+++ b/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "help",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "build": "rbxtsc",
+ "watch": "rbxtsc -w"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "devDependencies": {
+ "@rbxts/compiler-types": "^1.2.3-types.0",
+ "@rbxts/types": "^1.0.523",
+ "@typescript-eslint/eslint-plugin": "^4.30.0",
+ "@typescript-eslint/parser": "^4.30.0",
+ "eslint": "^7.32.0",
+ "eslint-config-prettier": "^8.3.0",
+ "eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-roblox-ts": "^0.0.31",
+ "prettier": "^2.3.2",
+ "typescript": "^4.4.2"
+ }
+}
diff --git a/src/client/init.client.ts b/src/client/init.client.ts
new file mode 100644
index 0000000..955f346
--- /dev/null
+++ b/src/client/init.client.ts
@@ -0,0 +1,1129 @@
+// Setup and Variables
+
+// Universal variables
+import { makeHello } from "shared/module";
+const plrs = game.GetService("Players");
+const ws = game.GetService("Workspace");
+const tween = game.GetService("TweenService");
+const runService = game.GetService("RunService");
+const storage = game.GetService("ReplicatedStorage");
+// Aliases
+const uD2 = UDim2;
+const v3 = Vector3;
+const cF = CFrame;
+const inst = Instance;
+const tN = tonumber;
+const tS = tostring;
+const wait = task.wait;
+const clock = os.clock;
+const floor = math.floor;
+const ceil = math.ceil;
+const abs = math.abs;
+const cos = math.cos;
+const sin = math.sin;
+const rad = math.rad;
+const rand = math.random;
+const clamp = math.clamp;
+const sub = string.sub;
+// Constructors
+const rgb = Color3.fromRGB;
+const hsv = Color3.fromHSV;
+const xyz = CFrame.fromEulerAnglesXYZ;
+const wrap = coroutine.wrap;
+
+const zF = new cF(0, 0, 0);
+//End of universal variables
+
+const uIS = game.GetService("UserInputService");
+
+const rid = "rbxassetid://";
+
+//const sequence = NumberSequence.new;
+const upper = string.upper;
+// const len = string.len;
+const Plr = plrs.LocalPlayer;
+const Cam = game.Workspace.CurrentCamera;
+const efFolder = ws.Effects;
+
+const remotes = storage.Remotes;
+const input = remotes.Input;
+const output = remotes.Output;
+//const ModeEvent = script.ModeEvent;
+const camera = ws.CurrentCamera;
+const camCustom = Enum.CameraType.Custom;
+const camScriptable = Enum.CameraType.Scriptable;
+
+//const DialogEvent = Remotes.Dialog;
+//const isDialog = false;
+//const DialogList = require(script.Parent.Dialog)
+//const enemyCEs = require(script.EnemyClientEvents)
+/*
+const eLM = storage.EnemyLocalModules.GetChildren();
+var enemyModules = {};
+warn("Amount of enemy modules: " + tSt(eLM.length));
+for i, v in pairs(eLM:GetChildren()) do
+ enemyModules[v.Name] = require(v)
+ warn("Required " .. v.Name)
+end
+*/
+
+//const v3Lerp = Vector3.new().Lerp;
+
+function aRa(v: number) {
+ //NOT A JOJO REFERENCE SHUT UP
+ return (rand(-100, 100) / 100) * v;
+}
+function getDist(one: Vector3, two: Vector3) {
+ return one.add(two).Magnitude;
+}
+function floorToBase(number: number, base: number) {
+ return floor(number * base) / base;
+}
+//music
+const Music = new inst("Sound");
+Music.Name = "Music";
+Music.Looped = true;
+Music.SoundId = rid + "564466195";
+Music.Parent = ws;
+Music.Play();
+const SendPlaybackLoudness = false;
+//Music.PlaybackSpeed = 1
+const coolUpdateCycle = 0;
+
+function tFind(tab: string[], element: string) {
+ return tab.findIndex((thisElement) => thisElement === element) !== -1;
+}
+
+function omniWait(waitTime: number) {
+ let sum = 0;
+ while (sum < waitTime) {
+ const [t, step] = runService.Stepped.Wait();
+ sum += step;
+ }
+}
+
+const plrGui = Plr.WaitForChild("PlayerGui");
+////////////////////////
+// Decorative Set GUI //
+////////////////////////
+/*
+var Gui = nil;
+var Title = nil;
+var TitleShadow = nil;
+var Vis = nil;
+var VisTable = {};
+var MusicLabel = nil;
+function makeGui(whichGui)
+ Gui = script[whichGui + "Gui"].Clone()
+ Gui.Parent = plrGui
+ Title = Gui.Title
+ TitleShadow = Gui:FindFirstChild("TitleShadow")
+ Vis = Gui.Visualizer
+ local absSize = Vis.AbsoluteSize
+ Vis.Position = Vis.Position + uD2(0,absSize.Y-absSize.X,0,0)
+ Vis.Size = Vis.Size + uD2(0,absSize.Y-absSize.X,0,0)
+ VisTable = {}
+ MusicLabel = Gui.Top.Music
+ for i = 1, #Vis:GetChildren() do
+ local bar = Vis["Bar" .. tSt(i)]
+ tInsert(VisTable,{bar,bar.Position,bar.Size})
+ end
+end
+makeGui("Star")
+
+
+function changeGuiMode(name,color1,color2,font,artist,track)
+ Title.Text = upper(name)
+ Title.Font = font
+ Title.TextColor3 = color1
+ Title.TextStrokeColor3 = color2
+ MusicLabel.Text = artist .. " - " .. track
+ if TitleShadow then
+ TitleShadow.Text = upper(name)
+ TitleShadow.Font = font
+ end
+ for i, v in pairs(VisTable) do
+ v[1].BackgroundColor3 = color1
+ end
+ //adapt to aspect ratio
+ local absSize = Vis.AbsoluteSize
+ Vis.Position = Vis.Position + uD2(0,absSize.Y-absSize.X,0,0)
+ Vis.Size = Vis.Size + uD2(0,absSize.Y-absSize.X,0,0)
+end
+*/
+//Miscellaneous
+/*
+function CamShake(ins,reps) {
+ var Hum = Plr.Character.Humanoid
+ for (let i = 1; i < reps; i++) {
+ local mult = 1-i/reps
+ local goal = v3(aRa(ins)*mult,aRa(ins)*mult,aRa(ins)*mult)
+ for j = 1,2 do
+ local mult = 1-i/reps
+ Hum.CameraOffset = v3Lerp(Hum.CameraOffset,goal,0.5)
+ omniWait(0.016)
+ end
+ }
+ local goal = v3(0,0,0)
+ for j = 1,2 do
+ Hum.CameraOffset = v3Lerp(Hum.CameraOffset,goal,0.5)
+ omniWait(0.016)
+ end
+ Hum.CameraOffset = goal
+}
+
+var Notifier = plrGui.WaitForChild("Help")
+
+local tim = nil
+local NotifyTinfo1 = TweenInfo.new(0.25,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
+local NotifyTinfo2 = TweenInfo.new(0.5,Enum.EasingStyle.Linear)
+local goal1 = {TextTransparency = 0}
+local goal2 = {TextTransparency = 1}
+function Notify(message)
+ tim = os.time()
+ local tim2 = tim
+ Notifier.Label.Text = message
+ if not Notifier.Enabled then
+ Notifier.Enabled = true
+ tween:Create(Notifier.Label,NotifyTinfo1,goal1):Play()
+ end
+ wait(2)
+ if tim == tim2 then
+ tween:Create(Notifier.Label,NotifyTinfo2,goal2):Play()
+ wait(1)
+ Notifier.Enabled = false
+ end
+end
+*/
+const modeKeys = ["Q", "E", "R", "F"];
+const abilityKeys = ["Z", "X", "C", "V"];
+const otherModeKeys = ["B", "N", "M", "1", "2", "3", "4"];
+
+////////////////////
+// Main interface //
+////////////////////
+/*
+local mainInterface = plrGui:WaitForChild("MainInterface")
+local interfaceCooldowns = mainInterface.Cooldowns
+local interfaceDiamond = mainInterface.Diamond
+local interfaceMenu = mainInterface.Menu
+interfaceDiamond.Visible = false
+interfaceMenu.Visible = false
+*/
+////////////////////
+// Cooldown stuff //
+////////////////////
+/*
+local coolDown = {}
+local movesExist = {Z = nil,X = nil,C = nil,V = nil}
+
+function getCoolTime(tab)
+ if not tab then
+ return 0
+ end
+ local t = tab[2]-(clock()-tab[1])
+ return t > 0 and floorToBase(t,10) or 0
+end
+
+local currentCoolCycle = 0
+
+function updateCooldownGui(Set,Side,Mode,Color)
+ //Stop any other cooldown loops currently occurring
+ local thisCycle = clock()
+ currentCoolCycle = thisCycle
+ for i, inp in pairs(abilityKeys) do
+ local part = interfaceCooldowns[inp]
+ if movesExist[inp] then
+ part.Visible = true
+ if Color then
+ part.Star1.BackgroundColor3 = Color
+ part.Star1.Star12.BackgroundColor3 = Color
+ end
+
+ //Show the counter
+ part.Gradient.Transparency = sequence(1,0.7)
+ part.WhiteBarBottom.Visible = true
+ part.WhiteBarTop.Visible = true
+ part.FramePart.Visible = true
+ part.WhiteBarDiagonal.Visible = true
+ part.Time.Visible = true
+
+ //Get potential cooldowns
+ local cool = nil
+ local coolTime = 0
+
+ local cools = {coolDown.Main,coolDown[inp],coolDown[Set .. Side .. Mode .. inp]}
+
+ //Determine the greatest cooldown
+ for i, v in pairs(cools) do
+ local t = getCoolTime(v)
+ if t > coolTime then
+ cool = v
+ coolTime = t
+ end
+ end
+
+ coroutine.wrap(function() // Cool down
+ while currentCoolCycle == thisCycle and coolTime > 0 do //Update the cooltime and GUI while it exists
+ coolTime = getCoolTime(cool)
+ part.Time.Text = coolTime
+ wait(0.1)
+ end
+
+ if coolTime <= 0 then //Remove the counter (only) once done cooling
+ part.Gradient.Transparency = sequence(1)
+ part.WhiteBarBottom.Visible = false
+ part.WhiteBarTop.Visible = false
+ part.FramePart.Visible = false
+ part.WhiteBarDiagonal.Visible = false
+ part.Time.Visible = false
+ end
+ end)()
+ else
+ part.Visible = false
+ end
+ end
+end
+
+
+function handleCooldown(cool,inp,Set,Side,Mode)
+ local now = floorToBase(clock(),10)
+ coolDown.Main = {now,cool}
+ coolDown[inp] = {now,cool*3}
+ coolDown[Set .. Side .. Mode .. inp] = {now,cool*9}
+ updateCooldownGui(Set,Side,Mode)
+end
+*/
+
+//////////////////////////////////
+// Mode switching diamond stuff //
+//////////////////////////////////
+let storedModeKey = "";
+/*
+function resizeDiamond()
+ local diamondAbs = interfaceDiamond.AbsoluteSize
+ local sizeDiff = diamondAbs.Y-diamondAbs.X
+ interfaceDiamond.Size = uD2(0.281,sizeDiff,0.5,0)
+ interfaceDiamond.Position = uD2(0.359,sizeDiff/(-2),0.25,0)
+ local strokeSize = ceil(diamondAbs.Y*0.00926)
+ for i = 1, 4 do
+ interfaceDiamond["Box" .. tSt(i)].Inside.UIStroke.Thickness = strokeSize
+ end
+end
+resizeDiamond()
+
+function updateDiamond(data)
+ for j = 1, 4 do
+ local thisBox = interfaceDiamond["Box" .. tSt(j)].Inside
+ for i = 1, 4 do
+ local thisStar = thisBox["Star" .. tSt(i)]
+ //print("Trying to obtain " .. tSt(modeKeys[j]) .. tSt(modeKeys[i]))
+ local thisColor = data[modeKeys[j]][modeKeys[i]]
+ if thisColor then
+ thisStar.BackgroundColor3 = thisColor
+ thisStar.Piece1.BackgroundColor3 = thisColor
+ thisStar.Visible = true
+ else
+ thisStar.Visible = false
+ end
+ end
+ end
+end
+
+local normalPositions = {uD2(0,0,0,0),uD2(0.5,0,0,0),uD2(0.5,0,0.5,0),uD2(0,0,0.5,0)}
+local boxResizes = {{1,1},{0,1},{0,0},{1,0}}
+local boxMajorOffsets = {{0,-1},{1,0},{0,1},{-1,0}}
+local diamondOffsets = {0.12,0.2}
+
+function resizeBoxes(mainBox,bigSize,smallSize)
+ for i = 1, 4 do
+ local object = interfaceDiamond["Box" .. tSt(i)]
+ local size = (i == mainBox and bigSize) or smallSize //Use the big box size if the box is the main one
+ local offset = 0.5-size
+ local boxFactors = boxResizes[i]
+ object.Size = uD2(size,0,size,0)
+ object.Position = normalPositions[i]+uD2(boxFactors[1]*offset,0,boxFactors[2]*offset,0)
+ end
+ local mainOffsets = boxMajorOffsets[mainBox]
+ interfaceDiamond.Position = uD2(0.359-diamondOffsets[1]*mainOffsets[1],0,0.25-diamondOffsets[2]*mainOffsets[2],0) //Offset the main diamond
+end
+*/
+//////////////
+// The Menu //
+//////////////
+
+const menuIsOpen = false;
+const currentPage = 2; // 1 is forms, 2 is equips, 3 is summons, 4 is settings/info
+const menuInTransit = false;
+/*
+local buttonMouseIsOn = ""
+local pages = interfaceMenu.Pages
+local mainStar = mainInterface.FatStar
+local lineR, lineB = interfaceMenu.RightLine, interfaceMenu.BottomLine
+local starR, starB = interfaceMenu.StarTR, interfaceMenu.StarBL
+local buttonParent = interfaceMenu.NavButtons
+local buttons = {buttonParent.Forms,buttonParent.Equips,buttonParent.Summons,buttonParent.Other}
+local buttonTags = {"Forms","Equipment","Enemies","Information and Settings"}
+local pageFolder = interfaceMenu.Pages
+local pages = {nil,pageFolder.Equipment,nil,nil}
+local selectName, selectDetails = interfaceMenu.SelectName, interfaceMenu.SelectDetails
+local pageName, nameDecoration = interfaceMenu.PageName, interfaceMenu.NameDecoration
+local hoverLabel = mainInterface.HoverLabel
+hoverLabel.Visible = false
+*/
+//////////////////////-
+// Page 2: Equipment //
+//////////////////////-
+/*
+local equipModule = require(storage.EquipModule)
+local equipDisplay = pages[2].Display
+local displaySortType, displaySortDirection = pages[2].SortType, pages[2].SortDirection
+local tabWeapons, tabArmor = pages[2].TabWeapons, pages[2].TabArmor
+local equipFolder = storage.Equipment
+local sEquipName = pages[2].WeaponName // sEquip is shorthand for "selected equip"
+local sEquipDescription = pages[2].WeaponDescription
+local sEquipType = pages[2].WeaponType
+local sEquipTraits = {pages[2].WeaponTrait1,pages[2].WeaponTrait2,pages[2].WeaponTrait3,pages[2].WeaponTrait4}
+local sEquipFrame = pages[2].ItemSelected.ViewportFrame
+local sEquipCam = new("Camera")
+sEquipCam.CameraType = Enum.CameraType.Scriptable
+sEquipCam.Parent = sEquipFrame
+sEquipCam.CFrame = CFrame.new(0,10,-10)
+sEquipFrame.CurrentCamera = sEquipCam
+
+local spinning = false
+local spinAngle = 0
+local spinMagnitude = 0
+local spinY = 0
+
+local currentEquipCategory = 1
+local sEquip = 0
+
+local equipRarityColors = {rgb(255,255,255),rgb(255,246,124),rgb(255,36,50),rgb(216,58,255),rgb(101,59,255),rgb(64,182,255)}
+local equipRarityNames = {"Regular", "Advanced", "Elite", "Extraordinary", "Transcendent", "Exalted"}
+local equipTraitNames = {"%attack", "defense", "%health", "%resistance", "speed"}
+local equipTraitColors = {"ff0e0e", "7db4f3", "5aee7d", "3155f5", "eeea5b"}
+
+local currentSortOrder = 1
+local sortReverse = false
+
+local function flipArray(array)
+ local n = #array
+ for i = 1, floor(n/2) do
+ local a, b = array[i], array[n + 1 - i]
+ array[i] = b
+ array[n + 1 - i] = a
+ end
+end
+
+local function sortRarity(one,two,fallbackSort,fallbackFallback)
+ local a, b = one[2], two[2]
+ if a < b then
+ return false
+ elseif a > b or not fallbackSort then
+ return true
+ else
+ return fallbackSort(one,two,fallbackFallback)
+ end
+end
+
+
+local function sortClass(one,two,fallbackSort,fallbackFallback)
+ local a, b = tN(sub(tSt(one[7]),1,1)), tN(sub(tSt(two[7]),1,1))
+ if a > b then
+ return false
+ elseif a < b or not fallbackSort then
+ return true
+ else
+ return fallbackSort(one,two,fallbackFallback)
+ end
+end
+
+local function sortAlpabetically(one,two,fallbackSort,fallbackFallback)
+ local a, b = one[1], two[1]
+ local aN, bN = len(a), len(b)
+ local n = (aN <= bN and aN) or bN
+ for i = 1, n do
+ local A, B = upper(sub(a,i,i)), upper(sub(b,i,i))
+ if A < B then
+ return true
+ elseif A > B then
+ return false
+ end
+ end //At this point, the names are entirely identical until the shortest one ends
+ if aN == bN and fallbackSort then
+ return fallbackSort(one,two,fallbackFallback)
+ elseif n == aN then // If a is the shorter one (n), we return it. If the strings are identical, we return a (true) to keep them in their previous order (stable sorting).
+ return true
+ else
+ return false
+ end
+end
+
+local sortOrders = {
+ {"Rarity", {sortRarity, sortClass, sortAlpabetically}},
+ {"Class", {sortClass, sortRarity, sortAlpabetically}},
+ {"Name", {sortAlpabetically, sortRarity, sortClass}}
+}
+
+ //////////////////////////////////////////////-
+//| leftSorter -> leftEnd | rightSorter -> last |//
+ //////////////////////////////////////////////-
+local function merge(array,first,last,sorter1,sorter2,sorter3)
+ local leftEnd = floor((first + last)/2) //1
+ local leftSorter = first //1
+ local rightSorter = leftEnd + 1 // 2
+ local sorted = {unpack(array)}
+ for i = first, last do
+ if rightSorter > last or (leftSorter <= leftEnd and sorter1(array[leftSorter],array[rightSorter],sorter2,sorter3)) then //Switch last to < to reverse order
+ sorted[i] = array[leftSorter]
+ leftSorter += 1
+ else
+ sorted[i] = array[rightSorter]
+ rightSorter += 1
+ end
+ end
+ for i = first, last do
+ array[i] = sorted[i]
+ //print(sorted[i][1])
+ end
+end
+
+function mergeSort(array,first,last,sorter1,sorter2,sorter3)
+ first = first or 1
+ last = last or #array
+
+ if first < last then
+ local middle = floor((first + last)/2)
+ mergeSort(array,first,middle,sorter1,sorter2,sorter3) // Sort left (recursively)
+ mergeSort(array,middle + 1,last,sorter1,sorter2,sorter3) // Sort right (recursively)
+
+ merge(array,first,last,sorter1,sorter2,sorter3)
+ end
+end
+
+local format = string.format
+
+function refreshEquips(ownedWeapons)
+ local equips = {unpack(equipModule[currentEquipCategory])} //Later this will be only the equips you have unlocked
+ local count = #equips
+ local rows = ceil(count/4)
+ // Sort the equips
+ mergeSort(equips,nil,nil,unpack(sortOrders[currentSortOrder][2]))
+ if sortReverse then
+ flipArray(equips)
+ end
+ // Adjust the canvas size to make all of the frames perfectly square
+ local pixelWidth = equipDisplay.Frame.AbsoluteSize.X
+ local displayY = (pixelWidth/5)*(rows*6 + 1)
+ local displayAbsY = equipDisplay.AbsoluteSize.Y
+ equipDisplay.CanvasSize = uD2(0,0,0,displayY)
+ //Adjust if there are < 4 rows
+ local practicalCanvas = 1
+ local offset
+ if rows < 4 and displayY <= displayAbsY then
+ offset = pixelWidth/5/displayAbsY//offset = 0.0467289
+ else
+ offset = 1/(rows*6 + 1)
+ end
+ // Adjust the frame sizes to make them take up the right amounts of the canvas
+ //local offset = practicalCanvas/(rows*6 + 1)
+ local height = offset*5
+ local diff = offset*6
+
+ for i, v in pairs(equipDisplay:GetChildren()) do
+ if v.Name ~= "Frame" then
+ v:Destroy()
+ end
+ end
+
+ local frameName = "WeaponFrame"
+ if currentEquipCategory == 2 then
+ frameName = "ArmorFrame"
+ end
+
+ for i, equip in paris(equips) do
+ local row = ceil(i/4) - 1
+ local column = i - row*4 - 1
+
+ local f = new("Frame")
+ f.Name = frameName
+ f.Size = uD2(0.2,0,height,0)
+ f.Position = uD2(0.04 + column*0.24,0,offset + row*diff,0)
+ f.BorderSizePixel = 0
+
+ local vF = new("ViewportFrame")
+ vF.Name = equip[8]
+ vF.Size = uD2(1,0,1,0)
+ vF.BackgroundTransparency = 1
+ vF.Position = uD2(0,0,0,0)
+ local w = equipFolder[equip[1]]:Clone()
+ w.Parent = vF
+ local c = new("Camera")
+ c.CFrame = equip[4]
+ c.Parent = vF
+ vF.CurrentCamera = c
+ vF.Parent = f
+
+ local g = new("UIGradient")
+ g.Rotation = -45
+ g.Transparency = NumberSequence.new(0,1)
+ g.Parent = f
+ if equip[2] == 6 then
+ f.BackgroundColor3 = equipRarityColors[equip[2]]
+ else
+ f.BackgroundColor3 = equipRarityColors[equip[2]]
+ end
+
+ f.Parent = equipDisplay
+ end
+end
+
+local uv = v3(0,1,0)
+function lookAt(start,ende) // Is in multiple scripts, could be consolidated
+ local fv = (ende-start).Unit
+ local rv = fv:Cross(uv)
+ local uv2 = rv:Cross(fv)
+ return CFrame.fromMatrix(start,rv,uv2)
+end
+
+function handleEquipClick(equipId,equipCategory,keepSpin)
+ local equip = equipModule[equipCategory][equipId]
+ local rarityColor = equipRarityColors[equip[2]]
+ local hexColor = format("%02X%02X%02X",rarityColor.R*255,rarityColor.G*255,rarityColor.B*255)
+ // Change the information
+ sEquipName.Text = equip[1]
+ sEquipType.Text = '' .. equipRarityNames[equip[2]] .. ' ' .. equip[3]
+ sEquipDescription.Text = equip[5]
+ local traits = equip[6]
+ for i = 1, 4 do // Show the traits
+ local traitId = traits[i*2 - 1]
+ if traitId then
+ local amount = traits[i*2]
+ local traitName = equipTraitNames[traitId]
+ // Add the sign based on positivity or negativity
+ amount = (amount >= 0 and "+ " .. tSt(amount)) or "- " .. tSt(amount)
+ // Add the % if the trait uses % as the measure
+ if sub(traitName,1,1) == "%" then
+ amount = amount .. "%"
+ traitName = sub(traitName,2,len(traitName))
+ end
+ sEquipTraits[i].Text = '' .. amount .. ' ' .. traitName
+ else
+ sEquipTraits[i].Text = ""
+ end
+ end
+ // Replace the existing model
+ local model = sEquipFrame:FindFirstChildOfClass("Model")
+ if model then
+ model:Destroy()
+ end
+ model = equipFolder:FindFirstChild(equip[1])
+ if model then
+ model:Clone().Parent = sEquipFrame
+ end
+ // Adjust spin values
+ if not keepSpin then
+ spinAngle = 0
+ end
+ spinY = equip[4].Position.Y
+ spinMagnitude = v3(equip[4].Position.X,0,equip[4].Position.Z).Magnitude
+end
+
+local mTInfo1 = TweenInfo.new(0.25,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
+local mTInfo2 = TweenInfo.new(0.25,Enum.EasingStyle.Quad,Enum.EasingDirection.In)
+function openMenu()
+ refreshEquips()
+ handleEquipClick(1,1,true)
+ menuInTransit = true
+
+ interfaceMenu.BackgroundTransparency = 1 //Set the stage
+ lineB.Position = uD2(1,0,0.998,0) //Push the stars and lines to the corner
+ lineB.Size = uD2(0,0,0.005,0)
+ lineR.Position = uD2(0.998,0,1,0)
+ lineR.Size = uD2(0.003,0,0,0)
+ starB.Position = uD2(0.994,0,0.989,0)
+ starR.Position = uD2(0.994,0,0.989,0)
+ for i, v in pairs(buttons) do
+ v.BackgroundTransparency = 1
+ v.NavButton.ImageTransparency = 1
+ end
+ selectName.TextTransparency = 1
+ selectName.TextStrokeTransparency = 1
+ selectDetails.TextTransparency = 1
+ selectDetails.TextStrokeTransparency = 1
+
+ pageName.TextTransparency = 1
+ pageName.TextStrokeTransparency = 1
+ nameDecoration.ImageTransparency = 1
+ nameDecoration.Frame.BackgroundTransparency = 1
+ nameDecoration.Frame.Image.ImageTransparency = 1
+
+ local children = pages[currentPage]:GetChildren()
+ for i, v in pairs(children) do
+ v.Visible = false
+ end
+
+ tween:Create(mainStar,mTInfo1,{Position = uD2(0.854,0,0.803,0), Size = uD2(0.042,0,0.075,0)}):Play()
+ wait(0.25)
+
+ interfaceMenu.Visible = true //The curtain rises
+
+ tween:Create(lineB,mTInfo1,{Position = uD2(0,0,0.998,0), Size = uD2(1,0,0.005,0)}):Play()
+ tween:Create(lineR,mTInfo1,{Position = uD2(0.998,0,0,0), Size = uD2(0.003,0,1,0)}):Play()
+ tween:Create(starB,mTInfo1,{Position = uD2(-0.006,0,0.989,0)}):Play()
+ tween:Create(starR,mTInfo1,{Position = uD2(0.994,0,-0.01,0)}):Play()
+ wait(0.25)
+ tween:Create(interfaceMenu,mTInfo1,{BackgroundTransparency = 0.5}):Play()
+ for i, v in pairs(buttons) do
+ tween:Create(v,mTInfo1,{BackgroundTransparency = 0.5}):Play()
+ tween:Create(v.NavButton,mTInfo1,{ImageTransparency = 0}):Play()
+ end
+ tween:Create(pageName,mTInfo1,{TextTransparency = 0, TextStrokeTransparency = 0.85}):Play()
+ tween:Create(nameDecoration,mTInfo1,{ImageTransparency = 0.5}):Play()
+ tween:Create(nameDecoration.Frame,mTInfo1,{BackgroundTransparency = 0.5}):Play()
+ tween:Create(nameDecoration.Frame.Image,mTInfo1,{ImageTransparency = 0.5}):Play()
+ for i, v in pairs(children) do //Show the page elements
+ v.Visible = true
+ wait()
+ end
+ menuIsOpen = true
+ menuInTransit = false
+ while menuIsOpen do // MAJOR SPOT FOR CLEANUP
+ if currentPage == 2 then
+ local x, y = sin(rad(spinAngle)), cos(rad(spinAngle))
+ sEquipCam.CFrame = lookAt(v3(x*spinMagnitude,spinY,y*spinMagnitude),v3(0,0,0))
+ spinAngle += 2
+ wait()
+ end
+ local mPos = uIS:GetMouseLocation() - Vector2.new(0,26)
+ //print(mPos.Y)
+ local gObjects = plrGui:GetGuiObjectsAtPosition(mPos.X,mPos.Y)
+ local thisButton = ""
+ local sawWeaponFrame = false
+ for i, v in pairs(gObjects) do
+ //print(v.Name)
+ //print(v.Name == "NavButton")
+ //hoverLabel.Visible = false
+ if v.Name == "NavButton" then
+ thisButton = v.Parent
+ print(thisButton.Name)
+ elseif v.Name == "WeaponFrame" then
+ hoverLabel.Text = equipModule[currentEquipCategory][tN(v:FindFirstChildOfClass("ViewportFrame").Name)][1]
+ hoverLabel.Position = uD2(0,mPos.X+5,0,mPos.Y)
+ hoverLabel.Visible = true
+ sawWeaponFrame = true
+ end
+ end
+ if not sawWeaponFrame then
+ hoverLabel.Visible = false
+ end
+ if thisButton ~= buttonMouseIsOn then
+ // Shrink formerly emphasized button
+ if buttonMouseIsOn ~= "" then
+ local size = buttonMouseIsOn.Size
+ local position = buttonMouseIsOn.Position
+ local sX, sY = size.X.Scale, size.Y.Scale
+ //local pX, pY = position.X.Scale+sX*0.1, position.Y.Scale+sY*0.1
+ tween:Create(buttonMouseIsOn,mTInfo1,{Position = uD2(-0.25 + tFind(buttons,buttonMouseIsOn)*0.25,0,0,0), Size = uD2(0.21,0,1,0)}):Play()
+ else
+ selectName.Text = buttonTags[tFind(buttons,thisButton)]
+ tween:Create(selectName,mTInfo1,{TextTransparency = 0, TextStrokeTransparency = 0.85}):Play()
+ end
+ buttonMouseIsOn = thisButton
+ // Enlarge newly emphasized button
+ if buttonMouseIsOn ~= "" then
+ local size = buttonMouseIsOn.Size
+ local position = buttonMouseIsOn.Position
+ local sX, sY = size.X.Scale, size.Y.Scale
+ //local pX, pY = position.X.Scale-sX*0.125, position.Y.Scale-sY*0.125
+ tween:Create(buttonMouseIsOn,mTInfo1,{Position = uD2(-0.271 + tFind(buttons,buttonMouseIsOn)*0.25,0,0,0), Size = uD2(0.252,0,1.2,0)}):Play()
+ else
+ tween:Create(selectName,mTInfo1,{TextTransparency = 1, TextStrokeTransparency = 1}):Play()
+ end
+ end
+ wait()
+ end
+end
+
+function closeMenu()
+ menuInTransit = true
+ tween:Create(interfaceMenu,mTInfo2,{BackgroundTransparency = 1}):Play()
+ for i, v in pairs(buttons) do
+ tween:Create(v,mTInfo2,{BackgroundTransparency = 1}):Play()
+ tween:Create(v.NavButton,mTInfo2,{ImageTransparency = 1}):Play()
+ end
+ tween:Create(pageName,mTInfo2,{TextTransparency = 1, TextStrokeTransparency = 1}):Play()
+ tween:Create(nameDecoration,mTInfo2,{ImageTransparency = 1}):Play()
+ tween:Create(nameDecoration.Frame,mTInfo2,{BackgroundTransparency = 1}):Play()
+ tween:Create(nameDecoration.Frame.Image,mTInfo2,{ImageTransparency = 1}):Play()
+ local children = pages[currentPage]:GetChildren() //Hide the page elements
+ local when = clock() + 0.25
+ for i, v in pairs(children) do
+ v.Visible = false
+ wait()
+ end
+ wait(when-clock())
+ tween:Create(lineB,mTInfo2,{Position = uD2(1,0,0.998,0), Size = uD2(0,0,0.005,0)}):Play()
+ tween:Create(lineR,mTInfo2,{Position = uD2(0.998,0,1,0), Size = uD2(0.003,0,0,0)}):Play()
+ tween:Create(starB,mTInfo2,{Position = uD2(0.994,0,0.989,0)}):Play()
+ tween:Create(starR,mTInfo2,{Position = uD2(0.994,0,0.989,0)}):Play()
+ wait(0.25)
+ tween:Create(mainStar,mTInfo2,{Position = uD2(0,106,0,7), Size = uD2(0,26,0,26)}):Play()
+ wait(0.25)
+ interfaceMenu.Visible = false //The curtain falls
+ menuIsOpen = false
+ menuInTransit = false
+end
+
+function changeSortType()
+ currentSortOrder = (currentSortOrder == 3 and 1) or currentSortOrder + 1
+ displaySortType.Text = "Sort by: " .. sortOrders[currentSortOrder][1]
+ refreshEquips()
+end
+
+function changeSortDirection()
+ if sortReverse then
+ sortReverse = false
+ displaySortDirection.Rotation = 0
+ else
+ sortReverse = true
+ displaySortDirection.Rotation = 180
+ end
+ refreshEquips()
+end
+
+function changeEquipCategory(armor)
+ if armor and currentEquipCategory ~= 2 then
+ currentEquipCategory = 2
+ tabArmor.BackgroundTransparency = 0.7
+ tabArmor.TextColor3 = rgb(255,255,255)
+ tabWeapons.BackgroundTransparency = 0.6
+ tabWeapons.TextColor3 = rgb(171,171,171)
+ refreshEquips()
+ elseif not armor and currentEquipCategory ~= 1 then
+ currentEquipCategory = 1
+ tabWeapons.BackgroundTransparency = 0.7
+ tabWeapons.TextColor3 = rgb(255,255,255)
+ tabArmor.BackgroundTransparency = 0.6
+ tabArmor.TextColor3 = rgb(171,171,171)
+ refreshEquips()
+ end
+end
+
+function handleMenuClick()
+ local mPos = uIS:GetMouseLocation() - Vector2.new(0,26)
+ local gObjects = plrGui:GetGuiObjectsAtPosition(mPos.X,mPos.Y)
+ for i, v in pairs(gObjects) do
+ if v.Name == "WeaponFrame" then
+ handleEquipClick(tN(v:FindFirstChildOfClass("ViewportFrame").Name),1)
+ elseif v.Name == "ArmorFrame" then
+ handleEquipClick(tN(v:FindFirstChildOfClass("ViewportFrame").Name),2)
+ elseif v == displaySortType then
+ changeSortType()
+ elseif v == displaySortDirection then
+ changeSortDirection()
+ elseif v == tabWeapons then
+ changeEquipCategory()
+ elseif v == tabArmor then
+ changeEquipCategory(true)
+ end
+ end
+end
+*/
+
+//Camera stuff
+//camera.CameraType = camScriptable
+//uIS.MouseBehavior = uISLockedCenter
+
+//Dialog stuff that's here from the SG:RPG, planning to rewrite it ~~if~~ WHEN we add NPCs to the map
+
+/*
+diaCache = {}
+function createDialog(f,tab)
+ if tab.Fire then
+ DialogEvent:FireServer(tab.Fire)
+ end
+ if tab.c ~= 0 then
+ f.SF.CanvasSize = UDim2.new(0,0,0,80+(tab.c-1)*90)
+ for i = 1, tab.c do
+ local c = f.SF["0"]:Clone()
+ c.TB.Text = tab[i].Choice
+ c.Visible = true
+ c.Name = i
+ c.Position = UDim2.new(0,0,0,90*(i-1))
+ c.Parent = f.SF
+ //Make the box show the cool gradient when the mouse enters it.
+ diaCache[#diaCache+1] = c.TB.MouseEnter:Connect(function()
+ for i = 1, 8 do
+ c.BackgroundTransparency = c.BackgroundTransparency/2
+ runService.Heartbeat:Wait()
+ end
+ c.BackgroundTransparency = 0
+ end)
+ //Make the box fade out when the mouse leaves.
+ diaCache[#diaCache+1] = c.TB.MouseLeave:Connect(function()
+ for i = 1, 8 do
+ c.BackgroundTransparency = (c.BackgroundTransparency+1)/2
+ runService.Heartbeat:Wait()
+ end
+ c.BackgroundTransparency = 1
+ end)
+ //Handle button click transitions.
+ diaCache[#diaCache+1] = c.TB.Activated:Connect(function()
+
+ f.Words.Text = tab[i].Resp
+ if string.len(tab[i].Resp) > 100 then
+ f.Words.TextScaled = true
+ else
+ f.Words.TextScaled = false
+ end
+
+ for i, v in pairs(f.SF:GetChildren()) do
+ if v.Name ~= "0" then
+ v:Destroy()
+ end
+ end
+ for i, v in pairs(diaCache) do
+ v:Disconnect()
+ end
+ diaCache = {}
+ createDialog(f,tab[i])
+ end)
+ end
+ else
+ wait(1+string.len(f.Words.Text)*0.03)
+ for i = 1, 20 do
+ pcall(function()
+ f.Position = f.Position:Lerp(UDim2.new(0,100,1,0),0.3)
+ runService.Heartbeat:Wait()
+ end)
+ end
+ pcall(function() f.Parent:Destroy() end)
+ isDialog = false
+ end
+end
+
+function Dialog(strin,model)
+ isDialog = true
+ local g = script.Dialog:Clone()
+ g.Parent = Plr.PlayerGui
+ local f = g.Frame
+
+ f.NPC.Text = strin.NPC
+ f.Words.Text = strin.FT
+ if string.len(strin.FT) > 100 then
+ f.Words.TextScaled = true
+ end
+
+ createDialog(f,strin)
+
+ local c = model:Clone()
+ c.Parent = f.VF
+ local cam = Instance.new("Camera",f.VF)
+ f.VF.CurrentCamera = cam
+ cam.CFrame = c.ClickBox.CFrame*strin.C
+
+ g.Frame.Position = UDim2.new(0,100,1,0)
+ g.Enabled = true
+ for i = 1, 20 do
+ f.Position =f.Position:Lerp(UDim2.new(0,100,0.6,0),0.3)
+ runService.Heartbeat:Wait()
+ end
+ g.Frame.Position = UDim2.new(0,100,0.6,0)
+end
+*/
+/*
+local shouldStartPBLLoop = true
+local connectionTable = {}
+
+local ngh = script.sgAnimate
+function giveScript(plr,mode)
+ if not script:FindFirstChild(plr.Name) then
+ local c = ngh:Clone()
+ c.Name = plr.Name
+ c.Parent = script
+ c.Disabled = false
+ if mode then
+ local uId = plr.UserId
+ local thisOne = rand(1,99999)
+ while connectionTable[thisOne] do
+ thisOne = rand(1,99999)
+ end
+ connectionTable[thisOne] = ModeEvent.Event:Connect(function(typ,aUId)
+ if typ == "Request" and aUId == uId then
+ connectionTable[thisOne]:Disconnect()
+ ModeEvent:Fire("Reply",uId,mode)
+ end
+ end)
+ end
+ end
+end
+*/
+//const rayCast = ws.Raycast;
+const hitParams = new RaycastParams();
+hitParams.FilterDescendantsInstances = [efFolder];
+hitParams.FilterType = Enum.RaycastFilterType.Blacklist;
+function mouse() {
+ const chr = Plr.Character;
+ if (chr) {
+ hitParams.FilterDescendantsInstances = [efFolder, chr];
+ } else {
+ hitParams.FilterDescendantsInstances = [efFolder];
+ }
+ const mouseLocation = uIS.GetMouseLocation();
+ if (Cam) {
+ const unitRay = Cam.ViewportPointToRay(mouseLocation.X, mouseLocation.Y);
+ const cast = ws.Raycast(unitRay.Origin, unitRay.Direction.mul(1000), hitParams);
+ if (cast) {
+ return [cast.Position, cast.Normal, cast.Instance];
+ } else {
+ return [unitRay.Origin.add(unitRay.Direction.mul(1000)), new v3(0, 0, 0), undefined];
+ }
+ } else {
+ print("Camera not found!");
+ }
+}
+/*
+Output.OnClientEvent.Connect((event: string,arg1,arg2,arg3,arg4,arg5,arg6) => {
+ if (event == "GiveScript") {
+ //giveScript(arg1,arg2)
+ } else if (event == "ModeChange" && arg1 == Plr.UserId) {
+ Music.SoundId = rid + arg2.music[1]
+ //changeGuiMode(arg2.name,arg2.main,arg2.sec,arg2.font,arg2.music[2],arg2.music[3])
+ if arg2.sendpbl and shouldStartPBLLoop then
+ shouldStartPBLLoop = false
+ SendPlaybackLoudness = true
+ while SendPlaybackLoudness do
+ wait(0.1)
+ Input:FireServer("PBL",Music.PlaybackLoudness)
+ end
+ shouldStartPBLLoop = true //This makes it so that multiple loops are not created if a player switches from one PBL mode to another
+ else
+ SendPlaybackLoudness = false
+ end
+ //} else if event == "Shake" then
+ //CamShake(arg1,arg2)
+ //} else if (event == "Notify") {
+ //Notify(arg1)
+ //} else if (event == "Cooldown") {
+ //handleCooldown(arg1,arg2,arg3,arg4,arg5,arg6)
+ //} else if (event == "MovesExist") {
+ //movesExist = arg1
+ //updateCooldownGui(arg2,arg3,arg4,arg5)
+ //} else if (event == "SideColors") {
+ //updateDiamond(arg1)
+ //} else if event == "EnemyInit" then
+ //warn("Got enemy init message: " .. arg1)
+ //enemyModules[arg1]["Init"](arg2)
+ //} else if event == "EnemyClientEvent" then
+ //print("Got enemy client event of " .. arg1 .. " " .. arg2)
+ //enemyModules[arg1][arg2](arg3,arg4,arg5)
+ //} else if event == "MouseRequest" or (event == "ClientEvent" and arg2 == "BeamUpdate" and arg1 == Plr.UserId) then
+ //print("Client got mouserequest, updating")
+ //Input:FireServer("Input",nil,mouse())
+ }
+});
+*/
+
+//Inputs
+function handleModeInput(key: string) {
+ storedModeKey += key;
+ if (storedModeKey.size() >= 2) {
+ //print("Firing server with " .. storedModeKey)
+ input.FireServer("Input", storedModeKey, mouse());
+ storedModeKey = "";
+ //interfaceDiamond.Visible = false;
+ } else {
+ //interfaceDiamond.Visible = true
+ /*
+ for (let i = 1; i <= 5; i++) {
+ local thisBox = interfaceDiamond["Box" .. tSt(i)].Inside
+ if (i == modeKeys.findIndex(,)) {
+ thisBox.Key.TextTransparency = 0
+ } else {
+ thisBox.Key.TextTransparency = 0.75
+ }
+ }
+ resizeBoxes(tFind(modeKeys,key),0.6,0.4)
+ */
+ }
+}
+
+function handleInput(k: InputObject, object: boolean) {
+ const keyCode = k.KeyCode;
+ if (k.UserInputType === Enum.UserInputType.MouseButton1 && !menuInTransit) {
+ if (menuIsOpen) {
+ //handleMenuClick()
+ } else if (!object) {
+ input.FireServer("Input", "click", mouse());
+ }
+ } else if (!object && keyCode && !menuInTransit) {
+ const key = sub(tS(keyCode), 14);
+ //print("Got key " .. keyCode)
+ if (key === "G") {
+ if (menuIsOpen) {
+ //closeMenu()
+ } else {
+ //openMenu()
+ }
+ } else if (!menuIsOpen && tFind(modeKeys, key)) {
+ //print("Got mode key")
+ handleModeInput(key);
+ } else if (!menuIsOpen && (tFind(abilityKeys, key) || tFind(otherModeKeys, key))) {
+ input.FireServer("Input", key, mouse());
+ }
+ }
+}
+
+uIS.InputBegan.Connect(handleInput);
+
+wait();
+/*
+for i, v in pairs (plrs:GetChildren()) do
+ giveScript(v.Name)
+end
+
+plrs.PlayerAdded:Connect(function(plr)
+ giveScript(plr.Name)
+end)
+*/
+
+//hey
+input.FireServer("Message", Plr.Name + "'s local script has loaded.");
+print(makeHello("The Reborn Client"));
+
+//More legacy stuff from the SG:RPG
+/*
+Plr.CharacterAdded:Connect(function() //Handle the health bar (it has to get the humanoid every time the character respawns
+ isDialog = false
+ wait(0.5)
+ hum = Plr.Character.Humanoid
+ G.Box.HP.L.Text = tostring(hum.MaxHealth) .. "/" .. tostring(hum.MaxHealth)
+ pcall(function() conch:Disconnect() end)
+ conch = hum.HealthChanged:Connect(function()
+ print(tostring(math.floor(hum.Health)))
+ G.Box.HP.L.Text = tostring(math.floor(hum.Health)) .. "/" .. tostring(hum.MaxHealth)
+ repeat
+ G.Box.HP.B.Size = G.Box.HP.B.Size:Lerp(UDim2.new(hum.Health/hum.MaxHealth,0,0,13),0.1)
+ runService.Heartbeat:Wait()
+ until G.Box.HP.B.Size == UDim2.new(hum.Health/hum.MaxHealth,0,0,13) or not hum
+ end)
+end)
+
+repeat //-Get the gosh darn humanoid already
+ pcall(function() hum = Plr.Character.Humanoid end)
+ wait()
+until hum
+
+if not conch then //The script's not fast enough to detect the initial spawn so I'm just leaving this here
+ conch = hum.HealthChanged:Connect(function()
+ print(tostring(math.floor(hum.Health)))
+ G.Box.HP.L.Text = tostring(math.floor(hum.Health)) .. "/" .. tostring(hum.MaxHealth)
+ repeat
+ G.Box.HP.B.Size = G.Box.HP.B.Size:Lerp(UDim2.new(hum.Health/hum.MaxHealth,0,0,13),0.1)
+ runService.Heartbeat:Wait()
+ until G.Box.HP.B.Size == UDim2.new(hum.Health/hum.MaxHealth,0,0,13) or not hum
+ end)
+end
+*/
diff --git a/src/client/init.meta.json b/src/client/init.meta.json
new file mode 100644
index 0000000..d157e77
--- /dev/null
+++ b/src/client/init.meta.json
@@ -0,0 +1,3 @@
+{
+ "ignoreUnknownInstances": true
+}
diff --git a/src/client/main.client.ts b/src/client/main.client.ts
new file mode 100644
index 0000000..3110bed
--- /dev/null
+++ b/src/client/main.client.ts
@@ -0,0 +1,5 @@
+import { makeHello } from "shared/module";
+const tween = game.GetService("TweenService");
+const v3 = Vector3;
+print("hello again");
+print(makeHello("main.client.ts"));
diff --git a/src/server/main.server.ts b/src/server/main.server.ts
new file mode 100644
index 0000000..a53c476
--- /dev/null
+++ b/src/server/main.server.ts
@@ -0,0 +1,768 @@
+//This is the core of reality.
+
+// BASIC SETUP
+
+// Universal variables
+import { makeHello } from "shared/module";
+const plrs = game.GetService("Players");
+const ws = game.GetService("Workspace");
+const tween = game.GetService("TweenService");
+const runService = game.GetService("RunService");
+const storage = game.GetService("ReplicatedStorage");
+// Aliases
+const uD2 = UDim2;
+const v3 = Vector3;
+const cF = CFrame;
+const inst = Instance;
+const tN = tonumber;
+const tS = tostring;
+const wait = task.wait;
+const clock = os.clock;
+const floor = math.floor;
+const ceil = math.ceil;
+const abs = math.abs;
+const cos = math.cos;
+const sin = math.sin;
+const rad = math.rad;
+const rand = math.random;
+const clamp = math.clamp;
+const sub = string.sub;
+// Constructors
+const rgb = Color3.fromRGB;
+const hsv = Color3.fromHSV;
+const xyz = CFrame.fromEulerAnglesXYZ;
+const wrap = coroutine.wrap;
+
+const zF = new cF(0, 0, 0);
+//End of universal variables
+
+//Other variables
+const neon = Enum.Material.Neon
+
+const remotes = storage.Remotes;
+const input = remotes.Input;
+const output = remotes.Output;
+
+function tB(data: any) { // to boolean
+ if (data) {return true;} else {return false;}
+}
+
+function floorToBase(number: number, base: number) { // Is in multiple scripts, could be consolidated
+ return floor(number * base) / base;
+}
+
+function AFrame(x: number,y: number,z: number,rx: number,ry: number,rz: number) { // Is in multiple scripts, could be consolidated
+ return new cF(x,y,z).mul(xyz(rad(rx),rad(ry),rad(rz)));
+}
+
+const uv = new v3(0,1,0);
+function lookAt(start: Vector3,ende: Vector3) { // Is in multiple scripts, could be consolidated (This is the master version)
+ let fv = (ende.sub(start)).Unit;
+ let rv = fv.Cross(uv);
+ let uv2 = rv.Cross(fv);
+ return cF.fromMatrix(start,rv,uv2);
+}
+
+function weld(name: string, p0: BasePart, p1: BasePart | undefined, cZero: CFrame, cOne: CFrame) {
+ let we = new inst("Motor6D"); // plot twist, it was a motor6D all along, now go home
+ we.Name = name;
+ we.Part0 = p0;
+ we.Part1 = p1;
+ we.C0 = cZero;
+ we.C1 = cOne;
+ we.Parent = p0;
+ return(we);
+}
+
+function newPart(parent: Instance,color: Color3,material: Enum.Material,transparency: number,anchored: boolean,canCollide: boolean,size: Vector3,shape?: Enum.PartType,hasmass?: boolean,hasshadow?: boolean) {
+ let part = new inst("Part");
+ part.Color = color;
+ part.Material = material;
+ part.Transparency = transparency;
+ part.Anchored = anchored;
+ part.CanCollide = canCollide;
+ part.Size = size;
+ part.Shape = shape || Enum.PartType.Block;
+ part.Massless = hasmass || false;
+ part.CastShadow = hasshadow || false;
+ part.Parent = parent;
+ return(part);
+}
+
+function emitter(tab: emitterTable) { // Is in multiple scripts, could be consolidated (This is the master version)
+ let e = new inst("ParticleEmitter");
+ e.Color = tab.color;
+ e.LightEmission = tab.lightE || 1;
+ e.LightInfluence = tab.lightI || 0;
+ e.Size = tab.size;
+ e.Texture = tab.texture;
+ e.Transparency = tab.transparency;
+ e.Drag = tab.drag || 0;
+ e.LockedToPart = tab.locked || false;
+ e.Lifetime = tab.lifetime;
+ e.Rate = tab.rate;
+ e.Rotation = tab.rotation || new NumberRange(-180, 180);
+ e.RotSpeed = tab.rotSpeed || new NumberRange(-100, 100);
+ e.Speed = tab.speed;
+ e.SpreadAngle = tab.spread || new Vector2(180,180);
+ e.Parent = tab.parent;
+ return e;
+}
+
+function getDist(one: Vector3, two: Vector3) { // Is in multiple scripts, could be consolidated
+ return one.add(two).Magnitude;
+}
+
+//local wingFolder = game:GetService("ServerStorage").Wings
+
+//const modules = game.GetService("ServerScriptService").Server.Modules
+//const modes = require(Modules.Modes)
+//const abilties = require(Modules.Abilities)
+/*
+ _________________
+ \ /
+ //| Inputs |//
+ /_________________\
+
+ *///
+//const eK = Enum.KeyCode
+const modeKeys = ["Q","E","R","F"];//{ek.Q,ek.E,ek.R,ek.T,ek.Y,ek.U,ek.F,ek.G,ek.H,ek.J,ek.K,ek.L}
+const subModeKeys = ["B","N","M"];//{ek.B,ek.N,ek.M}
+const sideKeys = ["1","2","3","4"];//{ek.One,ek.Two,ek.Three,ek.Four}
+const abilityKeys = ["Z","X","C","V"];
+//coolDown.Z, coolDown.X, coolDown.C, coolDown.V = {}, {}, {}, {}
+//local abilityKeysString = {"Z","X","C","V"}
+
+//local pvp = {} //Stores all of the PvP states for every player.
+//var mouseData = {} //Mouse data (mouseData[player id] = {pos, norm, targ})
+/*
+function localModeTable(modeTable) {
+ local wc = modeTable.wingc
+ return {
+ name = modeTable.name, font = modeTable.tag[4],
+ main = modeTable.main, sec = modeTable.sec,
+ wanim = modeTable.wanim, manim = modeTable.manim,
+ height = modeTable.height,
+ music = modeTable.music,
+ lefts = wc.left, rights = wc.right,
+ sendpbl = modeTable.sendpbl or nil, coloreffect = modeTable.coloreffect or nil, coloraffected = modeTable.coloraffected or nil, parttoaffect = modeTable.parttoaffect or nil
+ }
+}
+
+function sideColorTable(set,sideNumber)
+ local colorTable = {Q = {},E = {},R = {},F = {}}
+ for i, v in pairs(Modes[set][sideNumber]) do
+ if len(i) == 2 then
+ print("Set " .. tSt(sub(i,1,1)) .. tSt(sub(i,2)))
+ colorTable[sub(i,1,1)][sub(i,2)] = v.main
+ end
+ end
+ return colorTable
+end
+*/
+interface movesTable {
+ Z: boolean;
+ X: boolean;
+ C: boolean;
+ V: boolean;
+}
+
+interface pEntry {
+ set: number;
+ mode: string;
+
+ canDoAction: boolean;
+ hasMoves: movesTable;
+ clickAttack: [number, number];
+ coolDown: {[key: string]: number};
+ pvp: boolean;
+ mousePos: Vector3;
+
+ parts: [undefined?, Model, Humanoid, Part, Part, Part, Part, Part, Part, Part];
+ wings: [undefined?, Folder, Part[][], Part];
+ bGui: [undefined?, BillboardGui, TextLabel, TextLabel, GuiObject[], GuiObject[]]
+}
+
+var p: {[key: number]: pEntry} = []; // The god table. Legend says it holds the secrets of the universe.
+
+function initPlr(plr: Player) {
+ let uId = plr.UserId;
+ // PLAYER VARIABLES
+ let parts = getParts(uId);
+ if (!parts) { warn("Server: Player by UserId of " + tS(uId) + " not found, returning..."); return; } // One last chance to turn back
+ let wings = makeWings(parts); // From here, we are nihilists (if the thread errors, it errors)
+ makeDecor(wings, "SpectrumWing", "SpectrumCore")
+ let entry: pEntry = { // This should load information from datastores in the future
+ set = 1,
+ mode = "Q",
+
+ canDoAction = true,
+ hasMoves = {Z = false, X = false, C = false, V = false},
+ clickAttack = [1,0],
+ coolDown = {},
+ pvp = false,
+ mousePos = new v3 (0,0,0),
+
+ parts = parts,
+ wings = wings,
+ };
+ //guh.StoredModeInfo = {}
+ //PlaybackLoudness information
+ //guh.PBL = Instance.new("NumberValue",plr)
+ //guh.PBL.Name = "PBL"
+ //Stored tweens (like for mode changes)
+ //guh.Tweens = {}
+ //mouseData[uId] = {v3(0,0,0),v3(0,0,0),1}
+ //pvp[uId] = 0 //Zero is none, one is friends, two is all.
+ //Finish setup
+ p[uId] = entry;
+ setUp(plr); // TEMPORARY
+ //plr.CharacterAdded.Connect(setUp)
+
+ /* WILL BE REIMPLEMENTED WITH THE SGANIMATE REWORK
+ output.FireAllClients("GiveScript",plr) //Tell all clients to animate this player
+
+ for i, otherPlayer in pairs(plrs:GetChildren()) do //Tell this client to animate all of the other players
+ if otherPlayer ~= plr then
+ print("Giving script of " .. otherPlayer.Name .. " to " .. plr.Name)
+ Output:FireClient(plr,"GiveScript",otherPlayer,p[otherPlayer.UserId].StoredModeInfo)
+ end
+ end
+ */
+ print(plr.Name + " has initiallized successfully.");
+}
+
+function deinitPlr(plr: Player) {
+ let uId = plr.UserId;
+ // backup to datastore or something goes here
+ delete p[uId];
+ print(plr.Name + "has deinitiallized successfully.");
+}
+
+plrs.PlayerAdded.Connect(initPlr);
+plrs.PlayerRemoving.Connect(deinitPlr);
+
+// Initialization Complete. //
+
+/* May not be readded since PvP may be available on the arena if no PvE event is ongoing
+function playerZone(plr) //Locate where the player is on the map
+ local chr = plr.Character
+ if chr then
+ local root = chr:FindFirstChild("HumanoidRootPart")
+ if root and root.Position.Y < -2056 then
+ return "Outside"
+ elseif root and root.Position.Y <= -1024 then
+ return "Plateau"
+ end
+ end
+ return "Spawn"
+end
+*/
+//////////////////////////////////-
+
+// Character Variables //
+
+//////////////////////////////////-
+// Functions used when setting up the character
+// Get joints should be a different function (on the client)
+function getParts(uId: number) { // You need to make sure and check how the instances compile (1 instead of 0?)
+ let plr = plrs.GetPlayerByUserId(uId)
+ if (plr) {
+ // Get the character
+ let chr = plr.Character;
+ while (!chr) {
+ chr = plr.Character;
+ wait();
+ }
+ // Humanoid
+ let hum = chr.WaitForChild("Humanoid") as Humanoid;
+ // Body Parts
+ let root = chr.WaitForChild("Root") as Part;
+ let torso = chr.WaitForChild("Torso") as Part;
+ let head = chr.WaitForChild("Head") as Part;
+ let lArm = chr.WaitForChild("Left Arm") as Part;
+ let rArm = chr.WaitForChild("Right Arm") as Part;
+ let lLeg = chr.WaitForChild("Left Leg") as Part;
+ let rLeg = chr.WaitForChild("Right Leg") as Part;
+ let newParts: [undefined?, Model, Humanoid, Part, Part, Part, Part, Part, Part, Part] = [undefined, chr, hum, root, torso, head, lArm, rArm, lLeg, rLeg];
+ return newParts;
+ }
+}
+
+function makeWings(parts: [undefined?, Model, Humanoid, Part, Part, Part, Part, Part, Part, Part]) { // Make the core, true wings, etc.
+ // Decor model - Parent of all of the visible wings + the core
+ let adds = new inst("Folder");
+ adds.Name = "Decor";
+ // Wing folder - I seriously don't know how I (or birdmaid, god bless their soul) lived without table wings before
+ let iWingsFolder = new inst("Folder");
+ iWingsFolder.Name = "Wings";
+ let iWings: Part[][] = []; // The "true" wings (tiny invisible parts), which are animated by the client
+ // Central part + its weld
+ let cWPart = newPart(iWingsFolder, rgb(0,0,0), neon, 1, false, false, new v3(0.1,0.1,0.1)); // The center of the wings (and the core).
+ cWPart.Name = "CWPart";
+ weld("CoreWeld", cWPart, undefined, zF, zF);
+ let mainWeld = weld("MainWeld", parts[4] as Part, cWPart, new cF(0,1.5,1.05), new cF(0,0,0));
+ // Make the wing parts, put them in the table, and weld them
+ for (let j = 1; j <= 2; j += 1) {
+ iWings[j] = []
+ for (let i = 1; i <= 6; i += 1) {
+ iWings[j][i] = newPart(iWingsFolder, rgb(0,0,0), neon, 1, false, false, new v3(0.1,0.1,0.1));
+ weld((tS(j) + "_" + tS(i)),cWPart,iWings[j][i],zF,zF);
+ weld("WingWeld", iWings[j][i], undefined, zF, zF);
+ }
+ }
+ // Finalize
+ let chr = parts[1]
+ adds.Parent = chr;
+ iWingsFolder.Parent = chr;
+ // Assign to table and return
+ let wings: [undefined?, Folder, Part[][], Part] = [undefined, adds, iWings, cWPart];
+ return wings;
+}
+
+let wingFolder = storage.WaitForChild("WingFolder") as Folder // Temporary
+function makeDecor(wings: [undefined?, Folder, Part[][], Part], wing: string,core: string) { // Make the actual visible wings (This will take arguments pulled from a table about the set's intended wings later on, and wing alternates will be a thing)
+ wings[1].ClearAllChildren()
+ // Make the visible wings
+ let wingModel = wingFolder.FindFirstChild(wing)
+ assert(wingModel,"Server: Wing " + wing + " not found!")
+ for (let j = 1; j <= 2; j++) {
+ let theseIWings = wings[2][j];
+ for (let i = 1; i <= 6; i++) {
+ let thisWing = wingModel.Clone() as wingModelType;
+ thisWing.Name = tS(j) + "_" + tS(i);
+ thisWing.M.Size = thisWing.M.Size.mul(0.5 + ceil(i/3)/2); // Wings 4 to 6 get enlarged (I have decided that this objectively just looks cooler)
+ thisWing.Parent = wings[1];
+ // Weld the visible wings to the invisible wings
+ let wingWeld = theseIWings[i].FindFirstChild("WingWeld") as Motor6D | undefined;
+ assert(wingWeld, "Server: WingWeld of wing " + thisWing.Name + " not found!");
+ wingWeld.Part1 = thisWing.M;
+ }
+ }
+ // Make the visible core
+ let coreModel = wingFolder.FindFirstChild(core)
+ assert(coreModel,"Server: Core " + core + " not found!")
+ let thisCore = coreModel.Clone() as wingModelType
+ thisCore.Name = "Core"
+ thisCore.Parent = wings[1]
+ // Weld the visible core the cWPart
+ let coreWeld = wings[3].FindFirstChild("CoreWeld") as Motor6D | undefined;
+ assert(coreWeld, "Server: CoreWeld of core not found!");
+ coreWeld.Part1 = thisCore.M;
+}
+
+function makeBGui() {
+ let gui = new inst("BillboardGui")//game.ServerStorage.StarG:Clone()
+ //gui.Parent = p[uId].Parts[1]
+ //gui.Adornee = p[uId].Parts[4]
+ BGui[1] = gui
+ BGui[2] = gui.Title
+ BGui[3] = gui.Extra
+ BGui[4] = {} //Parts of the gui to be recolored to the primary color
+ BGui[5] = {} //Parts of the gui to be recolored to the secondary color
+ for i, v in pairs(gui:GetDescendants()) do //Sort the rest of the GUI into these tables
+ local startLetter = sub(v.Name,1,1)
+ if startLetter == "p" then
+ insert(BGui[4],v)
+ elseif startLetter == "s" then
+ insert(BGui[5],v)
+ end
+ end
+}
+
+function setUp(Plr: Player)
+ /*
+ Chr = plr.Character
+ repeat
+ pcall(getParts)
+ wait()
+ until Torso and RootJoint
+ Hum = Chr.Humanoid
+ Hum.MaxHealth = 200
+ Hum.Health = 200
+ */
+ if (Chr) {
+ Plr = plrFromChr(plrs,Chr)
+ } else {
+ do {
+ Chr = Plr.Character
+ wait()
+ }
+ while (!Chr);
+ }
+ let uId = Plr.UserId
+ getParts(Plr,Chr)
+ MakeDecor(uId)
+ GrabWings(uId,"StarWing","Ring",unpack(p[uId].Decor))
+ GiveGui(uId)
+ wait()
+ StandardTransform(Plr,1,"QQ")
+ wait(1)
+ StandardTransform(Plr,1,"QQ",nil,true)
+ Output:FireClient(Plr,"SideColors",sideColorTable("Star",1))
+ //waitForLeaveSpawn()
+end
+
+//Mode switching functions
+//local TT = {}
+wsti = TweenInfo.new(0.75)
+
+function tweenRecolor(Decor,TT,coloraffected,count,colors,materials) //Recolor, show and hide wings using the power of tweens
+ local Adds = Decor[1]
+ local CWings = Decor[3]
+ local VWings = Decor[8]
+ local Core = Decor[10][1]
+ for j = 1, 2 do
+ for i = 1, 6 do
+ local GM = {} //the goal tables used in the tweens
+ local GMless = {}
+ local GS = {}
+ local num = nil
+ if i <= count[j] then //wings that should be shown
+ num = 0
+ if not coloraffected or i > coloraffected[j][2] or i < coloraffected[j][1] then //Ignore recoloring if the client is supposed to take over
+ GM.Color = colors[j][i]
+ GMless.Color = colors[j][i]
+ GS.Color = colors["d"]
+ end
+ //VWings[j][i].M.Material = colors["m"][1] //almost forgot that you can't tween materials
+ pcall(function()
+ VWings[j][i].S.Material = colors["m"][2]
+ end)
+ VWings[j][i].M.Color = VWings[j][i].M.Color
+ VWings[j][i].Trail.Color = ColorSequence.new(colors[j][1])
+ VWings[j][i].M.Light.Enabled = true
+ else //wings to hide
+ num = 1
+ spawn(function()
+ wait(wsti.Time)
+ VWings[j][i].M.Light.Enabled = false
+ end)
+ end
+ GM.Transparency = num
+ GS.Transparency = num
+ GMless.Brightness = 0.25-num/4
+ VWings[j][i].Trail.Transparency = NumberSequence.new(num,1)
+ insert(TT,tweenServiceCreate(twS,VWings[j][i].M,wsti,GM))
+ insert(TT,tweenServiceCreate(twS,VWings[j][i].M.Light,wsti,GMless))
+ VWings[j][i].M.Material = materials[j][i]
+ pcall(function()
+ insert(TT,tweenServiceCreate(twS,VWings[j][i].S,wsti,GS))
+ end)
+ end
+ end
+
+ local GCE = {} //core extra
+
+ if not coloraffected then //Ignore if the client is supposed to take over
+ local GC = {Color = colors.core[1]} //core
+ GCE.Color = colors[1][4]
+
+ Core.Extra.Material = materials[1][4]
+
+ insert(TT,tweenServiceCreate(twS,Core.Main,wsti,GC))
+
+ insert(TT,tweenServiceCreate(twS,Core.Main.Light,wsti,GC))
+ end
+
+ if count[1] < 6 or count[2] < 6 then
+ GCE["Transparency"] = 1
+ else
+ GCE["Transparency"] = 0
+ end
+ insert(TT,tweenServiceCreate(twS,Core.Extra,wsti,GCE))
+end
+
+function recolorBasedOnClass(item,color,color2)
+ local class = item.ClassName
+ if class == "Frame" then
+ item.BackgroundColor3 = color
+ elseif class == "ImageLabel" then
+ item.ImageColor3 = color
+ elseif class == "TextLabel" then
+ item.TextColor3 = color
+ item.TextStrokeColor3 = color2
+ end
+end
+
+function returnTableBasedOnClass(item,color,color2)
+ local class = item.ClassName
+ if class == "Frame" then
+ return {BackgroundColor3 = color}
+ elseif class == "ImageLabel" then
+ return {ImageColor3 = color}
+ elseif class == "TextLabel" then
+ return {TextColor3 = color, TextStrokeColor3 = color2}
+ end
+end
+
+function nameChange(BGui,TT,Head,coloreffect,one, two, text, font,extra) //This one doesn't really need an explanation
+ local gui = BGui[1]
+ local nem = BGui[2]
+ local extr = BGui[3]
+ nem.Text = text
+ nem.Font = font
+ if not coloreffect then
+ local GT = {}
+ GT.TextColor3 = one
+ GT.TextStrokeColor3 = two
+ insert(TT,tweenServiceCreate(twS,nem,wsti,GT))
+ for i, v in pairs(BGui[4]) do //Recolor the extra components (primary)
+ insert(TT,tweenServiceCreate(twS,v,wsti,returnTableBasedOnClass(v,one,two)))//recolorBasedOnClass(v,one,two)
+ end
+ for i, v in pairs(BGui[5]) do //Recolor the extra components (secondary)
+ insert(TT,tweenServiceCreate(twS,v,wsti,returnTableBasedOnClass(v,two,one)))//recolorBasedOnClass(v,two,one)
+ end
+ end
+ if extra then
+ extr.Text = extra
+ extr.Color = one//extr.g.Color = ColorSequence.new({ColorSequenceKeypoint.new(0,two),ColorSequenceKeypoint.new(0.5,one),ColorSequenceKeypoint.new(1,two)})
+ extr.Visible = true
+ else
+ extr.Visible = false
+ end
+end
+
+function checkForMove(set,side,mode,inp)
+ local sane = nil
+ pcall(function()
+ sane = Abilties[inp][set][side][mode]
+ end)
+ return sane
+end
+
+
+function StandardTransform(Plr,side,mod,sub,override) //I wouldn't call this spaghetti but it probably is damn hard to read
+ //Reads a mode and calls nameChange and tweenRecolor as well as doing some other basic stuff
+ local guh = p[Plr.UserId]
+ local set = guh.Set
+ if side ~= guh.Side or mod ~= guh.Mode or sub or override then
+
+ if sub then //the idea of appending the sub key to the current mode is originally gun's idea
+ mod = mod .. sub
+ end
+
+ local modeTable = Modes[set][side][mod]
+
+ if modeTable then //make sure the mode actually exists
+ guh.CDA = false
+ guh.modeTable = modeTable
+
+ for i, v in pairs(guh.Tweens) do
+ v:Pause()
+ v:Destroy()
+ end
+ //print(test)
+ guh.Tweens = {}
+ if side ~= guh.Side then
+ Output:FireClient(Plr,"SideColors",sideColorTable(set,side))
+ end
+ guh.Side, guh.Mode = side, mod
+
+ //Recolor the billboard GUI
+ local text = modeTable.name
+ if modeTable.tag[1] then //make the name uppercase
+ text = string.upper(text)
+ end
+ nameChange(guh.BGui,guh.Tweens,guh.Parts[1],modeTable.coloreffect or nil, modeTable.tag[2], modeTable.tag[3], text, modeTable.tag[4])
+
+ //Deal with stats like walkspeed and hover height
+ local Hum = guh.Parts[2]
+ Hum.WalkSpeed = modeTable.ws
+ Hum.HipHeight = modeTable.height or 0
+ //storedWalkSpeed = modeTable[7]
+
+ //Recolor the wings
+ local wc = modeTable.wingc
+ //{{table for left wings}, {table for right wings}, d = detailing color, m = {material (default neon), detailing material (default glass)}, ring = ring color (default main wing color)}
+ local colores = {{},{},d = wc.d,m = {wc.m or neon, wc.dm or Enum.Material.Glass}, ring = wc.ring or wc.L1} //yeah this table is unreadable
+ local materials = {{wc["ML1"] or neon},{wc["MR1"] or neon}}
+ colores[1][1] = wc.L1 //This is the only wing color that is explicitly required, every other one will default to this
+ colores[2][1] = wc.R1 or wc.L1 //See?
+ for j = 1, 2 do //Give every other wing either the designated color or the color of the previous wing
+ local l = (j == 1 and "L") or "R"
+ for i = 2, 6 do
+ colores[j][i] = wc[l .. tSt(i)] or colores[j][i-1]
+ materials[j][i] = wc["M" .. l .. tSt(i)] or materials[j][i-1]
+ end
+ end
+ colores.core = {wc.core or colores[1][1]}
+
+ tweenRecolor(guh.Decor,guh.Tweens,modeTable.coloraffected or nil,{wc.left,wc.right},colores,materials)
+
+ local localTable = localModeTable(modeTable)
+ guh.StoredModeInfo = localTable
+ Output:FireAllClients("ModeChange",Plr.UserId,localTable)
+ //wait(1)
+ for i, v in pairs(guh.Tweens) do
+ v:Play()
+ end
+ guh.CDA = true
+
+ //Give all of the other data to the client
+
+ local mE = guh.MovesExist
+ local mEC = {}
+ for i, inp in pairs(abilityKeys) do
+ mE[inp] = checkForMove(set,side,mod,inp)
+ //if mE[inp] then
+ //print("Got move for " .. inp)
+ //print(mE[inp])
+ //end
+ mEC[inp] = toboolean(mE[inp])
+ end
+ Output:FireClient(Plr,"MovesExist",mEC,set,side,mod,modeTable.main)
+ end
+ end
+end
+
+// Attacks //
+
+wlist = Enum.RaycastFilterType.Whitelist
+blist = Enum.RaycastFilterType.Blacklist
+function CastRay(start,ende,list,listype)
+ local params = RaycastParams.new()
+ params.FilterDescendantsInstances = list
+ params.FilterType = listype
+ return workspace:Raycast(start,ende-start,params)
+end
+
+function checkCoolDowns(cd,inp,Set,Side,Mode)
+ local now = floorToBase(clock(),10)
+ for i, v in pairs(cd) do
+ if now > v[1] + v[2] then
+ cd[i] = nil
+ end
+ end
+end
+/*
+function reg3HitBox(Chr,siz,pos)
+ local realsize = v3(math.ceil(siz.X*0.25)*4,math.ceil(siz.Y*0.25)*4,math.ceil(siz.Z*0.25)*4)
+
+ local reg3 = Region3.new(pos-realsize*0.5,pos+realsize*0.5)
+ local results = workspace:FindPartsInRegion3WithIgnoreList(reg3,{Chr,game.Workspace.Map},64)
+ local tosend = {}
+ for i, v in pairs(results) do
+ if v.Parent:FindFirstChild("Humanoid") then
+ if not plrs:GetPlayerFromCharacter(v.Parent) or (plrs:GetPlayerFromCharacter(v.Parent).Pvp.Value == true and Pvp.Value == true) then
+ insert(tosend,v)
+ end
+ end
+ end
+ return tosend
+end
+
+function hitSphere(rad,pos,damage,effect,pass)
+ local res = reg3HitBox(v3(rad*2,rad*2,rad*2),pos)
+ local done = {}
+ for i, v in pairs(res) do
+ if not tFind(done,v.Parent) then
+ if (v.Position-pos).Magnitude < rad then
+ insert(done,v.Parent)
+ v.Parent:FindFirstChild("Humanoid"):TakeDamage(damage)
+ end
+ end
+ end
+ return (done[1] and done) or nil //DONE AND DONE
+end
+
+function clickAttackNumberFunction()
+ clickAttackNumber = (clickAttackNumber == 3 and 1) or clickAttackNumber+1
+ local ostime = os.time()+ rand
+ print(ostime)
+ clickAttackNumberFunctionStoredNumber = ostime
+ wait(0.5)
+ if ostime == clickAttackNumberFunctionStoredNumber then
+ clickAttackNumber = 1
+ end
+end
+*/
+
+Input.OnServerEvent:Connect(function(plr,typ,inp,pos,norm,targ)
+ //print(inp)
+ local uId = plr.UserId
+ local guh = p[uId]
+
+ mouseData[uId] = {pos or mouseData[uId][1],norm or mouseData[uId][2],targ or mouseData[uId][3]}
+ pos, norm, targ = unpack(mouseData[uId])
+ if type(inp) ~= "string" then
+ Update:Fire("MouseResponse",uId,mouseData[uId])
+ return
+ end
+
+ if typ == "Message" then
+ print(inp)
+ elseif typ == "PBL" then
+ guh.PBL.Value = inp
+ elseif typ == "Input" and guh.CDA then //regular attacks
+
+ if inp == "click" then
+ if playerZone(plr) == "Spawn" then
+ Output:FireClient(plr,"Notify","Abilities cannot be used at spawn.")
+ else
+ //Check if click attack should be reverted to 1 (too long ago/out of bounds)
+ local cd = guh.ClickAttack
+ local now = floorToBase(clock(),10)
+ if now - cd[2] > 0.5 or cd[1] == 4 then
+ cd[1] = 1
+ end
+
+ //Click Attack
+ Output:FireAllClients("Attack",uId,"Click",guh.Set,cd[1])
+ guh.CDA = false
+ Abilties["Click"][guh.Set][cd[1*/(plr,pvp,pos, norm, targ,unpack(guh.Parts))
+
+ //Finish
+ cd[1] += 1
+ cd[2] = floorToBase(clock(),10)
+ guh.CDA = true
+ end
+ elseif tFind(abilityKeys,inp) then
+ if playerZone(plr) == "Spawn" then
+ Output:FireClient(plr,"Notify","Abilities cannot be used at spawn.")
+ else
+ local coolDown = guh.CoolDown
+ local Set = guh.Set
+ local Side = guh.Side
+ local Mode = guh.Mode
+ //print(tostring(inp))
+ //inp = sub(tSt(inp),14)
+ checkCoolDowns(coolDown,inp,Set,Side,Mode)
+ if not coolDown.Main and not coolDown[inp] and not coolDown[Set .. Side .. Mode .. inp] then
+
+ local move = guh.MovesExist[inp]
+ //print(inp)
+ //for i,v in pairs(guh.MovesExist) do
+ // print(i)
+ //end
+ print(move)
+ if not move then
+ return
+ end
+
+ Output:FireAllClients("Attack",uId,inp,Set,Side,Mode)
+ guh.CDA = false
+ local cool = move(plr,pvp,guh.Gyro,pos,norm,targ,unpack(guh.Parts))
+ //local cool = sane(plr,pvp,pos, norm, targ,unpack(guh.Parts))//Chr,Root,Pos,Norm,Target)
+
+ //cooldown
+ local now = floorToBase(clock(),10)
+ Output:FireClient(plr,"Cooldown",cool,inp,Set,Side,Mode)
+ coolDown.Main = {now,cool}
+ coolDown[inp] = {now,cool*3}
+ coolDown[Set .. Side .. Mode .. inp] = {now,cool*9}
+ guh.CDA = true
+ end
+ end
+ elseif tFind(modeKeys,sub(inp,1,1)) and tFind(modeKeys,sub(inp,2)) then
+ //inp = sub(tSt(inp),14)
+ StandardTransform(plr,guh.Side,inp)
+ elseif tFind(subModeKeys,inp) then
+ //inp = sub(tSt(inp),14)
+ StandardTransform(plr,guh.Side,guh.Mode,inp)
+ elseif tFind(sideKeys,inp) then
+ StandardTransform(plr,tFind(sideKeys,inp),"QQ")
+ end
+ end
+
+end)
diff --git a/src/services.d.ts b/src/services.d.ts
new file mode 100644
index 0000000..5d13919
--- /dev/null
+++ b/src/services.d.ts
@@ -0,0 +1,52 @@
+interface emitterTable {
+ parent: Instance;
+ color: ColorSequence;
+ lightE?: number;
+ lightI?: number;
+ size: NumberSequence;
+ texture: string;
+ transparency: NumberSequence;
+ drag?: number;
+ locked: boolean;
+ lifetime: NumberRange;
+ rate: number;
+ rotation?: NumberRange;
+ rotSpeed?: NumberRange;
+ speed: NumberRange;
+ spread?: Vector2;
+}
+interface Workspace extends Instance {
+ Effects: Folder;
+ Enemies: Folder;
+}
+interface ReplicatedStorage extends Instance {
+ Remotes: Folder & {
+ Input: RemoteEvent;
+ Output: RemoteEvent;
+ };
+ Meshpile: Folder;
+}
+interface wingModelType extends Model {
+ M: MeshPart;
+ S: MeshPart;
+}
+interface Player extends Instance {
+ PlayerGui: PlayerGui;
+}
+interface Character extends Model {
+ HumanoidRootPart: Part & {
+ RootJoint: Motor6D;
+ };
+ Torso: Part & {
+ Neck: Motor6D;
+ ["Left Shoulder"]: Motor6D;
+ ["Right Shoulder"]: Motor6D;
+ ["Left Hip"]: Motor6D;
+ ["Right Hip"]: Motor6D;
+ };
+ Head: Part;
+ ["Left Arm"]: Part;
+ ["Right Arm"]: Part;
+ ["Left Leg"]: Part;
+ ["Right Leg"]: Part;
+}
diff --git a/src/shared/module.ts b/src/shared/module.ts
new file mode 100644
index 0000000..68a26bf
--- /dev/null
+++ b/src/shared/module.ts
@@ -0,0 +1,3 @@
+export function makeHello(name: string) {
+ return `Hello from ${name}!`;
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..c2f8e14
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ // required
+ "allowSyntheticDefaultImports": true,
+ "downlevelIteration": true,
+ "jsx": "react",
+ "jsxFactory": "Roact.createElement",
+ "jsxFragmentFactory": "Roact.Fragment",
+ "module": "commonjs",
+ "moduleResolution": "Node",
+ "noLib": true,
+ "resolveJsonModule": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "target": "ESNext",
+ "typeRoots": ["node_modules/@rbxts"],
+
+ // configurable
+ "rootDir": "src",
+ "outDir": "out",
+ "baseUrl": "src",
+ "incremental": true,
+ "tsBuildInfoFile": "out/tsconfig.tsbuildinfo"
+ }
+}