Advertisement
UpdateHub

Untitled

May 31st, 2023
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 407.38 KB | None | 0 0
  1. -- https://github.com/LorekeeperZinnia/Dex
  2.  
  3. --[[
  4. New Dex
  5. Final Version
  6. Developed by Moon
  7. Modified for Infinite Yield
  8.  
  9. Dex is a debugging suite designed to help the user debug games and find any potential vulnerabilities.
  10.  
  11. This is the final version of this script.
  12. You are encouraged to edit, fork, do whatever with this. I pretty much won't be updating it anymore.
  13. Though I would appreciate it if you kept the credits in the script if you enjoy this hard work.
  14.  
  15. If you want more info, you can join the server: https://discord.io/zinnia
  16. Note that very limited to no support will be provided.
  17. ]]
  18.  
  19. local nodes = {}
  20. local selection
  21. local clonerefs = cloneref or function(...) return ... end
  22.  
  23. local EmbeddedModules = {
  24. Explorer = function()
  25. --[[
  26. Explorer App Module
  27.  
  28. The main explorer interface
  29. ]]
  30.  
  31. -- Common Locals
  32. local Main,Lib,Apps,Settings -- Main Containers
  33. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  34. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  35.  
  36. local function initDeps(data)
  37. Main = data.Main
  38. Lib = data.Lib
  39. Apps = data.Apps
  40. Settings = data.Settings
  41.  
  42. API = data.API
  43. RMD = data.RMD
  44. env = data.env
  45. service = data.service
  46. plr = data.plr
  47. create = data.create
  48. createSimple = data.createSimple
  49. end
  50.  
  51. local function initAfterMain()
  52. Explorer = Apps.Explorer
  53. Properties = Apps.Properties
  54. ScriptViewer = Apps.ScriptViewer
  55. Notebook = Apps.Notebook
  56. end
  57.  
  58. local function main()
  59. local Explorer = {}
  60. local tree,listEntries,explorerOrders,searchResults,specResults = {},{},{},{},{}
  61. local expanded
  62. local entryTemplate,treeFrame,toolBar,descendantAddedCon,descendantRemovingCon,itemChangedCon
  63. local ffa = game.FindFirstAncestorWhichIsA
  64. local getDescendants = game.GetDescendants
  65. local getTextSize = service.TextService.GetTextSize
  66. local updateDebounce,refreshDebounce = false,false
  67. local nilNode = {Obj = Instance.new("Folder")}
  68. local idCounter = 0
  69. local scrollV,scrollH,clipboard
  70. local renameBox,renamingNode,searchFunc
  71. local sortingEnabled,autoUpdateSearch
  72. local table,math = table,math
  73. local nilMap,nilCons = {},{}
  74. local connectSignal = game.DescendantAdded.Connect
  75. local addObject,removeObject,moveObject = nil,nil,nil
  76.  
  77. addObject = function(root)
  78. if nodes[root] then return end
  79.  
  80. local isNil = false
  81. local rootParObj = ffa(root,"Instance")
  82. local par = nodes[rootParObj]
  83.  
  84. -- Nil Handling
  85. if not par then
  86. if nilMap[root] then
  87. nilCons[root] = nilCons[root] or {
  88. connectSignal(root.ChildAdded,addObject),
  89. connectSignal(root.AncestryChanged,moveObject),
  90. }
  91. par = nilNode
  92. isNil = true
  93. else
  94. return
  95. end
  96. elseif nilMap[rootParObj] or par == nilNode then
  97. nilMap[root] = true
  98. nilCons[root] = nilCons[root] or {
  99. connectSignal(root.ChildAdded,addObject),
  100. connectSignal(root.AncestryChanged,moveObject),
  101. }
  102. isNil = true
  103. end
  104.  
  105. local newNode = {Obj = root, Parent = par}
  106. nodes[root] = newNode
  107.  
  108. -- Automatic sorting if expanded
  109. if sortingEnabled and expanded[par] and par.Sorted then
  110. local left,right = 1,#par
  111. local floor = math.floor
  112. local sorter = Explorer.NodeSorter
  113. local pos = (right == 0 and 1)
  114.  
  115. if not pos then
  116. while true do
  117. if left >= right then
  118. if sorter(newNode,par[left]) then
  119. pos = left
  120. else
  121. pos = left+1
  122. end
  123. break
  124. end
  125.  
  126. local mid = floor((left+right)/2)
  127. if sorter(newNode,par[mid]) then
  128. right = mid-1
  129. else
  130. left = mid+1
  131. end
  132. end
  133. end
  134.  
  135. table.insert(par,pos,newNode)
  136. else
  137. par[#par+1] = newNode
  138. par.Sorted = nil
  139. end
  140.  
  141. local insts = getDescendants(root)
  142. for i = 1,#insts do
  143. local obj = insts[i]
  144. if nodes[obj] then continue end -- Deferred
  145.  
  146. local par = nodes[ffa(obj,"Instance")]
  147. if not par then continue end
  148. local newNode = {Obj = obj, Parent = par}
  149. nodes[obj] = newNode
  150. par[#par+1] = newNode
  151.  
  152. -- Nil Handling
  153. if isNil then
  154. nilMap[obj] = true
  155. nilCons[obj] = nilCons[obj] or {
  156. connectSignal(obj.ChildAdded,addObject),
  157. connectSignal(obj.AncestryChanged,moveObject),
  158. }
  159. end
  160. end
  161.  
  162. if searchFunc and autoUpdateSearch then
  163. searchFunc({newNode})
  164. end
  165.  
  166. if not updateDebounce and Explorer.IsNodeVisible(par) then
  167. if expanded[par] then
  168. Explorer.PerformUpdate()
  169. elseif not refreshDebounce then
  170. Explorer.PerformRefresh()
  171. end
  172. end
  173. end
  174.  
  175. removeObject = function(root)
  176. local node = nodes[root]
  177. if not node then return end
  178.  
  179. -- Nil Handling
  180. if nilMap[node.Obj] then
  181. moveObject(node.Obj)
  182. return
  183. end
  184.  
  185. local par = node.Parent
  186. if par then
  187. par.HasDel = true
  188. end
  189.  
  190. local function recur(root)
  191. for i = 1,#root do
  192. local node = root[i]
  193. if not node.Del then
  194. nodes[node.Obj] = nil
  195. if #node > 0 then recur(node) end
  196. end
  197. end
  198. end
  199. recur(node)
  200. node.Del = true
  201. nodes[root] = nil
  202.  
  203. if par and not updateDebounce and Explorer.IsNodeVisible(par) then
  204. if expanded[par] then
  205. Explorer.PerformUpdate()
  206. elseif not refreshDebounce then
  207. Explorer.PerformRefresh()
  208. end
  209. end
  210. end
  211.  
  212. moveObject = function(obj)
  213. local node = nodes[obj]
  214. if not node then return end
  215.  
  216. local oldPar = node.Parent
  217. local newPar = nodes[ffa(obj,"Instance")]
  218. if oldPar == newPar then return end
  219.  
  220. -- Nil Handling
  221. if not newPar then
  222. if nilMap[obj] then
  223. newPar = nilNode
  224. else
  225. return
  226. end
  227. elseif nilMap[newPar.Obj] or newPar == nilNode then
  228. nilMap[obj] = true
  229. nilCons[obj] = nilCons[obj] or {
  230. connectSignal(obj.ChildAdded,addObject),
  231. connectSignal(obj.AncestryChanged,moveObject),
  232. }
  233. end
  234.  
  235. if oldPar then
  236. local parPos = table.find(oldPar,node)
  237. if parPos then table.remove(oldPar,parPos) end
  238. end
  239.  
  240. node.Id = nil
  241. node.Parent = newPar
  242.  
  243. if sortingEnabled and expanded[newPar] and newPar.Sorted then
  244. local left,right = 1,#newPar
  245. local floor = math.floor
  246. local sorter = Explorer.NodeSorter
  247. local pos = (right == 0 and 1)
  248.  
  249. if not pos then
  250. while true do
  251. if left >= right then
  252. if sorter(node,newPar[left]) then
  253. pos = left
  254. else
  255. pos = left+1
  256. end
  257. break
  258. end
  259.  
  260. local mid = floor((left+right)/2)
  261. if sorter(node,newPar[mid]) then
  262. right = mid-1
  263. else
  264. left = mid+1
  265. end
  266. end
  267. end
  268.  
  269. table.insert(newPar,pos,node)
  270. else
  271. newPar[#newPar+1] = node
  272. newPar.Sorted = nil
  273. end
  274.  
  275. if searchFunc and searchResults[node] then
  276. local currentNode = node.Parent
  277. while currentNode and (not searchResults[currentNode] or expanded[currentNode] == 0) do
  278. expanded[currentNode] = true
  279. searchResults[currentNode] = true
  280. currentNode = currentNode.Parent
  281. end
  282. end
  283.  
  284. if not updateDebounce and (Explorer.IsNodeVisible(newPar) or Explorer.IsNodeVisible(oldPar)) then
  285. if expanded[newPar] or expanded[oldPar] then
  286. Explorer.PerformUpdate()
  287. elseif not refreshDebounce then
  288. Explorer.PerformRefresh()
  289. end
  290. end
  291. end
  292.  
  293. Explorer.ViewWidth = 0
  294. Explorer.Index = 0
  295. Explorer.EntryIndent = 20
  296. Explorer.FreeWidth = 32
  297. Explorer.GuiElems = {}
  298.  
  299. Explorer.InitRenameBox = function()
  300. renameBox = create({{1,"TextBox",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.062745101749897,0.51764708757401,1),BorderMode=2,ClearTextOnFocus=false,Font=3,Name="RenameBox",PlaceholderColor3=Color3.new(0.69803923368454,0.69803923368454,0.69803923368454),Position=UDim2.new(0,26,0,2),Size=UDim2.new(0,200,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,Visible=false,ZIndex=2}}})
  301.  
  302. renameBox.Parent = Explorer.Window.GuiElems.Content.List
  303.  
  304. renameBox.FocusLost:Connect(function()
  305. if not renamingNode then return end
  306.  
  307. pcall(function() renamingNode.Obj.Name = renameBox.Text end)
  308. renamingNode = nil
  309. Explorer.Refresh()
  310. end)
  311.  
  312. renameBox.Focused:Connect(function()
  313. renameBox.SelectionStart = 1
  314. renameBox.CursorPosition = #renameBox.Text + 1
  315. end)
  316. end
  317.  
  318. Explorer.SetRenamingNode = function(node)
  319. renamingNode = node
  320. renameBox.Text = tostring(node.Obj)
  321. renameBox:CaptureFocus()
  322. Explorer.Refresh()
  323. end
  324.  
  325. Explorer.SetSortingEnabled = function(val)
  326. sortingEnabled = val
  327. Settings.Explorer.Sorting = val
  328. end
  329.  
  330. Explorer.UpdateView = function()
  331. local maxNodes = math.ceil(treeFrame.AbsoluteSize.Y / 20)
  332. local maxX = treeFrame.AbsoluteSize.X
  333. local totalWidth = Explorer.ViewWidth + Explorer.FreeWidth
  334.  
  335. scrollV.VisibleSpace = maxNodes
  336. scrollV.TotalSpace = #tree + 1
  337. scrollH.VisibleSpace = maxX
  338. scrollH.TotalSpace = totalWidth
  339.  
  340. scrollV.Gui.Visible = #tree + 1 > maxNodes
  341. scrollH.Gui.Visible = totalWidth > maxX
  342.  
  343. local oldSize = treeFrame.Size
  344. treeFrame.Size = UDim2.new(1,(scrollV.Gui.Visible and -16 or 0),1,(scrollH.Gui.Visible and -39 or -23))
  345. if oldSize ~= treeFrame.Size then
  346. Explorer.UpdateView()
  347. else
  348. scrollV:Update()
  349. scrollH:Update()
  350.  
  351. renameBox.Size = UDim2.new(0,maxX-100,0,16)
  352.  
  353. if scrollV.Gui.Visible and scrollH.Gui.Visible then
  354. scrollV.Gui.Size = UDim2.new(0,16,1,-39)
  355. scrollH.Gui.Size = UDim2.new(1,-16,0,16)
  356. Explorer.Window.GuiElems.Content.ScrollCorner.Visible = true
  357. else
  358. scrollV.Gui.Size = UDim2.new(0,16,1,-23)
  359. scrollH.Gui.Size = UDim2.new(1,0,0,16)
  360. Explorer.Window.GuiElems.Content.ScrollCorner.Visible = false
  361. end
  362.  
  363. Explorer.Index = scrollV.Index
  364. end
  365. end
  366.  
  367. Explorer.NodeSorter = function(a,b)
  368. if a.Del or b.Del then return false end -- Ghost node
  369.  
  370. local aClass = a.Class
  371. local bClass = b.Class
  372. if not aClass then aClass = a.Obj.ClassName a.Class = aClass end
  373. if not bClass then bClass = b.Obj.ClassName b.Class = bClass end
  374.  
  375. local aOrder = explorerOrders[aClass]
  376. local bOrder = explorerOrders[bClass]
  377. if not aOrder then aOrder = RMD.Classes[aClass] and tonumber(RMD.Classes[aClass].ExplorerOrder) or 9999 explorerOrders[aClass] = aOrder end
  378. if not bOrder then bOrder = RMD.Classes[bClass] and tonumber(RMD.Classes[bClass].ExplorerOrder) or 9999 explorerOrders[bClass] = bOrder end
  379.  
  380. if aOrder ~= bOrder then
  381. return aOrder < bOrder
  382. else
  383. local aName,bName = tostring(a.Obj),tostring(b.Obj)
  384. if aName ~= bName then
  385. return aName < bName
  386. elseif aClass ~= bClass then
  387. return aClass < bClass
  388. else
  389. local aId = a.Id if not aId then aId = idCounter idCounter = (idCounter+0.001)%999999999 a.Id = aId end
  390. local bId = b.Id if not bId then bId = idCounter idCounter = (idCounter+0.001)%999999999 b.Id = bId end
  391. return aId < bId
  392. end
  393. end
  394. end
  395.  
  396. Explorer.Update = function()
  397. table.clear(tree)
  398. local maxNameWidth,maxDepth,count = 0,1,1
  399. local nameCache = {}
  400. local font = Enum.Font.SourceSans
  401. local size = Vector2.new(math.huge,20)
  402. local useNameWidth = Settings.Explorer.UseNameWidth
  403. local tSort = table.sort
  404. local sortFunc = Explorer.NodeSorter
  405. local isSearching = (expanded == Explorer.SearchExpanded)
  406. local textServ = service.TextService
  407.  
  408. local function recur(root,depth)
  409. if depth > maxDepth then maxDepth = depth end
  410. depth = depth + 1
  411. if sortingEnabled and not root.Sorted then
  412. tSort(root,sortFunc)
  413. root.Sorted = true
  414. end
  415. for i = 1,#root do
  416. local n = root[i]
  417.  
  418. if (isSearching and not searchResults[n]) or n.Del then continue end
  419.  
  420. if useNameWidth then
  421. local nameWidth = n.NameWidth
  422. if not nameWidth then
  423. local objName = tostring(n.Obj)
  424. nameWidth = nameCache[objName]
  425. if not nameWidth then
  426. nameWidth = getTextSize(textServ,objName,14,font,size).X
  427. nameCache[objName] = nameWidth
  428. end
  429. n.NameWidth = nameWidth
  430. end
  431. if nameWidth > maxNameWidth then
  432. maxNameWidth = nameWidth
  433. end
  434. end
  435.  
  436. tree[count] = n
  437. count = count + 1
  438. if expanded[n] and #n > 0 then
  439. recur(n,depth)
  440. end
  441. end
  442. end
  443.  
  444. recur(nodes[game],1)
  445.  
  446. -- Nil Instances
  447. if env.getnilinstances then
  448. if not (isSearching and not searchResults[nilNode]) then
  449. tree[count] = nilNode
  450. count = count + 1
  451. if expanded[nilNode] then
  452. recur(nilNode,2)
  453. end
  454. end
  455. end
  456.  
  457. Explorer.MaxNameWidth = maxNameWidth
  458. Explorer.MaxDepth = maxDepth
  459. Explorer.ViewWidth = useNameWidth and Explorer.EntryIndent*maxDepth + maxNameWidth + 26 or Explorer.EntryIndent*maxDepth + 226
  460. Explorer.UpdateView()
  461. end
  462.  
  463. Explorer.StartDrag = function(offX,offY)
  464. if Explorer.Dragging then return end
  465. Explorer.Dragging = true
  466.  
  467. local dragTree = treeFrame:Clone()
  468. dragTree:ClearAllChildren()
  469.  
  470. for i,v in pairs(listEntries) do
  471. local node = tree[i + Explorer.Index]
  472. if node and selection.Map[node] then
  473. local clone = v:Clone()
  474. clone.Active = false
  475. clone.Indent.Expand.Visible = false
  476. clone.Parent = dragTree
  477. end
  478. end
  479.  
  480. local newGui = Instance.new("ScreenGui")
  481. newGui.DisplayOrder = Main.DisplayOrders.Menu
  482. dragTree.Parent = newGui
  483. Lib.ShowGui(newGui)
  484.  
  485. local dragOutline = create({
  486. {1,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="DragSelect",Size=UDim2.new(1,0,1,0),}},
  487. {2,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Size=UDim2.new(1,0,0,1),ZIndex=2,}},
  488. {3,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Position=UDim2.new(0,0,1,-1),Size=UDim2.new(1,0,0,1),ZIndex=2,}},
  489. {4,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Size=UDim2.new(0,1,1,0),ZIndex=2,}},
  490. {5,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Line",Parent={1},Position=UDim2.new(1,-1,0,0),Size=UDim2.new(0,1,1,0),ZIndex=2,}},
  491. })
  492. dragOutline.Parent = treeFrame
  493.  
  494.  
  495. local mouse = Main.Mouse or service.Players.LocalPlayer:GetMouse()
  496. local function move()
  497. local posX = mouse.X - offX
  498. local posY = mouse.Y - offY
  499. dragTree.Position = UDim2.new(0,posX,0,posY)
  500.  
  501. for i = 1,#listEntries do
  502. local entry = listEntries[i]
  503. if Lib.CheckMouseInGui(entry) then
  504. dragOutline.Position = UDim2.new(0,entry.Indent.Position.X.Offset-scrollH.Index,0,entry.Position.Y.Offset)
  505. dragOutline.Size = UDim2.new(0,entry.Size.X.Offset-entry.Indent.Position.X.Offset,0,20)
  506. dragOutline.Visible = true
  507. return
  508. end
  509. end
  510. dragOutline.Visible = false
  511. end
  512. move()
  513.  
  514. local input = service.UserInputService
  515. local mouseEvent,releaseEvent
  516.  
  517. mouseEvent = input.InputChanged:Connect(function(input)
  518. if input.UserInputType == Enum.UserInputType.MouseMovement then
  519. move()
  520. end
  521. end)
  522.  
  523. releaseEvent = input.InputEnded:Connect(function(input)
  524. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  525. releaseEvent:Disconnect()
  526. mouseEvent:Disconnect()
  527. newGui:Destroy()
  528. dragOutline:Destroy()
  529. Explorer.Dragging = false
  530.  
  531. for i = 1,#listEntries do
  532. if Lib.CheckMouseInGui(listEntries[i]) then
  533. local node = tree[i + Explorer.Index]
  534. if node then
  535. if selection.Map[node] then return end
  536. local newPar = node.Obj
  537. local sList = selection.List
  538. for i = 1,#sList do
  539. local n = sList[i]
  540. pcall(function() n.Obj.Parent = newPar end)
  541. end
  542. Explorer.ViewNode(sList[1])
  543. end
  544. break
  545. end
  546. end
  547. end
  548. end)
  549. end
  550.  
  551. Explorer.NewListEntry = function(index)
  552. local newEntry = entryTemplate:Clone()
  553. newEntry.Position = UDim2.new(0,0,0,20*(index-1))
  554.  
  555. local isRenaming = false
  556.  
  557. newEntry.InputBegan:Connect(function(input)
  558. local node = tree[index + Explorer.Index]
  559. if not node or selection.Map[node] or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  560.  
  561. newEntry.Indent.BackgroundColor3 = Settings.Theme.Button
  562. newEntry.Indent.BorderSizePixel = 0
  563. newEntry.Indent.BackgroundTransparency = 0
  564. end)
  565.  
  566. newEntry.InputEnded:Connect(function(input)
  567. local node = tree[index + Explorer.Index]
  568. if not node or selection.Map[node] or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  569.  
  570. newEntry.Indent.BackgroundTransparency = 1
  571. end)
  572.  
  573. newEntry.MouseButton1Down:Connect(function()
  574.  
  575. end)
  576.  
  577. newEntry.MouseButton1Up:Connect(function()
  578.  
  579. end)
  580.  
  581. newEntry.InputBegan:Connect(function(input)
  582. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  583. local releaseEvent,mouseEvent
  584.  
  585. local mouse = Main.Mouse or plr:GetMouse()
  586. local startX = mouse.X
  587. local startY = mouse.Y
  588.  
  589. local listOffsetX = startX - treeFrame.AbsolutePosition.X
  590. local listOffsetY = startY - treeFrame.AbsolutePosition.Y
  591.  
  592. releaseEvent = clonerefs(game:GetService("UserInputService")).InputEnded:Connect(function(input)
  593. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  594. releaseEvent:Disconnect()
  595. mouseEvent:Disconnect()
  596. end
  597. end)
  598.  
  599. mouseEvent = clonerefs(game:GetService("UserInputService")).InputChanged:Connect(function(input)
  600. if input.UserInputType == Enum.UserInputType.MouseMovement then
  601. local deltaX = mouse.X - startX
  602. local deltaY = mouse.Y - startY
  603. local dist = math.sqrt(deltaX^2 + deltaY^2)
  604.  
  605. if dist > 5 then
  606. releaseEvent:Disconnect()
  607. mouseEvent:Disconnect()
  608. isRenaming = false
  609. Explorer.StartDrag(listOffsetX,listOffsetY)
  610. end
  611. end
  612. end)
  613. end
  614. end)
  615.  
  616. newEntry.MouseButton2Down:Connect(function()
  617.  
  618. end)
  619.  
  620. newEntry.Indent.Expand.InputBegan:Connect(function(input)
  621. local node = tree[index + Explorer.Index]
  622. if not node or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  623.  
  624. Explorer.MiscIcons:DisplayByKey(newEntry.Indent.Expand.Icon, expanded[node] and "Collapse_Over" or "Expand_Over")
  625. end)
  626.  
  627. newEntry.Indent.Expand.InputEnded:Connect(function(input)
  628. local node = tree[index + Explorer.Index]
  629. if not node or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  630.  
  631. Explorer.MiscIcons:DisplayByKey(newEntry.Indent.Expand.Icon, expanded[node] and "Collapse" or "Expand")
  632. end)
  633.  
  634. newEntry.Indent.Expand.MouseButton1Down:Connect(function()
  635. local node = tree[index + Explorer.Index]
  636. if not node or #node == 0 then return end
  637.  
  638. expanded[node] = not expanded[node]
  639. Explorer.Update()
  640. Explorer.Refresh()
  641. end)
  642.  
  643. newEntry.Parent = treeFrame
  644. return newEntry
  645. end
  646.  
  647. Explorer.Refresh = function()
  648. local maxNodes = math.max(math.ceil((treeFrame.AbsoluteSize.Y) / 20),0)
  649. local renameNodeVisible = false
  650. local isa = game.IsA
  651.  
  652. for i = 1,maxNodes do
  653. local entry = listEntries[i]
  654. if not listEntries[i] then entry = Explorer.NewListEntry(i) listEntries[i] = entry Explorer.ClickSystem:Add(entry) end
  655.  
  656. local node = tree[i + Explorer.Index]
  657. if node then
  658. local obj = node.Obj
  659. local depth = Explorer.EntryIndent*Explorer.NodeDepth(node)
  660.  
  661. entry.Visible = true
  662. entry.Position = UDim2.new(0,-scrollH.Index,0,entry.Position.Y.Offset)
  663. entry.Size = UDim2.new(0,Explorer.ViewWidth,0,20)
  664. entry.Indent.EntryName.Text = tostring(node.Obj)
  665. entry.Indent.Position = UDim2.new(0,depth,0,0)
  666. entry.Indent.Size = UDim2.new(1,-depth,1,0)
  667.  
  668. entry.Indent.EntryName.TextTruncate = (Settings.Explorer.UseNameWidth and Enum.TextTruncate.None or Enum.TextTruncate.AtEnd)
  669.  
  670. if (isa(obj,"LocalScript") or isa(obj,"Script")) and obj.Disabled then
  671. Explorer.MiscIcons:DisplayByKey(entry.Indent.Icon, isa(obj,"LocalScript") and "LocalScript_Disabled" or "Script_Disabled")
  672. else
  673. local rmdEntry = RMD.Classes[obj.ClassName]
  674. Explorer.ClassIcons:Display(entry.Indent.Icon, rmdEntry and rmdEntry.ExplorerImageIndex or 0)
  675. end
  676.  
  677. if selection.Map[node] then
  678. entry.Indent.BackgroundColor3 = Settings.Theme.ListSelection
  679. entry.Indent.BorderSizePixel = 0
  680. entry.Indent.BackgroundTransparency = 0
  681. else
  682. if Lib.CheckMouseInGui(entry) then
  683. entry.Indent.BackgroundColor3 = Settings.Theme.Button
  684. else
  685. entry.Indent.BackgroundTransparency = 1
  686. end
  687. end
  688.  
  689. if node == renamingNode then
  690. renameNodeVisible = true
  691. renameBox.Position = UDim2.new(0,depth+25-scrollH.Index,0,entry.Position.Y.Offset+2)
  692. renameBox.Visible = true
  693. end
  694.  
  695. if #node > 0 and expanded[node] ~= 0 then
  696. if Lib.CheckMouseInGui(entry.Indent.Expand) then
  697. Explorer.MiscIcons:DisplayByKey(entry.Indent.Expand.Icon, expanded[node] and "Collapse_Over" or "Expand_Over")
  698. else
  699. Explorer.MiscIcons:DisplayByKey(entry.Indent.Expand.Icon, expanded[node] and "Collapse" or "Expand")
  700. end
  701. entry.Indent.Expand.Visible = true
  702. else
  703. entry.Indent.Expand.Visible = false
  704. end
  705. else
  706. entry.Visible = false
  707. end
  708. end
  709.  
  710. if not renameNodeVisible then
  711. renameBox.Visible = false
  712. end
  713.  
  714. for i = maxNodes+1, #listEntries do
  715. Explorer.ClickSystem:Remove(listEntries[i])
  716. listEntries[i]:Destroy()
  717. listEntries[i] = nil
  718. end
  719. end
  720.  
  721. Explorer.PerformUpdate = function(instant)
  722. updateDebounce = true
  723. Lib.FastWait(not instant and 0.1)
  724. if not updateDebounce then return end
  725. updateDebounce = false
  726. if not Explorer.Window:IsVisible() then return end
  727. Explorer.Update()
  728. Explorer.Refresh()
  729. end
  730.  
  731. Explorer.ForceUpdate = function(norefresh)
  732. updateDebounce = false
  733. Explorer.Update()
  734. if not norefresh then Explorer.Refresh() end
  735. end
  736.  
  737. Explorer.PerformRefresh = function()
  738. refreshDebounce = true
  739. Lib.FastWait(0.1)
  740. refreshDebounce = false
  741. if updateDebounce or not Explorer.Window:IsVisible() then return end
  742. Explorer.Refresh()
  743. end
  744.  
  745. Explorer.IsNodeVisible = function(node)
  746. if not node then return end
  747.  
  748. local curNode = node.Parent
  749. while curNode do
  750. if not expanded[curNode] then return false end
  751. curNode = curNode.Parent
  752. end
  753. return true
  754. end
  755.  
  756. Explorer.NodeDepth = function(node)
  757. local depth = 0
  758.  
  759. if node == nilNode then
  760. return 1
  761. end
  762.  
  763. local curNode = node.Parent
  764. while curNode do
  765. if curNode == nilNode then depth = depth + 1 end
  766. curNode = curNode.Parent
  767. depth = depth + 1
  768. end
  769. return depth
  770. end
  771.  
  772. Explorer.SetupConnections = function()
  773. if descendantAddedCon then descendantAddedCon:Disconnect() end
  774. if descendantRemovingCon then descendantRemovingCon:Disconnect() end
  775. if itemChangedCon then itemChangedCon:Disconnect() end
  776.  
  777. if Main.Elevated then
  778. descendantAddedCon = game.DescendantAdded:Connect(addObject)
  779. descendantRemovingCon = game.DescendantRemoving:Connect(removeObject)
  780. else
  781. descendantAddedCon = game.DescendantAdded:Connect(function(obj) pcall(addObject,obj) end)
  782. descendantRemovingCon = game.DescendantRemoving:Connect(function(obj) pcall(removeObject,obj) end)
  783. end
  784.  
  785. if Settings.Explorer.UseNameWidth then
  786. itemChangedCon = game.ItemChanged:Connect(function(obj,prop)
  787. if prop == "Parent" and nodes[obj] then
  788. moveObject(obj)
  789. elseif prop == "Name" and nodes[obj] then
  790. nodes[obj].NameWidth = nil
  791. end
  792. end)
  793. else
  794. itemChangedCon = game.ItemChanged:Connect(function(obj,prop)
  795. if prop == "Parent" and nodes[obj] then
  796. moveObject(obj)
  797. end
  798. end)
  799. end
  800. end
  801.  
  802. Explorer.ViewNode = function(node)
  803. if not node then return end
  804.  
  805. Explorer.MakeNodeVisible(node)
  806. Explorer.ForceUpdate(true)
  807. local visibleSpace = scrollV.VisibleSpace
  808.  
  809. for i,v in next,tree do
  810. if v == node then
  811. local relative = i - 1
  812. if Explorer.Index > relative then
  813. scrollV.Index = relative
  814. elseif Explorer.Index + visibleSpace - 1 <= relative then
  815. scrollV.Index = relative - visibleSpace + 2
  816. end
  817. end
  818. end
  819.  
  820. scrollV:Update() Explorer.Index = scrollV.Index
  821. Explorer.Refresh()
  822. end
  823.  
  824. Explorer.ViewObj = function(obj)
  825. Explorer.ViewNode(nodes[obj])
  826. end
  827.  
  828. Explorer.MakeNodeVisible = function(node,expandRoot)
  829. if not node then return end
  830.  
  831. local hasExpanded = false
  832.  
  833. if expandRoot and not expanded[node] then
  834. expanded[node] = true
  835. hasExpanded = true
  836. end
  837.  
  838. local currentNode = node.Parent
  839. while currentNode do
  840. hasExpanded = true
  841. expanded[currentNode] = true
  842. currentNode = currentNode.Parent
  843. end
  844.  
  845. if hasExpanded and not updateDebounce then
  846. coroutine.wrap(Explorer.PerformUpdate)(true)
  847. end
  848. end
  849.  
  850. Explorer.ShowRightClick = function()
  851. local context = Explorer.RightClickContext
  852. context:Clear()
  853.  
  854. local sList = selection.List
  855. local sMap = selection.Map
  856. local emptyClipboard = #clipboard == 0
  857. local presentClasses = {}
  858. local apiClasses = API.Classes
  859.  
  860. for i = 1, #sList do
  861. local node = sList[i]
  862. local class = node.Class
  863. if not class then class = node.Obj.ClassName node.Class = class end
  864. local curClass = apiClasses[class]
  865. while curClass and not presentClasses[curClass.Name] do
  866. presentClasses[curClass.Name] = true
  867. curClass = curClass.Superclass
  868. end
  869. end
  870.  
  871. context:AddRegistered("CUT")
  872. context:AddRegistered("COPY")
  873. context:AddRegistered("PASTE", emptyClipboard)
  874. context:AddRegistered("DUPLICATE")
  875. context:AddRegistered("DELETE")
  876. context:AddRegistered("RENAME", #sList ~= 1)
  877.  
  878. context:AddDivider()
  879. context:AddRegistered("GROUP")
  880. context:AddRegistered("UNGROUP")
  881. context:AddRegistered("SELECT_CHILDREN")
  882. context:AddRegistered("JUMP_TO_PARENT")
  883. context:AddRegistered("EXPAND_ALL")
  884. context:AddRegistered("COLLAPSE_ALL")
  885.  
  886. context:AddDivider()
  887. if expanded == Explorer.SearchExpanded then context:AddRegistered("CLEAR_SEARCH_AND_JUMP_TO") end
  888. if env.setclipboard then context:AddRegistered("COPY_PATH") end
  889. context:AddRegistered("INSERT_OBJECT")
  890. context:AddRegistered("SAVE_INST")
  891. context:AddRegistered("CALL_FUNCTION")
  892. context:AddRegistered("VIEW_CONNECTIONS")
  893. context:AddRegistered("GET_REFERENCES")
  894. context:AddRegistered("VIEW_API")
  895.  
  896. context:QueueDivider()
  897.  
  898. if presentClasses["BasePart"] or presentClasses["Model"] then
  899. context:AddRegistered("TELEPORT_TO")
  900. context:AddRegistered("VIEW_OBJECT")
  901. end
  902.  
  903. if presentClasses["TouchTransmitter"] then context:AddRegistered("FIRE_TOUCHTRANSMITTER", firetouchinterest == nil) end
  904. if presentClasses["ClickDetector"] then context:AddRegistered("FIRE_CLICKDETECTOR", fireclickdetector == nil) end
  905. if presentClasses["ProximityPrompt"] then context:AddRegistered("FIRE_PROXIMITYPROMPT", fireproximityprompt == nil) end
  906. if presentClasses["Player"] then context:AddRegistered("SELECT_CHARACTER") end
  907. if presentClasses["Players"] then context:AddRegistered("SELECT_LOCAL_PLAYER") end
  908. if presentClasses["LuaSourceContainer"] then context:AddRegistered("VIEW_SCRIPT") end
  909.  
  910. if sMap[nilNode] then
  911. context:AddRegistered("REFRESH_NIL")
  912. context:AddRegistered("HIDE_NIL")
  913. end
  914.  
  915. Explorer.LastRightClickX, Explorer.LastRightClickY = Main.Mouse.X, Main.Mouse.Y
  916. context:Show()
  917. end
  918.  
  919. Explorer.InitRightClick = function()
  920. local context = Lib.ContextMenu.new()
  921.  
  922. context:Register("CUT",{Name = "Cut", IconMap = Explorer.MiscIcons, Icon = "Cut", DisabledIcon = "Cut_Disabled", Shortcut = "Ctrl+Z", OnClick = function()
  923. local destroy,clone = game.Destroy,game.Clone
  924. local sList,newClipboard = selection.List,{}
  925. local count = 1
  926. for i = 1,#sList do
  927. local inst = sList[i].Obj
  928. local s,cloned = pcall(clone,inst)
  929. if s and cloned then
  930. newClipboard[count] = cloned
  931. count = count + 1
  932. end
  933. pcall(destroy,inst)
  934. end
  935. clipboard = newClipboard
  936. selection:Clear()
  937. end})
  938.  
  939. context:Register("COPY",{Name = "Copy", IconMap = Explorer.MiscIcons, Icon = "Copy", DisabledIcon = "Copy_Disabled", Shortcut = "Ctrl+C", OnClick = function()
  940. local clone = game.Clone
  941. local sList,newClipboard = selection.List,{}
  942. local count = 1
  943. for i = 1,#sList do
  944. local inst = sList[i].Obj
  945. local s,cloned = pcall(clone,inst)
  946. if s and cloned then
  947. newClipboard[count] = cloned
  948. count = count + 1
  949. end
  950. end
  951. clipboard = newClipboard
  952. end})
  953.  
  954. context:Register("PASTE",{Name = "Paste Into", IconMap = Explorer.MiscIcons, Icon = "Paste", DisabledIcon = "Paste_Disabled", Shortcut = "Ctrl+Shift+V", OnClick = function()
  955. local sList = selection.List
  956. local newSelection = {}
  957. local count = 1
  958. for i = 1,#sList do
  959. local node = sList[i]
  960. local inst = node.Obj
  961. Explorer.MakeNodeVisible(node,true)
  962. for c = 1,#clipboard do
  963. local cloned = clipboard[c]:Clone()
  964. if cloned then
  965. cloned.Parent = inst
  966. local clonedNode = nodes[cloned]
  967. if clonedNode then newSelection[count] = clonedNode count = count + 1 end
  968. end
  969. end
  970. end
  971. selection:SetTable(newSelection)
  972.  
  973. if #newSelection > 0 then
  974. Explorer.ViewNode(newSelection[1])
  975. end
  976. end})
  977.  
  978. context:Register("DUPLICATE",{Name = "Duplicate", IconMap = Explorer.MiscIcons, Icon = "Copy", DisabledIcon = "Copy_Disabled", Shortcut = "Ctrl+D", OnClick = function()
  979. local clone = game.Clone
  980. local sList = selection.List
  981. local newSelection = {}
  982. local count = 1
  983. for i = 1,#sList do
  984. local node = sList[i]
  985. local inst = node.Obj
  986. local instPar = node.Parent and node.Parent.Obj
  987. Explorer.MakeNodeVisible(node)
  988. local s,cloned = pcall(clone,inst)
  989. if s and cloned then
  990. cloned.Parent = instPar
  991. local clonedNode = nodes[cloned]
  992. if clonedNode then newSelection[count] = clonedNode count = count + 1 end
  993. end
  994. end
  995.  
  996. selection:SetTable(newSelection)
  997. if #newSelection > 0 then
  998. Explorer.ViewNode(newSelection[1])
  999. end
  1000. end})
  1001.  
  1002. context:Register("DELETE",{Name = "Delete", IconMap = Explorer.MiscIcons, Icon = "Delete", DisabledIcon = "Delete_Disabled", Shortcut = "Del", OnClick = function()
  1003. local destroy = game.Destroy
  1004. local sList = selection.List
  1005. for i = 1,#sList do
  1006. pcall(destroy,sList[i].Obj)
  1007. end
  1008. selection:Clear()
  1009. end})
  1010.  
  1011. context:Register("RENAME",{Name = "Rename", IconMap = Explorer.MiscIcons, Icon = "Rename", DisabledIcon = "Rename_Disabled", Shortcut = "F2", OnClick = function()
  1012. local sList = selection.List
  1013. if sList[1] then
  1014. Explorer.SetRenamingNode(sList[1])
  1015. end
  1016. end})
  1017.  
  1018. context:Register("GROUP",{Name = "Group", IconMap = Explorer.MiscIcons, Icon = "Group", DisabledIcon = "Group_Disabled", Shortcut = "Ctrl+G", OnClick = function()
  1019. local sList = selection.List
  1020. if #sList == 0 then return end
  1021.  
  1022. local model = Instance.new("Model",sList[#sList].Obj.Parent)
  1023. for i = 1,#sList do
  1024. pcall(function() sList[i].Obj.Parent = model end)
  1025. end
  1026.  
  1027. if nodes[model] then
  1028. selection:Set(nodes[model])
  1029. Explorer.ViewNode(nodes[model])
  1030. end
  1031. end})
  1032.  
  1033. context:Register("UNGROUP",{Name = "Ungroup", IconMap = Explorer.MiscIcons, Icon = "Ungroup", DisabledIcon = "Ungroup_Disabled", Shortcut = "Ctrl+U", OnClick = function()
  1034. local newSelection = {}
  1035. local count = 1
  1036. local isa = game.IsA
  1037.  
  1038. local function ungroup(node)
  1039. local par = node.Parent.Obj
  1040. local ch = {}
  1041. local chCount = 1
  1042.  
  1043. for i = 1,#node do
  1044. local n = node[i]
  1045. newSelection[count] = n
  1046. ch[chCount] = n
  1047. count = count + 1
  1048. chCount = chCount + 1
  1049. end
  1050.  
  1051. for i = 1,#ch do
  1052. pcall(function() ch[i].Obj.Parent = par end)
  1053. end
  1054.  
  1055. node.Obj:Destroy()
  1056. end
  1057.  
  1058. for i,v in next,selection.List do
  1059. if isa(v.Obj,"Model") then
  1060. ungroup(v)
  1061. end
  1062. end
  1063.  
  1064. selection:SetTable(newSelection)
  1065. if #newSelection > 0 then
  1066. Explorer.ViewNode(newSelection[1])
  1067. end
  1068. end})
  1069.  
  1070. context:Register("SELECT_CHILDREN",{Name = "Select Children", IconMap = Explorer.MiscIcons, Icon = "SelectChildren", DisabledIcon = "SelectChildren_Disabled", OnClick = function()
  1071. local newSelection = {}
  1072. local count = 1
  1073. local sList = selection.List
  1074.  
  1075. for i = 1,#sList do
  1076. local node = sList[i]
  1077. for ind = 1,#node do
  1078. local cNode = node[ind]
  1079. if ind == 1 then Explorer.MakeNodeVisible(cNode) end
  1080.  
  1081. newSelection[count] = cNode
  1082. count = count + 1
  1083. end
  1084. end
  1085.  
  1086. selection:SetTable(newSelection)
  1087. if #newSelection > 0 then
  1088. Explorer.ViewNode(newSelection[1])
  1089. else
  1090. Explorer.Refresh()
  1091. end
  1092. end})
  1093.  
  1094. context:Register("JUMP_TO_PARENT",{Name = "Jump to Parent", IconMap = Explorer.MiscIcons, Icon = "JumpToParent", OnClick = function()
  1095. local newSelection = {}
  1096. local count = 1
  1097. local sList = selection.List
  1098.  
  1099. for i = 1,#sList do
  1100. local node = sList[i]
  1101. if node.Parent then
  1102. newSelection[count] = node.Parent
  1103. count = count + 1
  1104. end
  1105. end
  1106.  
  1107. selection:SetTable(newSelection)
  1108. if #newSelection > 0 then
  1109. Explorer.ViewNode(newSelection[1])
  1110. else
  1111. Explorer.Refresh()
  1112. end
  1113. end})
  1114.  
  1115. context:Register("TELEPORT_TO",{Name = "Teleport To", IconMap = Explorer.MiscIcons, Icon = "TeleportTo", OnClick = function()
  1116. local sList = selection.List
  1117. local isa = game.IsA
  1118.  
  1119. local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
  1120. if not hrp then return end
  1121.  
  1122. for i = 1,#sList do
  1123. local node = sList[i]
  1124.  
  1125. if isa(node.Obj,"BasePart") then
  1126. hrp.CFrame = node.Obj.CFrame + Settings.Explorer.TeleportToOffset
  1127. break
  1128. elseif isa(node.Obj,"Model") then
  1129. if node.Obj.PrimaryPart then
  1130. hrp.CFrame = node.Obj.PrimaryPart.CFrame + Settings.Explorer.TeleportToOffset
  1131. break
  1132. else
  1133. local part = node.Obj:FindFirstChildWhichIsA("BasePart",true)
  1134. if part and nodes[part] then
  1135. hrp.CFrame = nodes[part].Obj.CFrame + Settings.Explorer.TeleportToOffset
  1136. end
  1137. end
  1138. end
  1139. end
  1140. end})
  1141.  
  1142. context:Register("EXPAND_ALL",{Name = "Expand All", OnClick = function()
  1143. local sList = selection.List
  1144.  
  1145. local function expand(node)
  1146. expanded[node] = true
  1147. for i = 1,#node do
  1148. if #node[i] > 0 then
  1149. expand(node[i])
  1150. end
  1151. end
  1152. end
  1153.  
  1154. for i = 1,#sList do
  1155. expand(sList[i])
  1156. end
  1157.  
  1158. Explorer.ForceUpdate()
  1159. end})
  1160.  
  1161. context:Register("COLLAPSE_ALL",{Name = "Collapse All", OnClick = function()
  1162. local sList = selection.List
  1163.  
  1164. local function expand(node)
  1165. expanded[node] = nil
  1166. for i = 1,#node do
  1167. if #node[i] > 0 then
  1168. expand(node[i])
  1169. end
  1170. end
  1171. end
  1172.  
  1173. for i = 1,#sList do
  1174. expand(sList[i])
  1175. end
  1176.  
  1177. Explorer.ForceUpdate()
  1178. end})
  1179.  
  1180. context:Register("CLEAR_SEARCH_AND_JUMP_TO",{Name = "Clear Search and Jump to", OnClick = function()
  1181. local newSelection = {}
  1182. local count = 1
  1183. local sList = selection.List
  1184.  
  1185. for i = 1,#sList do
  1186. newSelection[count] = sList[i]
  1187. count = count + 1
  1188. end
  1189.  
  1190. selection:SetTable(newSelection)
  1191. Explorer.ClearSearch()
  1192. if #newSelection > 0 then
  1193. Explorer.ViewNode(newSelection[1])
  1194. end
  1195. end})
  1196.  
  1197. local clth = function(str)
  1198. if str:sub(1, 28) == "game:GetService(\"Workspace\")" then str = str:gsub("game:GetService%(\"Workspace\"%)", "workspace", 1) end
  1199. if str:sub(1, 27 + #plr.Name) == "game:GetService(\"Players\")." .. plr.Name then str = str:gsub("game:GetService%(\"Players\"%)." .. plr.Name, "game:GetService(\"Players\").LocalPlayer", 1) end
  1200. return str
  1201. end
  1202.  
  1203. context:Register("COPY_PATH",{Name = "Copy Path", OnClick = function()
  1204. local sList = selection.List
  1205. if #sList == 1 then
  1206. env.setclipboard(clth(Explorer.GetInstancePath(sList[1].Obj)))
  1207. elseif #sList > 1 then
  1208. local resList = {"{"}
  1209. local count = 2
  1210. for i = 1,#sList do
  1211. local path = "\t"..clth(Explorer.GetInstancePath(sList[i].Obj))..","
  1212. if #path > 0 then
  1213. resList[count] = path
  1214. count = count+1
  1215. end
  1216. end
  1217. resList[count] = "}"
  1218. env.setclipboard(table.concat(resList,"\n"))
  1219. end
  1220. end})
  1221.  
  1222. context:Register("INSERT_OBJECT",{Name = "Insert Object", IconMap = Explorer.MiscIcons, Icon = "InsertObject", OnClick = function()
  1223. local mouse = Main.Mouse
  1224. local x,y = Explorer.LastRightClickX or mouse.X, Explorer.LastRightClickY or mouse.Y
  1225. Explorer.InsertObjectContext:Show(x,y)
  1226. end})
  1227.  
  1228. context:Register("CALL_FUNCTION",{Name = "Call Function", IconMap = Explorer.ClassIcons, Icon = 66, OnClick = function()
  1229.  
  1230. end})
  1231.  
  1232. context:Register("GET_REFERENCES",{Name = "Get Lua References", IconMap = Explorer.ClassIcons, Icon = 34, OnClick = function()
  1233.  
  1234. end})
  1235.  
  1236. context:Register("SAVE_INST",{Name = "Save to File", IconMap = Explorer.MiscIcons, Icon = "Save", OnClick = function()
  1237.  
  1238. end})
  1239.  
  1240. context:Register("VIEW_CONNECTIONS",{Name = "View Connections", OnClick = function()
  1241.  
  1242. end})
  1243.  
  1244. context:Register("VIEW_API",{Name = "View API Page", IconMap = Explorer.MiscIcons, Icon = "Reference", OnClick = function()
  1245.  
  1246. end})
  1247.  
  1248. context:Register("VIEW_OBJECT",{Name = "View Object (Right click to reset)", IconMap = Explorer.ClassIcons, Icon = 5, OnClick = function()
  1249. local sList = selection.List
  1250. local isa = game.IsA
  1251.  
  1252. for i = 1,#sList do
  1253. local node = sList[i]
  1254.  
  1255. if isa(node.Obj,"BasePart") or isa(node.Obj,"Model") then
  1256. workspace.CurrentCamera.CameraSubject = node.Obj
  1257. break
  1258. end
  1259. end
  1260. end, OnRightClick = function()
  1261. workspace.CurrentCamera.CameraSubject = plr.Character
  1262. end})
  1263.  
  1264. context:Register("FIRE_TOUCHTRANSMITTER",{Name = "Fire TouchTransmitter", IconMap = Explorer.ClassIcons, Icon = 37, OnClick = function()
  1265. local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
  1266. if not hrp then return end
  1267. for _, v in ipairs(selection.List) do if v.Obj and v.Obj:IsA("TouchTransmitter") then firetouchinterest(hrp, v.Obj.Parent, 0) end end
  1268. end})
  1269.  
  1270. context:Register("FIRE_CLICKDETECTOR",{Name = "Fire ClickDetector", IconMap = Explorer.ClassIcons, Icon = 41, OnClick = function()
  1271. local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
  1272. if not hrp then return end
  1273. for _, v in ipairs(selection.List) do if v.Obj and v.Obj:IsA("ClickDetector") then fireclickdetector(v.Obj) end end
  1274. end})
  1275.  
  1276. context:Register("FIRE_PROXIMITYPROMPT",{Name = "Fire ProximityPrompt", IconMap = Explorer.ClassIcons, Icon = 124, OnClick = function()
  1277. local hrp = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
  1278. if not hrp then return end
  1279. for _, v in ipairs(selection.List) do if v.Obj and v.Obj:IsA("ProximityPrompt") then fireproximityprompt(v.Obj) end end
  1280. end})
  1281.  
  1282. context:Register("VIEW_SCRIPT",{Name = "View Script", IconMap = Explorer.MiscIcons, Icon = "ViewScript", OnClick = function()
  1283. local scr = selection.List[1] and selection.List[1].Obj
  1284. if scr then ScriptViewer.ViewScript(scr) end
  1285. end})
  1286.  
  1287. context:Register("SELECT_CHARACTER",{Name = "Select Character", IconMap = Explorer.ClassIcons, Icon = 9, OnClick = function()
  1288. local newSelection = {}
  1289. local count = 1
  1290. local sList = selection.List
  1291. local isa = game.IsA
  1292.  
  1293. for i = 1,#sList do
  1294. local node = sList[i]
  1295. if isa(node.Obj,"Player") and nodes[node.Obj.Character] then
  1296. newSelection[count] = nodes[node.Obj.Character]
  1297. count = count + 1
  1298. end
  1299. end
  1300.  
  1301. selection:SetTable(newSelection)
  1302. if #newSelection > 0 then
  1303. Explorer.ViewNode(newSelection[1])
  1304. else
  1305. Explorer.Refresh()
  1306. end
  1307. end})
  1308.  
  1309. context:Register("SELECT_LOCAL_PLAYER",{Name = "Select Local Player", IconMap = Explorer.ClassIcons, Icon = 9, OnClick = function()
  1310. pcall(function() if nodes[plr] then selection:Set(nodes[plr]) Explorer.ViewNode(nodes[plr]) end end)
  1311. end})
  1312.  
  1313. context:Register("REFRESH_NIL",{Name = "Refresh Nil Instances", OnClick = function()
  1314. Explorer.RefreshNilInstances()
  1315. end})
  1316.  
  1317. context:Register("HIDE_NIL",{Name = "Hide Nil Instances", OnClick = function()
  1318. Explorer.HideNilInstances()
  1319. end})
  1320.  
  1321. Explorer.RightClickContext = context
  1322. end
  1323.  
  1324. Explorer.HideNilInstances = function()
  1325. table.clear(nilMap)
  1326.  
  1327. local disconnectCon = Instance.new("Folder").ChildAdded:Connect(function() end).Disconnect
  1328. for i,v in next,nilCons do
  1329. disconnectCon(v[1])
  1330. disconnectCon(v[2])
  1331. end
  1332. table.clear(nilCons)
  1333.  
  1334. for i = 1,#nilNode do
  1335. coroutine.wrap(removeObject)(nilNode[i].Obj)
  1336. end
  1337.  
  1338. Explorer.Update()
  1339. Explorer.Refresh()
  1340. end
  1341.  
  1342. Explorer.RefreshNilInstances = function()
  1343. if not env.getnilinstances then return end
  1344.  
  1345. local nilInsts = env.getnilinstances()
  1346. local game = game
  1347. local getDescs = game.GetDescendants
  1348. --local newNilMap = {}
  1349. --local newNilRoots = {}
  1350. --local nilRoots = Explorer.NilRoots
  1351. --local connect = game.DescendantAdded.Connect
  1352. --local disconnect
  1353. --if not nilRoots then nilRoots = {} Explorer.NilRoots = nilRoots end
  1354.  
  1355. for i = 1,#nilInsts do
  1356. local obj = nilInsts[i]
  1357. if obj ~= game then
  1358. nilMap[obj] = true
  1359. --newNilRoots[obj] = true
  1360.  
  1361. local descs = getDescs(obj)
  1362. for j = 1,#descs do
  1363. nilMap[descs[j]] = true
  1364. end
  1365. end
  1366. end
  1367.  
  1368. -- Remove unmapped nil nodes
  1369. --[[for i = 1,#nilNode do
  1370. local node = nilNode[i]
  1371. if not newNilMap[node.Obj] then
  1372. nilMap[node.Obj] = nil
  1373. coroutine.wrap(removeObject)(node)
  1374. end
  1375. end]]
  1376.  
  1377. --nilMap = newNilMap
  1378.  
  1379. for i = 1,#nilInsts do
  1380. local obj = nilInsts[i]
  1381. local node = nodes[obj]
  1382. if not node then coroutine.wrap(addObject)(obj) end
  1383. end
  1384.  
  1385. --[[
  1386. -- Remove old root connections
  1387. for obj in next,nilRoots do
  1388. if not newNilRoots[obj] then
  1389. if not disconnect then disconnect = obj[1].Disconnect end
  1390. disconnect(obj[1])
  1391. disconnect(obj[2])
  1392. end
  1393. end
  1394.  
  1395. for obj in next,newNilRoots do
  1396. if not nilRoots[obj] then
  1397. nilRoots[obj] = {
  1398. connect(obj.DescendantAdded,addObject),
  1399. connect(obj.DescendantRemoving,removeObject)
  1400. }
  1401. end
  1402. end]]
  1403.  
  1404. --nilMap = newNilMap
  1405. --Explorer.NilRoots = newNilRoots
  1406.  
  1407. Explorer.Update()
  1408. Explorer.Refresh()
  1409. end
  1410.  
  1411. Explorer.GetInstancePath = function(obj)
  1412. local ffc = game.FindFirstChild
  1413. local getCh = game.GetChildren
  1414. local path = ""
  1415. local curObj = obj
  1416. local ts = tostring
  1417. local match = string.match
  1418. local gsub = string.gsub
  1419. local tableFind = table.find
  1420. local useGetCh = Settings.Explorer.CopyPathUseGetChildren
  1421. local formatLuaString = Lib.FormatLuaString
  1422.  
  1423. while curObj do
  1424. if curObj == game then
  1425. path = "game"..path
  1426. break
  1427. end
  1428.  
  1429. local className = curObj.ClassName
  1430. local curName = ts(curObj)
  1431. local indexName
  1432. if match(curName,"^[%a_][%w_]*$") then
  1433. indexName = "."..curName
  1434. else
  1435. local cleanName = formatLuaString(curName)
  1436. indexName = '["'..cleanName..'"]'
  1437. end
  1438.  
  1439. local parObj = curObj.Parent
  1440. if parObj then
  1441. local fc = ffc(parObj,curName)
  1442. if useGetCh and fc and fc ~= curObj then
  1443. local parCh = getCh(parObj)
  1444. local fcInd = tableFind(parCh,curObj)
  1445. indexName = ":GetChildren()["..fcInd.."]"
  1446. elseif parObj == game and API.Classes[className] and API.Classes[className].Tags.Service then
  1447. indexName = ':GetService("'..className..'")'
  1448. end
  1449. elseif parObj == nil then
  1450. local getnil = "local getNil = function(name, class) for _, v in next, getnilinstances() do if v.ClassName == class and v.Name == name then return v end end end"
  1451. local gotnil = "\n\ngetNil(\"%s\", \"%s\")"
  1452. indexName = getnil .. gotnil:format(curObj.Name, className)
  1453. end
  1454.  
  1455. path = indexName..path
  1456. curObj = parObj
  1457. end
  1458.  
  1459. return path
  1460. end
  1461.  
  1462. Explorer.InitInsertObject = function()
  1463. local context = Lib.ContextMenu.new()
  1464. context.SearchEnabled = true
  1465. context.MaxHeight = 400
  1466. context:ApplyTheme({
  1467. ContentColor = Settings.Theme.Main2,
  1468. OutlineColor = Settings.Theme.Outline1,
  1469. DividerColor = Settings.Theme.Outline1,
  1470. TextColor = Settings.Theme.Text,
  1471. HighlightColor = Settings.Theme.ButtonHover
  1472. })
  1473.  
  1474. local classes = {}
  1475. for i,class in next,API.Classes do
  1476. local tags = class.Tags
  1477. if not tags.NotCreatable and not tags.Service then
  1478. local rmdEntry = RMD.Classes[class.Name]
  1479. classes[#classes+1] = {class,rmdEntry and rmdEntry.ClassCategory or "Uncategorized"}
  1480. end
  1481. end
  1482. table.sort(classes,function(a,b)
  1483. if a[2] ~= b[2] then
  1484. return a[2] < b[2]
  1485. else
  1486. return a[1].Name < b[1].Name
  1487. end
  1488. end)
  1489.  
  1490. local function onClick(className)
  1491. local sList = selection.List
  1492. local instNew = Instance.new
  1493. for i = 1,#sList do
  1494. local node = sList[i]
  1495. local obj = node.Obj
  1496. Explorer.MakeNodeVisible(node,true)
  1497. pcall(instNew,className,obj)
  1498. end
  1499. end
  1500.  
  1501. local lastCategory = ""
  1502. for i = 1,#classes do
  1503. local class = classes[i][1]
  1504. local rmdEntry = RMD.Classes[class.Name]
  1505. local iconInd = rmdEntry and tonumber(rmdEntry.ExplorerImageIndex) or 0
  1506. local category = classes[i][2]
  1507.  
  1508. if lastCategory ~= category then
  1509. context:AddDivider(category)
  1510. lastCategory = category
  1511. end
  1512. context:Add({Name = class.Name, IconMap = Explorer.ClassIcons, Icon = iconInd, OnClick = onClick})
  1513. end
  1514.  
  1515. Explorer.InsertObjectContext = context
  1516. end
  1517.  
  1518. --[[
  1519. Headers, Setups, Predicate, ObjectDefs
  1520. ]]
  1521. Explorer.SearchFilters = { -- TODO: Use data table (so we can disable some if funcs don't exist)
  1522. Comparison = {
  1523. ["isa"] = function(argString)
  1524. local lower = string.lower
  1525. local find = string.find
  1526. local classQuery = string.split(argString)[1]
  1527. if not classQuery then return end
  1528. classQuery = lower(classQuery)
  1529.  
  1530. local className
  1531. for class,_ in pairs(API.Classes) do
  1532. local cName = lower(class)
  1533. if cName == classQuery then
  1534. className = class
  1535. break
  1536. elseif find(cName,classQuery,1,true) then
  1537. className = class
  1538. end
  1539. end
  1540. if not className then return end
  1541.  
  1542. return {
  1543. Headers = {"local isa = game.IsA"},
  1544. Predicate = "isa(obj,'"..className.."')"
  1545. }
  1546. end,
  1547. ["remotes"] = function(argString)
  1548. return {
  1549. Headers = {"local isa = game.IsA"},
  1550. Predicate = "isa(obj,'RemoteEvent') or isa(obj,'RemoteFunction')"
  1551. }
  1552. end,
  1553. ["bindables"] = function(argString)
  1554. return {
  1555. Headers = {"local isa = game.IsA"},
  1556. Predicate = "isa(obj,'BindableEvent') or isa(obj,'BindableFunction')"
  1557. }
  1558. end,
  1559. ["rad"] = function(argString)
  1560. local num = tonumber(argString)
  1561. if not num then return end
  1562.  
  1563. if not service.Players.LocalPlayer.Character or not service.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart") or not service.Players.LocalPlayer.Character.HumanoidRootPart:IsA("BasePart") then return end
  1564.  
  1565. return {
  1566. Headers = {"local isa = game.IsA", "local hrp = service.Players.LocalPlayer.Character.HumanoidRootPart"},
  1567. Setups = {"local hrpPos = hrp.Position"},
  1568. ObjectDefs = {"local isBasePart = isa(obj,'BasePart')"},
  1569. Predicate = "(isBasePart and (obj.Position-hrpPos).Magnitude <= "..num..")"
  1570. }
  1571. end,
  1572. },
  1573. Specific = {
  1574. ["players"] = function()
  1575. return function() return service.Players:GetPlayers() end
  1576. end,
  1577. ["loadedmodules"] = function()
  1578. return env.getloadedmodules
  1579. end,
  1580. },
  1581. Default = function(argString,caseSensitive)
  1582. local cleanString = argString:gsub("\"","\\\""):gsub("\n","\\n")
  1583. if caseSensitive then
  1584. return {
  1585. Headers = {"local find = string.find"},
  1586. ObjectDefs = {"local objName = tostring(obj)"},
  1587. Predicate = "find(objName,\"" .. cleanString .. "\",1,true)"
  1588. }
  1589. else
  1590. return {
  1591. Headers = {"local lower = string.lower","local find = string.find","local tostring = tostring"},
  1592. ObjectDefs = {"local lowerName = lower(tostring(obj))"},
  1593. Predicate = "find(lowerName,\"" .. cleanString:lower() .. "\",1,true)"
  1594. }
  1595. end
  1596. end,
  1597. SpecificDefault = function(n)
  1598. return {
  1599. Headers = {},
  1600. ObjectDefs = {"local isSpec"..n.." = specResults["..n.."][node]"},
  1601. Predicate = "isSpec"..n
  1602. }
  1603. end,
  1604. }
  1605.  
  1606. Explorer.BuildSearchFunc = function(query)
  1607. local specFilterList,specMap = {},{}
  1608. local finalPredicate = ""
  1609. local rep = string.rep
  1610. local formatQuery = query:gsub("\\."," "):gsub('".-"',function(str) return rep(" ",#str) end)
  1611. local headers = {}
  1612. local objectDefs = {}
  1613. local setups = {}
  1614. local find = string.find
  1615. local sub = string.sub
  1616. local lower = string.lower
  1617. local match = string.match
  1618. local ops = {
  1619. ["("] = "(",
  1620. [")"] = ")",
  1621. ["||"] = " or ",
  1622. ["&&"] = " and "
  1623. }
  1624. local filterCount = 0
  1625. local compFilters = Explorer.SearchFilters.Comparison
  1626. local specFilters = Explorer.SearchFilters.Specific
  1627. local init = 1
  1628. local lastOp = nil
  1629.  
  1630. local function processFilter(dat)
  1631. if dat.Headers then
  1632. local t = dat.Headers
  1633. for i = 1,#t do
  1634. headers[t[i]] = true
  1635. end
  1636. end
  1637.  
  1638. if dat.ObjectDefs then
  1639. local t = dat.ObjectDefs
  1640. for i = 1,#t do
  1641. objectDefs[t[i]] = true
  1642. end
  1643. end
  1644.  
  1645. if dat.Setups then
  1646. local t = dat.Setups
  1647. for i = 1,#t do
  1648. setups[t[i]] = true
  1649. end
  1650. end
  1651.  
  1652. finalPredicate = finalPredicate..dat.Predicate
  1653. end
  1654.  
  1655. local found = {}
  1656. local foundData = {}
  1657. local find = string.find
  1658. local sub = string.sub
  1659.  
  1660. local function findAll(str,pattern)
  1661. local count = #found+1
  1662. local init = 1
  1663. local sz = #pattern
  1664. local x,y,extra = find(str,pattern,init,true)
  1665. while x do
  1666. found[count] = x
  1667. foundData[x] = {sz,pattern}
  1668.  
  1669. count = count+1
  1670. init = y+1
  1671. x,y,extra = find(str,pattern,init,true)
  1672. end
  1673. end
  1674. local start = tick()
  1675. findAll(formatQuery,'&&')
  1676. findAll(formatQuery,"||")
  1677. findAll(formatQuery,"(")
  1678. findAll(formatQuery,")")
  1679. table.sort(found)
  1680. table.insert(found,#formatQuery+1)
  1681.  
  1682. local function inQuotes(str)
  1683. local len = #str
  1684. if sub(str,1,1) == '"' and sub(str,len,len) == '"' then
  1685. return sub(str,2,len-1)
  1686. end
  1687. end
  1688.  
  1689. for i = 1,#found do
  1690. local nextInd = found[i]
  1691. local nextData = foundData[nextInd] or {1}
  1692. local op = ops[nextData[2]]
  1693. local term = sub(query,init,nextInd-1)
  1694. term = match(term,"^%s*(.-)%s*$") or "" -- Trim
  1695.  
  1696. if #term > 0 then
  1697. if sub(term,1,1) == "!" then
  1698. term = sub(term,2)
  1699. finalPredicate = finalPredicate.."not "
  1700. end
  1701.  
  1702. local qTerm = inQuotes(term)
  1703. if qTerm then
  1704. processFilter(Explorer.SearchFilters.Default(qTerm,true))
  1705. else
  1706. local x,y = find(term,"%S+")
  1707. if x then
  1708. local first = sub(term,x,y)
  1709. local specifier = sub(first,1,1) == "/" and lower(sub(first,2))
  1710. local compFunc = specifier and compFilters[specifier]
  1711. local specFunc = specifier and specFilters[specifier]
  1712.  
  1713. if compFunc then
  1714. local argStr = sub(term,y+2)
  1715. local ret = compFunc(inQuotes(argStr) or argStr)
  1716. if ret then
  1717. processFilter(ret)
  1718. else
  1719. finalPredicate = finalPredicate.."false"
  1720. end
  1721. elseif specFunc then
  1722. local argStr = sub(term,y+2)
  1723. local ret = specFunc(inQuotes(argStr) or argStr)
  1724. if ret then
  1725. if not specMap[term] then
  1726. specFilterList[#specFilterList + 1] = ret
  1727. specMap[term] = #specFilterList
  1728. end
  1729. processFilter(Explorer.SearchFilters.SpecificDefault(specMap[term]))
  1730. else
  1731. finalPredicate = finalPredicate.."false"
  1732. end
  1733. else
  1734. processFilter(Explorer.SearchFilters.Default(term))
  1735. end
  1736. end
  1737. end
  1738. end
  1739.  
  1740. if op then
  1741. finalPredicate = finalPredicate..op
  1742. if op == "(" and (#term > 0 or lastOp == ")") then -- Handle bracket glitch
  1743. return
  1744. else
  1745. lastOp = op
  1746. end
  1747. end
  1748. init = nextInd+nextData[1]
  1749. end
  1750.  
  1751. local finalSetups = ""
  1752. local finalHeaders = ""
  1753. local finalObjectDefs = ""
  1754.  
  1755. for setup,_ in next,setups do finalSetups = finalSetups..setup.."\n" end
  1756. for header,_ in next,headers do finalHeaders = finalHeaders..header.."\n" end
  1757. for oDef,_ in next,objectDefs do finalObjectDefs = finalObjectDefs..oDef.."\n" end
  1758.  
  1759. local template = [==[
  1760. local searchResults = searchResults
  1761. local nodes = nodes
  1762. local expandTable = Explorer.SearchExpanded
  1763. local specResults = specResults
  1764. local service = service
  1765.  
  1766. %s
  1767. local function search(root)
  1768. %s
  1769.  
  1770. local expandedpar = false
  1771. for i = 1,#root do
  1772. local node = root[i]
  1773. local obj = node.Obj
  1774.  
  1775. %s
  1776.  
  1777. if %s then
  1778. expandTable[node] = 0
  1779. searchResults[node] = true
  1780. if not expandedpar then
  1781. local parnode = node.Parent
  1782. while parnode and (not searchResults[parnode] or expandTable[parnode] == 0) do
  1783. expandTable[parnode] = true
  1784. searchResults[parnode] = true
  1785. parnode = parnode.Parent
  1786. end
  1787. expandedpar = true
  1788. end
  1789. end
  1790.  
  1791. if #node > 0 then search(node) end
  1792. end
  1793. end
  1794. return search]==]
  1795.  
  1796. local funcStr = template:format(finalHeaders,finalSetups,finalObjectDefs,finalPredicate)
  1797. local s,func = pcall(loadstring,funcStr)
  1798. if not s or not func then return nil,specFilterList end
  1799.  
  1800. local env = setmetatable({["searchResults"] = searchResults, ["nodes"] = nodes, ["Explorer"] = Explorer, ["specResults"] = specResults,
  1801. ["service"] = service},{__index = getfenv()})
  1802. setfenv(func,env)
  1803.  
  1804. return func(),specFilterList
  1805. end
  1806.  
  1807. Explorer.DoSearch = function(query)
  1808. table.clear(Explorer.SearchExpanded)
  1809. table.clear(searchResults)
  1810. expanded = (#query == 0 and Explorer.Expanded or Explorer.SearchExpanded)
  1811. searchFunc = nil
  1812.  
  1813. if #query > 0 then
  1814. local expandTable = Explorer.SearchExpanded
  1815. local specFilters
  1816.  
  1817. local lower = string.lower
  1818. local find = string.find
  1819. local tostring = tostring
  1820.  
  1821. local lowerQuery = lower(query)
  1822.  
  1823. local function defaultSearch(root)
  1824. local expandedpar = false
  1825. for i = 1,#root do
  1826. local node = root[i]
  1827. local obj = node.Obj
  1828.  
  1829. if find(lower(tostring(obj)),lowerQuery,1,true) then
  1830. expandTable[node] = 0
  1831. searchResults[node] = true
  1832. if not expandedpar then
  1833. local parnode = node.Parent
  1834. while parnode and (not searchResults[parnode] or expandTable[parnode] == 0) do
  1835. expanded[parnode] = true
  1836. searchResults[parnode] = true
  1837. parnode = parnode.Parent
  1838. end
  1839. expandedpar = true
  1840. end
  1841. end
  1842.  
  1843. if #node > 0 then defaultSearch(node) end
  1844. end
  1845. end
  1846.  
  1847. if Main.Elevated then
  1848. local start = tick()
  1849. searchFunc,specFilters = Explorer.BuildSearchFunc(query)
  1850. --print("BUILD SEARCH",tick()-start)
  1851. else
  1852. searchFunc = defaultSearch
  1853. end
  1854.  
  1855. if specFilters then
  1856. table.clear(specResults)
  1857. for i = 1,#specFilters do -- Specific search filers that returns list of matches
  1858. local resMap = {}
  1859. specResults[i] = resMap
  1860. local objs = specFilters[i]()
  1861. for c = 1,#objs do
  1862. local node = nodes[objs[c]]
  1863. if node then
  1864. resMap[node] = true
  1865. end
  1866. end
  1867. end
  1868. end
  1869.  
  1870. if searchFunc then
  1871. local start = tick()
  1872. searchFunc(nodes[game])
  1873. searchFunc(nilNode)
  1874. --warn(tick()-start)
  1875. end
  1876. end
  1877.  
  1878. Explorer.ForceUpdate()
  1879. end
  1880.  
  1881. Explorer.ClearSearch = function()
  1882. Explorer.GuiElems.SearchBar.Text = ""
  1883. expanded = Explorer.Expanded
  1884. searchFunc = nil
  1885. end
  1886.  
  1887. Explorer.InitSearch = function()
  1888. local searchBox = Explorer.GuiElems.ToolBar.SearchFrame.SearchBox
  1889. Explorer.GuiElems.SearchBar = searchBox
  1890.  
  1891. Lib.ViewportTextBox.convert(searchBox)
  1892.  
  1893. searchBox.FocusLost:Connect(function()
  1894. Explorer.DoSearch(searchBox.Text)
  1895. end)
  1896. end
  1897.  
  1898. Explorer.InitEntryTemplate = function()
  1899. entryTemplate = create({
  1900. {1,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0,0,0),BackgroundTransparency=1,BorderColor3=Color3.new(0,0,0),Font=3,Name="Entry",Position=UDim2.new(0,1,0,1),Size=UDim2.new(0,250,0,20),Text="",TextSize=14,}},
  1901. {2,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BackgroundTransparency=1,BorderColor3=Color3.new(0.33725491166115,0.49019610881805,0.73725491762161),BorderSizePixel=0,Name="Indent",Parent={1},Position=UDim2.new(0,20,0,0),Size=UDim2.new(1,-20,1,0),}},
  1902. {3,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="EntryName",Parent={2},Position=UDim2.new(0,26,0,0),Size=UDim2.new(1,-26,1,0),Text="Workspace",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  1903. {4,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Font=3,Name="Expand",Parent={2},Position=UDim2.new(0,-20,0,0),Size=UDim2.new(0,20,0,20),Text="",TextSize=14,}},
  1904. {5,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642383285",ImageRectOffset=Vector2.new(144,16),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={4},Position=UDim2.new(0,2,0,2),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  1905. {6,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxasset://textures/ClassImages.png",ImageRectOffset=Vector2.new(304,0),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={2},Position=UDim2.new(0,4,0,2),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  1906. })
  1907.  
  1908. local sys = Lib.ClickSystem.new()
  1909. sys.AllowedButtons = {1,2}
  1910. sys.OnDown:Connect(function(item,combo,button)
  1911. local ind = table.find(listEntries,item)
  1912. if not ind then return end
  1913. local node = tree[ind + Explorer.Index]
  1914. if not node then return end
  1915.  
  1916. local entry = listEntries[ind]
  1917.  
  1918. if button == 1 then
  1919. if combo == 2 then
  1920. if node.Obj:IsA("LuaSourceContainer") then
  1921. ScriptViewer.ViewScript(node.Obj)
  1922. elseif #node > 0 and expanded[node] ~= 0 then
  1923. expanded[node] = not expanded[node]
  1924. Explorer.Update()
  1925. end
  1926. end
  1927.  
  1928. if Properties.SelectObject(node.Obj) then
  1929. sys.IsRenaming = false
  1930. return
  1931. end
  1932.  
  1933. sys.IsRenaming = selection.Map[node]
  1934.  
  1935. if Lib.IsShiftDown() then
  1936. if not selection.Piviot then return end
  1937.  
  1938. local fromIndex = table.find(tree,selection.Piviot)
  1939. local toIndex = table.find(tree,node)
  1940. if not fromIndex or not toIndex then return end
  1941. fromIndex,toIndex = math.min(fromIndex,toIndex),math.max(fromIndex,toIndex)
  1942.  
  1943. local sList = selection.List
  1944. for i = #sList,1,-1 do
  1945. local elem = sList[i]
  1946. if selection.ShiftSet[elem] then
  1947. selection.Map[elem] = nil
  1948. table.remove(sList,i)
  1949. end
  1950. end
  1951. selection.ShiftSet = {}
  1952. for i = fromIndex,toIndex do
  1953. local elem = tree[i]
  1954. if not selection.Map[elem] then
  1955. selection.ShiftSet[elem] = true
  1956. selection.Map[elem] = true
  1957. sList[#sList+1] = elem
  1958. end
  1959. end
  1960. selection.Changed:Fire()
  1961. elseif Lib.IsCtrlDown() then
  1962. selection.ShiftSet = {}
  1963. if selection.Map[node] then selection:Remove(node) else selection:Add(node) end
  1964. selection.Piviot = node
  1965. sys.IsRenaming = false
  1966. elseif not selection.Map[node] then
  1967. selection.ShiftSet = {}
  1968. selection:Set(node)
  1969. selection.Piviot = node
  1970. end
  1971. elseif button == 2 then
  1972. if Properties.SelectObject(node.Obj) then
  1973. return
  1974. end
  1975.  
  1976. if not Lib.IsCtrlDown() and not selection.Map[node] then
  1977. selection.ShiftSet = {}
  1978. selection:Set(node)
  1979. selection.Piviot = node
  1980. Explorer.Refresh()
  1981. end
  1982. end
  1983.  
  1984. Explorer.Refresh()
  1985. end)
  1986.  
  1987. sys.OnRelease:Connect(function(item,combo,button)
  1988. local ind = table.find(listEntries,item)
  1989. if not ind then return end
  1990. local node = tree[ind + Explorer.Index]
  1991. if not node then return end
  1992.  
  1993. if button == 1 then
  1994. if selection.Map[node] and not Lib.IsShiftDown() and not Lib.IsCtrlDown() then
  1995. selection.ShiftSet = {}
  1996. selection:Set(node)
  1997. selection.Piviot = node
  1998. Explorer.Refresh()
  1999. end
  2000.  
  2001. local id = sys.ClickId
  2002. Lib.FastWait(sys.ComboTime)
  2003. if combo == 1 and id == sys.ClickId and sys.IsRenaming and selection.Map[node] then
  2004. Explorer.SetRenamingNode(node)
  2005. end
  2006. elseif button == 2 then
  2007. Explorer.ShowRightClick()
  2008. end
  2009. end)
  2010. Explorer.ClickSystem = sys
  2011. end
  2012.  
  2013. Explorer.InitDelCleaner = function()
  2014. coroutine.wrap(function()
  2015. local fw = Lib.FastWait
  2016. while true do
  2017. local processed = false
  2018. local c = 0
  2019. for _,node in next,nodes do
  2020. if node.HasDel then
  2021. local delInd
  2022. for i = 1,#node do
  2023. if node[i].Del then
  2024. delInd = i
  2025. break
  2026. end
  2027. end
  2028. if delInd then
  2029. for i = delInd+1,#node do
  2030. local cn = node[i]
  2031. if not cn.Del then
  2032. node[delInd] = cn
  2033. delInd = delInd+1
  2034. end
  2035. end
  2036. for i = delInd,#node do
  2037. node[i] = nil
  2038. end
  2039. end
  2040. node.HasDel = false
  2041. processed = true
  2042. fw()
  2043. end
  2044. c = c + 1
  2045. if c > 10000 then
  2046. c = 0
  2047. fw()
  2048. end
  2049. end
  2050. if processed and not refreshDebounce then Explorer.PerformRefresh() end
  2051. fw(0.5)
  2052. end
  2053. end)()
  2054. end
  2055.  
  2056. Explorer.UpdateSelectionVisuals = function()
  2057. local holder = Explorer.SelectionVisualsHolder
  2058. local isa = game.IsA
  2059. local clone = game.Clone
  2060. if not holder then
  2061. holder = Instance.new("ScreenGui")
  2062. holder.Name = "ExplorerSelections"
  2063. holder.DisplayOrder = Main.DisplayOrders.Core
  2064. Lib.ShowGui(holder)
  2065. Explorer.SelectionVisualsHolder = holder
  2066. Explorer.SelectionVisualCons = {}
  2067.  
  2068. local guiTemplate = create({
  2069. {1,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Size=UDim2.new(0,100,0,100),}},
  2070. {2,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,-1,0,-1),Size=UDim2.new(1,2,0,1),}},
  2071. {3,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,-1,1,0),Size=UDim2.new(1,2,0,1),}},
  2072. {4,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,-1,0,0),Size=UDim2.new(0,1,1,0),}},
  2073. {5,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BorderSizePixel=0,Parent={1},Position=UDim2.new(1,0,0,0),Size=UDim2.new(0,1,1,0),}},
  2074. })
  2075. Explorer.SelectionVisualGui = guiTemplate
  2076.  
  2077. local boxTemplate = Instance.new("SelectionBox")
  2078. boxTemplate.LineThickness = 0.03
  2079. boxTemplate.Color3 = Color3.fromRGB(0, 170, 255)
  2080. Explorer.SelectionVisualBox = boxTemplate
  2081. end
  2082. holder:ClearAllChildren()
  2083.  
  2084. -- Updates theme
  2085. for i,v in pairs(Explorer.SelectionVisualGui:GetChildren()) do
  2086. v.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
  2087. end
  2088.  
  2089. local attachCons = Explorer.SelectionVisualCons
  2090. for i = 1,#attachCons do
  2091. attachCons[i].Destroy()
  2092. end
  2093. table.clear(attachCons)
  2094.  
  2095. local partEnabled = Settings.Explorer.PartSelectionBox
  2096. local guiEnabled = Settings.Explorer.GuiSelectionBox
  2097. if not partEnabled and not guiEnabled then return end
  2098.  
  2099. local svg = Explorer.SelectionVisualGui
  2100. local svb = Explorer.SelectionVisualBox
  2101. local attachTo = Lib.AttachTo
  2102. local sList = selection.List
  2103. local count = 1
  2104. local boxCount = 0
  2105. local workspaceNode = nodes[workspace]
  2106. for i = 1,#sList do
  2107. if boxCount > 1000 then break end
  2108. local node = sList[i]
  2109. local obj = node.Obj
  2110.  
  2111. if node ~= workspaceNode then
  2112. if isa(obj,"GuiObject") and guiEnabled then
  2113. local newVisual = clone(svg)
  2114. attachCons[count] = attachTo(newVisual,{Target = obj, Resize = true})
  2115. count = count + 1
  2116. newVisual.Parent = holder
  2117. boxCount = boxCount + 1
  2118. elseif isa(obj,"PVInstance") and partEnabled then
  2119. local newBox = clone(svb)
  2120. newBox.Adornee = obj
  2121. newBox.Parent = holder
  2122. boxCount = boxCount + 1
  2123. end
  2124. end
  2125. end
  2126. end
  2127.  
  2128. Explorer.Init = function()
  2129. Explorer.ClassIcons = Lib.IconMap.newLinear("rbxasset://textures/ClassImages.png",16,16)
  2130. Explorer.MiscIcons = Main.MiscIcons
  2131.  
  2132. clipboard = {}
  2133.  
  2134. selection = Lib.Set.new()
  2135. selection.ShiftSet = {}
  2136. selection.Changed:Connect(Properties.ShowExplorerProps)
  2137. Explorer.Selection = selection
  2138.  
  2139. Explorer.InitRightClick()
  2140. Explorer.InitInsertObject()
  2141. Explorer.SetSortingEnabled(Settings.Explorer.Sorting)
  2142. Explorer.Expanded = setmetatable({},{__mode = "k"})
  2143. Explorer.SearchExpanded = setmetatable({},{__mode = "k"})
  2144. expanded = Explorer.Expanded
  2145.  
  2146. nilNode.Obj.Name = "Nil Instances"
  2147. nilNode.Locked = true
  2148.  
  2149. local explorerItems = create({
  2150. {1,"Folder",{Name="ExplorerItems",}},
  2151. {2,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="ToolBar",Parent={1},Size=UDim2.new(1,0,0,22),}},
  2152. {3,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.1176470592618,0.1176470592618,0.1176470592618),BorderSizePixel=0,Name="SearchFrame",Parent={2},Position=UDim2.new(0,3,0,1),Size=UDim2.new(1,-6,0,18),}},
  2153. {4,"TextBox",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClearTextOnFocus=false,Font=3,Name="SearchBox",Parent={3},PlaceholderColor3=Color3.new(0.39215689897537,0.39215689897537,0.39215689897537),PlaceholderText="Search workspace",Position=UDim2.new(0,4,0,0),Size=UDim2.new(1,-24,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,}},
  2154. {5,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
  2155. {6,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Reset",Parent={3},Position=UDim2.new(1,-17,0,1),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  2156. {7,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034718129",ImageColor3=Color3.new(0.39215686917305,0.39215686917305,0.39215686917305),Parent={6},Size=UDim2.new(0,16,0,16),}},
  2157. {8,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Refresh",Parent={2},Position=UDim2.new(1,-20,0,1),Size=UDim2.new(0,18,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  2158. {9,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642310344",Parent={8},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,12,0,12),}},
  2159. {10,"Frame",{BackgroundColor3=Color3.new(0.15686275064945,0.15686275064945,0.15686275064945),BorderSizePixel=0,Name="ScrollCorner",Parent={1},Position=UDim2.new(1,-16,1,-16),Size=UDim2.new(0,16,0,16),Visible=false,}},
  2160. {11,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Name="List",Parent={1},Position=UDim2.new(0,0,0,23),Size=UDim2.new(1,0,1,-23),}},
  2161. })
  2162.  
  2163. toolBar = explorerItems.ToolBar
  2164. treeFrame = explorerItems.List
  2165.  
  2166. Explorer.GuiElems.ToolBar = toolBar
  2167. Explorer.GuiElems.TreeFrame = treeFrame
  2168.  
  2169. scrollV = Lib.ScrollBar.new()
  2170. scrollV.WheelIncrement = 3
  2171. scrollV.Gui.Position = UDim2.new(1,-16,0,23)
  2172. scrollV:SetScrollFrame(treeFrame)
  2173. scrollV.Scrolled:Connect(function()
  2174. Explorer.Index = scrollV.Index
  2175. Explorer.Refresh()
  2176. end)
  2177.  
  2178. scrollH = Lib.ScrollBar.new(true)
  2179. scrollH.Increment = 5
  2180. scrollH.WheelIncrement = Explorer.EntryIndent
  2181. scrollH.Gui.Position = UDim2.new(0,0,1,-16)
  2182. scrollH.Scrolled:Connect(function()
  2183. Explorer.Refresh()
  2184. end)
  2185.  
  2186. local window = Lib.Window.new()
  2187. Explorer.Window = window
  2188. window:SetTitle("Explorer")
  2189. window.GuiElems.Line.Position = UDim2.new(0,0,0,22)
  2190.  
  2191. Explorer.InitEntryTemplate()
  2192. toolBar.Parent = window.GuiElems.Content
  2193. treeFrame.Parent = window.GuiElems.Content
  2194. explorerItems.ScrollCorner.Parent = window.GuiElems.Content
  2195. scrollV.Gui.Parent = window.GuiElems.Content
  2196. scrollH.Gui.Parent = window.GuiElems.Content
  2197.  
  2198. -- Init stuff that requires the window
  2199. Explorer.InitRenameBox()
  2200. Explorer.InitSearch()
  2201. Explorer.InitDelCleaner()
  2202. selection.Changed:Connect(Explorer.UpdateSelectionVisuals)
  2203.  
  2204. -- Window events
  2205. window.GuiElems.Main:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  2206. if Explorer.Active then
  2207. Explorer.UpdateView()
  2208. Explorer.Refresh()
  2209. end
  2210. end)
  2211. window.OnActivate:Connect(function()
  2212. Explorer.Active = true
  2213. Explorer.UpdateView()
  2214. Explorer.Update()
  2215. Explorer.Refresh()
  2216. end)
  2217. window.OnRestore:Connect(function()
  2218. Explorer.Active = true
  2219. Explorer.UpdateView()
  2220. Explorer.Update()
  2221. Explorer.Refresh()
  2222. end)
  2223. window.OnDeactivate:Connect(function() Explorer.Active = false end)
  2224. window.OnMinimize:Connect(function() Explorer.Active = false end)
  2225.  
  2226. -- Settings
  2227. autoUpdateSearch = Settings.Explorer.AutoUpdateSearch
  2228.  
  2229.  
  2230. -- Fill in nodes
  2231. nodes[game] = {Obj = game}
  2232. expanded[nodes[game]] = true
  2233.  
  2234. -- Nil Instances
  2235. if env.getnilinstances then
  2236. nodes[nilNode.Obj] = nilNode
  2237. end
  2238.  
  2239. Explorer.SetupConnections()
  2240.  
  2241. local insts = getDescendants(game)
  2242. if Main.Elevated then
  2243. for i = 1,#insts do
  2244. local obj = insts[i]
  2245. local par = nodes[ffa(obj,"Instance")]
  2246. if not par then continue end
  2247. local newNode = {
  2248. Obj = obj,
  2249. Parent = par,
  2250. }
  2251. nodes[obj] = newNode
  2252. par[#par+1] = newNode
  2253. end
  2254. else
  2255. for i = 1,#insts do
  2256. local obj = insts[i]
  2257. local s,parObj = pcall(ffa,obj,"Instance")
  2258. local par = nodes[parObj]
  2259. if not par then continue end
  2260. local newNode = {
  2261. Obj = obj,
  2262. Parent = par,
  2263. }
  2264. nodes[obj] = newNode
  2265. par[#par+1] = newNode
  2266. end
  2267. end
  2268. end
  2269.  
  2270. return Explorer
  2271. end
  2272.  
  2273. return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  2274. end,
  2275. Properties = function()
  2276. --[[
  2277. Properties App Module
  2278.  
  2279. The main properties interface
  2280. ]]
  2281.  
  2282. -- Common Locals
  2283. local Main,Lib,Apps,Settings -- Main Containers
  2284. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  2285. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  2286.  
  2287. local function initDeps(data)
  2288. Main = data.Main
  2289. Lib = data.Lib
  2290. Apps = data.Apps
  2291. Settings = data.Settings
  2292.  
  2293. API = data.API
  2294. RMD = data.RMD
  2295. env = data.env
  2296. service = data.service
  2297. plr = data.plr
  2298. create = data.create
  2299. createSimple = data.createSimple
  2300. end
  2301.  
  2302. local function initAfterMain()
  2303. Explorer = Apps.Explorer
  2304. Properties = Apps.Properties
  2305. ScriptViewer = Apps.ScriptViewer
  2306. Notebook = Apps.Notebook
  2307. end
  2308.  
  2309. local function main()
  2310. local Properties = {}
  2311.  
  2312. local window, toolBar, propsFrame
  2313. local scrollV, scrollH
  2314. local categoryOrder
  2315. local props,viewList,expanded,indexableProps,propEntries,autoUpdateObjs = {},{},{},{},{},{}
  2316. local inputBox,inputTextBox,inputProp
  2317. local checkboxes,propCons = {},{}
  2318. local table,string = table,string
  2319. local getPropChangedSignal = game.GetPropertyChangedSignal
  2320. local getAttributeChangedSignal = game.GetAttributeChangedSignal
  2321. local isa = game.IsA
  2322. local getAttribute = game.GetAttribute
  2323. local setAttribute = game.SetAttribute
  2324.  
  2325. Properties.GuiElems = {}
  2326. Properties.Index = 0
  2327. Properties.ViewWidth = 0
  2328. Properties.MinInputWidth = 100
  2329. Properties.EntryIndent = 16
  2330. Properties.EntryOffset = 4
  2331. Properties.NameWidthCache = {}
  2332. Properties.SubPropCache = {}
  2333. Properties.ClassLists = {}
  2334. Properties.SearchText = ""
  2335.  
  2336. Properties.AddAttributeProp = {Category = "Attributes", Class = "", Name = "", SpecialRow = "AddAttribute", Tags = {}}
  2337. Properties.SoundPreviewProp = {Category = "Data", ValueType = {Name = "SoundPlayer"}, Class = "Sound", Name = "Preview", Tags = {}}
  2338.  
  2339. Properties.IgnoreProps = {
  2340. ["DataModel"] = {
  2341. ["PrivateServerId"] = true,
  2342. ["PrivateServerOwnerId"] = true,
  2343. ["VIPServerId"] = true,
  2344. ["VIPServerOwnerId"] = true
  2345. }
  2346. }
  2347.  
  2348. Properties.ExpandableTypes = {
  2349. ["Vector2"] = true,
  2350. ["Vector3"] = true,
  2351. ["UDim"] = true,
  2352. ["UDim2"] = true,
  2353. ["CFrame"] = true,
  2354. ["Rect"] = true,
  2355. ["PhysicalProperties"] = true,
  2356. ["Ray"] = true,
  2357. ["NumberRange"] = true,
  2358. ["Faces"] = true,
  2359. ["Axes"] = true,
  2360. }
  2361.  
  2362. Properties.ExpandableProps = {
  2363. ["Sound.SoundId"] = true
  2364. }
  2365.  
  2366. Properties.CollapsedCategories = {
  2367. ["Surface Inputs"] = true,
  2368. ["Surface"] = true
  2369. }
  2370.  
  2371. Properties.ConflictSubProps = {
  2372. ["Vector2"] = {"X","Y"},
  2373. ["Vector3"] = {"X","Y","Z"},
  2374. ["UDim"] = {"Scale","Offset"},
  2375. ["UDim2"] = {"X","X.Scale","X.Offset","Y","Y.Scale","Y.Offset"},
  2376. ["CFrame"] = {"Position","Position.X","Position.Y","Position.Z",
  2377. "RightVector","RightVector.X","RightVector.Y","RightVector.Z",
  2378. "UpVector","UpVector.X","UpVector.Y","UpVector.Z",
  2379. "LookVector","LookVector.X","LookVector.Y","LookVector.Z"},
  2380. ["Rect"] = {"Min.X","Min.Y","Max.X","Max.Y"},
  2381. ["PhysicalProperties"] = {"Density","Elasticity","ElasticityWeight","Friction","FrictionWeight"},
  2382. ["Ray"] = {"Origin","Origin.X","Origin.Y","Origin.Z","Direction","Direction.X","Direction.Y","Direction.Z"},
  2383. ["NumberRange"] = {"Min","Max"},
  2384. ["Faces"] = {"Back","Bottom","Front","Left","Right","Top"},
  2385. ["Axes"] = {"X","Y","Z"}
  2386. }
  2387.  
  2388. Properties.ConflictIgnore = {
  2389. ["BasePart"] = {
  2390. ["ResizableFaces"] = true
  2391. }
  2392. }
  2393.  
  2394. Properties.RoundableTypes = {
  2395. ["float"] = true,
  2396. ["double"] = true,
  2397. ["Color3"] = true,
  2398. ["UDim"] = true,
  2399. ["UDim2"] = true,
  2400. ["Vector2"] = true,
  2401. ["Vector3"] = true,
  2402. ["NumberRange"] = true,
  2403. ["Rect"] = true,
  2404. ["NumberSequence"] = true,
  2405. ["ColorSequence"] = true,
  2406. ["Ray"] = true,
  2407. ["CFrame"] = true
  2408. }
  2409.  
  2410. Properties.TypeNameConvert = {
  2411. ["number"] = "double",
  2412. ["boolean"] = "bool"
  2413. }
  2414.  
  2415. Properties.ToNumberTypes = {
  2416. ["int"] = true,
  2417. ["int64"] = true,
  2418. ["float"] = true,
  2419. ["double"] = true
  2420. }
  2421.  
  2422. Properties.DefaultPropValue = {
  2423. string = "",
  2424. bool = false,
  2425. double = 0,
  2426. UDim = UDim.new(0,0),
  2427. UDim2 = UDim2.new(0,0,0,0),
  2428. BrickColor = BrickColor.new("Medium stone grey"),
  2429. Color3 = Color3.new(1,1,1),
  2430. Vector2 = Vector2.new(0,0),
  2431. Vector3 = Vector3.new(0,0,0),
  2432. NumberSequence = NumberSequence.new(1),
  2433. ColorSequence = ColorSequence.new(Color3.new(1,1,1)),
  2434. NumberRange = NumberRange.new(0),
  2435. Rect = Rect.new(0,0,0,0)
  2436. }
  2437.  
  2438. Properties.AllowedAttributeTypes = {"string","boolean","number","UDim","UDim2","BrickColor","Color3","Vector2","Vector3","NumberSequence","ColorSequence","NumberRange","Rect"}
  2439.  
  2440. Properties.StringToValue = function(prop,str)
  2441. local typeData = prop.ValueType
  2442. local typeName = typeData.Name
  2443.  
  2444. if typeName == "string" or typeName == "Content" then
  2445. return str
  2446. elseif Properties.ToNumberTypes[typeName] then
  2447. return tonumber(str)
  2448. elseif typeName == "Vector2" then
  2449. local vals = str:split(",")
  2450. local x,y = tonumber(vals[1]),tonumber(vals[2])
  2451. if x and y and #vals >= 2 then return Vector2.new(x,y) end
  2452. elseif typeName == "Vector3" then
  2453. local vals = str:split(",")
  2454. local x,y,z = tonumber(vals[1]),tonumber(vals[2]),tonumber(vals[3])
  2455. if x and y and z and #vals >= 3 then return Vector3.new(x,y,z) end
  2456. elseif typeName == "UDim" then
  2457. local vals = str:split(",")
  2458. local scale,offset = tonumber(vals[1]),tonumber(vals[2])
  2459. if scale and offset and #vals >= 2 then return UDim.new(scale,offset) end
  2460. elseif typeName == "UDim2" then
  2461. local vals = str:gsub("[{}]",""):split(",")
  2462. local xScale,xOffset,yScale,yOffset = tonumber(vals[1]),tonumber(vals[2]),tonumber(vals[3]),tonumber(vals[4])
  2463. if xScale and xOffset and yScale and yOffset and #vals >= 4 then return UDim2.new(xScale,xOffset,yScale,yOffset) end
  2464. elseif typeName == "CFrame" then
  2465. local vals = str:split(",")
  2466. local s,result = pcall(CFrame.new,unpack(vals))
  2467. if s and #vals >= 12 then return result end
  2468. elseif typeName == "Rect" then
  2469. local vals = str:split(",")
  2470. local s,result = pcall(Rect.new,unpack(vals))
  2471. if s and #vals >= 4 then return result end
  2472. elseif typeName == "Ray" then
  2473. local vals = str:gsub("[{}]",""):split(",")
  2474. local s,origin = pcall(Vector3.new,unpack(vals,1,3))
  2475. local s2,direction = pcall(Vector3.new,unpack(vals,4,6))
  2476. if s and s2 and #vals >= 6 then return Ray.new(origin,direction) end
  2477. elseif typeName == "NumberRange" then
  2478. local vals = str:split(",")
  2479. local s,result = pcall(NumberRange.new,unpack(vals))
  2480. if s and #vals >= 1 then return result end
  2481. elseif typeName == "Color3" then
  2482. local vals = str:gsub("[{}]",""):split(",")
  2483. local s,result = pcall(Color3.fromRGB,unpack(vals))
  2484. if s and #vals >= 3 then return result end
  2485. end
  2486.  
  2487. return nil
  2488. end
  2489.  
  2490. Properties.ValueToString = function(prop,val)
  2491. local typeData = prop.ValueType
  2492. local typeName = typeData.Name
  2493.  
  2494. if typeName == "Color3" then
  2495. return Lib.ColorToBytes(val)
  2496. elseif typeName == "NumberRange" then
  2497. return val.Min..", "..val.Max
  2498. end
  2499.  
  2500. return tostring(val)
  2501. end
  2502.  
  2503. Properties.GetIndexableProps = function(obj,classData)
  2504. if not Main.Elevated then
  2505. if not pcall(function() return obj.ClassName end) then return nil end
  2506. end
  2507.  
  2508. local ignoreProps = Properties.IgnoreProps[classData.Name] or {}
  2509.  
  2510. local result = {}
  2511. local count = 1
  2512. local props = classData.Properties
  2513. for i = 1,#props do
  2514. local prop = props[i]
  2515. if not ignoreProps[prop.Name] then
  2516. local s = pcall(function() return obj[prop.Name] end)
  2517. if s then
  2518. result[count] = prop
  2519. count = count + 1
  2520. end
  2521. end
  2522. end
  2523.  
  2524. return result
  2525. end
  2526.  
  2527. Properties.FindFirstObjWhichIsA = function(class)
  2528. local classList = Properties.ClassLists[class] or {}
  2529. if classList and #classList > 0 then
  2530. return classList[1]
  2531. end
  2532.  
  2533. return nil
  2534. end
  2535.  
  2536. Properties.ComputeConflicts = function(p)
  2537. local maxConflictCheck = Settings.Properties.MaxConflictCheck
  2538. local sList = Explorer.Selection.List
  2539. local classLists = Properties.ClassLists
  2540. local stringSplit = string.split
  2541. local t_clear = table.clear
  2542. local conflictIgnore = Properties.ConflictIgnore
  2543. local conflictMap = {}
  2544. local propList = p and {p} or props
  2545.  
  2546. if p then
  2547. local gName = p.Class.."."..p.Name
  2548. autoUpdateObjs[gName] = nil
  2549. local subProps = Properties.ConflictSubProps[p.ValueType.Name] or {}
  2550. for i = 1,#subProps do
  2551. autoUpdateObjs[gName.."."..subProps[i]] = nil
  2552. end
  2553. else
  2554. table.clear(autoUpdateObjs)
  2555. end
  2556.  
  2557. if #sList > 0 then
  2558. for i = 1,#propList do
  2559. local prop = propList[i]
  2560. local propName,propClass = prop.Name,prop.Class
  2561. local typeData = prop.RootType or prop.ValueType
  2562. local typeName = typeData.Name
  2563. local attributeName = prop.AttributeName
  2564. local gName = propClass.."."..propName
  2565.  
  2566. local checked = 0
  2567. local subProps = Properties.ConflictSubProps[typeName] or {}
  2568. local subPropCount = #subProps
  2569. local toCheck = subPropCount + 1
  2570. local conflictsFound = 0
  2571. local indexNames = {}
  2572. local ignored = conflictIgnore[propClass] and conflictIgnore[propClass][propName]
  2573. local truthyCheck = (typeName == "PhysicalProperties")
  2574. local isAttribute = prop.IsAttribute
  2575. local isMultiType = prop.MultiType
  2576.  
  2577. t_clear(conflictMap)
  2578.  
  2579. if not isMultiType then
  2580. local firstVal,firstObj,firstSet
  2581. local classList = classLists[prop.Class] or {}
  2582. for c = 1,#classList do
  2583. local obj = classList[c]
  2584. if not firstSet then
  2585. if isAttribute then
  2586. firstVal = getAttribute(obj,attributeName)
  2587. if firstVal ~= nil then
  2588. firstObj = obj
  2589. firstSet = true
  2590. end
  2591. else
  2592. firstVal = obj[propName]
  2593. firstObj = obj
  2594. firstSet = true
  2595. end
  2596. if ignored then break end
  2597. else
  2598. local propVal,skip
  2599. if isAttribute then
  2600. propVal = getAttribute(obj,attributeName)
  2601. if propVal == nil then skip = true end
  2602. else
  2603. propVal = obj[propName]
  2604. end
  2605.  
  2606. if not skip then
  2607. if not conflictMap[1] then
  2608. if truthyCheck then
  2609. if (firstVal and true or false) ~= (propVal and true or false) then
  2610. conflictMap[1] = true
  2611. conflictsFound = conflictsFound + 1
  2612. end
  2613. elseif firstVal ~= propVal then
  2614. conflictMap[1] = true
  2615. conflictsFound = conflictsFound + 1
  2616. end
  2617. end
  2618.  
  2619. if subPropCount > 0 then
  2620. for sPropInd = 1,subPropCount do
  2621. local indexes = indexNames[sPropInd]
  2622. if not indexes then indexes = stringSplit(subProps[sPropInd],".") indexNames[sPropInd] = indexes end
  2623.  
  2624. local firstValSub = firstVal
  2625. local propValSub = propVal
  2626.  
  2627. for j = 1,#indexes do
  2628. if not firstValSub or not propValSub then break end -- PhysicalProperties
  2629. local indexName = indexes[j]
  2630. firstValSub = firstValSub[indexName]
  2631. propValSub = propValSub[indexName]
  2632. end
  2633.  
  2634. local mapInd = sPropInd + 1
  2635. if not conflictMap[mapInd] and firstValSub ~= propValSub then
  2636. conflictMap[mapInd] = true
  2637. conflictsFound = conflictsFound + 1
  2638. end
  2639. end
  2640. end
  2641.  
  2642. if conflictsFound == toCheck then break end
  2643. end
  2644. end
  2645.  
  2646. checked = checked + 1
  2647. if checked == maxConflictCheck then break end
  2648. end
  2649.  
  2650. if not conflictMap[1] then autoUpdateObjs[gName] = firstObj end
  2651. for sPropInd = 1,subPropCount do
  2652. if not conflictMap[sPropInd+1] then
  2653. autoUpdateObjs[gName.."."..subProps[sPropInd]] = firstObj
  2654. end
  2655. end
  2656. end
  2657. end
  2658. end
  2659.  
  2660. if p then
  2661. Properties.Refresh()
  2662. end
  2663. end
  2664.  
  2665. -- Fetches the properties to be displayed based on the explorer selection
  2666. Settings.Properties.ShowAttributes = true -- im making it true anyway since its useful by default and people complain
  2667. Properties.ShowExplorerProps = function()
  2668. local maxConflictCheck = Settings.Properties.MaxConflictCheck
  2669. local sList = Explorer.Selection.List
  2670. local foundClasses = {}
  2671. local propCount = 1
  2672. local elevated = Main.Elevated
  2673. local showDeprecated,showHidden = Settings.Properties.ShowDeprecated,Settings.Properties.ShowHidden
  2674. local Classes = API.Classes
  2675. local classLists = {}
  2676. local lower = string.lower
  2677. local RMDCustomOrders = RMD.PropertyOrders
  2678. local getAttributes = game.GetAttributes
  2679. local maxAttrs = Settings.Properties.MaxAttributes
  2680. local showingAttrs = Settings.Properties.ShowAttributes
  2681. local foundAttrs = {}
  2682. local attrCount = 0
  2683. local typeof = typeof
  2684. local typeNameConvert = Properties.TypeNameConvert
  2685.  
  2686. table.clear(props)
  2687.  
  2688. for i = 1,#sList do
  2689. local node = sList[i]
  2690. local obj = node.Obj
  2691. local class = node.Class
  2692. if not class then class = obj.ClassName node.Class = class end
  2693.  
  2694. local apiClass = Classes[class]
  2695. while apiClass do
  2696. local APIClassName = apiClass.Name
  2697. if not foundClasses[APIClassName] then
  2698. local apiProps = indexableProps[APIClassName]
  2699. if not apiProps then apiProps = Properties.GetIndexableProps(obj,apiClass) indexableProps[APIClassName] = apiProps end
  2700.  
  2701. for i = 1,#apiProps do
  2702. local prop = apiProps[i]
  2703. local tags = prop.Tags
  2704. if (not tags.Deprecated or showDeprecated) and (not tags.Hidden or showHidden) then
  2705. props[propCount] = prop
  2706. propCount = propCount + 1
  2707. end
  2708. end
  2709. foundClasses[APIClassName] = true
  2710. end
  2711.  
  2712. local classList = classLists[APIClassName]
  2713. if not classList then classList = {} classLists[APIClassName] = classList end
  2714. classList[#classList+1] = obj
  2715.  
  2716. apiClass = apiClass.Superclass
  2717. end
  2718.  
  2719. if showingAttrs and attrCount < maxAttrs then
  2720. local attrs = getAttributes(obj)
  2721. for name,val in pairs(attrs) do
  2722. local typ = typeof(val)
  2723. if not foundAttrs[name] then
  2724. local category = (typ == "Instance" and "Class") or (typ == "EnumItem" and "Enum") or "Other"
  2725. local valType = {Name = typeNameConvert[typ] or typ, Category = category}
  2726. local attrProp = {IsAttribute = true, Name = "ATTR_"..name, AttributeName = name, DisplayName = name, Class = "Instance", ValueType = valType, Category = "Attributes", Tags = {}}
  2727. props[propCount] = attrProp
  2728. propCount = propCount + 1
  2729. attrCount = attrCount + 1
  2730. foundAttrs[name] = {typ,attrProp}
  2731. if attrCount == maxAttrs then break end
  2732. elseif foundAttrs[name][1] ~= typ then
  2733. foundAttrs[name][2].MultiType = true
  2734. foundAttrs[name][2].Tags.ReadOnly = true
  2735. foundAttrs[name][2].ValueType = {Name = "string"}
  2736. end
  2737. end
  2738. end
  2739. end
  2740.  
  2741. table.sort(props,function(a,b)
  2742. if a.Category ~= b.Category then
  2743. return (categoryOrder[a.Category] or 9999) < (categoryOrder[b.Category] or 9999)
  2744. else
  2745. local aOrder = (RMDCustomOrders[a.Class] and RMDCustomOrders[a.Class][a.Name]) or 9999999
  2746. local bOrder = (RMDCustomOrders[b.Class] and RMDCustomOrders[b.Class][b.Name]) or 9999999
  2747. if aOrder ~= bOrder then
  2748. return aOrder < bOrder
  2749. else
  2750. return lower(a.Name) < lower(b.Name)
  2751. end
  2752. end
  2753. end)
  2754.  
  2755. -- Find conflicts and get auto-update instances
  2756. Properties.ClassLists = classLists
  2757. Properties.ComputeConflicts()
  2758. --warn("CONFLICT",tick()-start)
  2759. if #props > 0 then
  2760. props[#props+1] = Properties.AddAttributeProp
  2761. end
  2762.  
  2763. Properties.Update()
  2764. Properties.Refresh()
  2765. end
  2766.  
  2767. Properties.UpdateView = function()
  2768. local maxEntries = math.ceil(propsFrame.AbsoluteSize.Y / 23)
  2769. local maxX = propsFrame.AbsoluteSize.X
  2770. local totalWidth = Properties.ViewWidth + Properties.MinInputWidth
  2771.  
  2772. scrollV.VisibleSpace = maxEntries
  2773. scrollV.TotalSpace = #viewList + 1
  2774. scrollH.VisibleSpace = maxX
  2775. scrollH.TotalSpace = totalWidth
  2776.  
  2777. scrollV.Gui.Visible = #viewList + 1 > maxEntries
  2778. scrollH.Gui.Visible = Settings.Properties.ScaleType == 0 and totalWidth > maxX
  2779.  
  2780. local oldSize = propsFrame.Size
  2781. propsFrame.Size = UDim2.new(1,(scrollV.Gui.Visible and -16 or 0),1,(scrollH.Gui.Visible and -39 or -23))
  2782. if oldSize ~= propsFrame.Size then
  2783. Properties.UpdateView()
  2784. else
  2785. scrollV:Update()
  2786. scrollH:Update()
  2787.  
  2788. if scrollV.Gui.Visible and scrollH.Gui.Visible then
  2789. scrollV.Gui.Size = UDim2.new(0,16,1,-39)
  2790. scrollH.Gui.Size = UDim2.new(1,-16,0,16)
  2791. Properties.Window.GuiElems.Content.ScrollCorner.Visible = true
  2792. else
  2793. scrollV.Gui.Size = UDim2.new(0,16,1,-23)
  2794. scrollH.Gui.Size = UDim2.new(1,0,0,16)
  2795. Properties.Window.GuiElems.Content.ScrollCorner.Visible = false
  2796. end
  2797.  
  2798. Properties.Index = scrollV.Index
  2799. end
  2800. end
  2801.  
  2802. Properties.MakeSubProp = function(prop,subName,valueType,displayName)
  2803. local subProp = {}
  2804. for i,v in pairs(prop) do
  2805. subProp[i] = v
  2806. end
  2807. subProp.RootType = subProp.RootType or subProp.ValueType
  2808. subProp.ValueType = valueType
  2809. subProp.SubName = subProp.SubName and (subProp.SubName..subName) or subName
  2810. subProp.DisplayName = displayName
  2811.  
  2812. return subProp
  2813. end
  2814.  
  2815. Properties.GetExpandedProps = function(prop) -- TODO: Optimize using table
  2816. local result = {}
  2817. local typeData = prop.ValueType
  2818. local typeName = typeData.Name
  2819. local makeSubProp = Properties.MakeSubProp
  2820.  
  2821. if typeName == "Vector2" then
  2822. result[1] = makeSubProp(prop,".X",{Name = "float"})
  2823. result[2] = makeSubProp(prop,".Y",{Name = "float"})
  2824. elseif typeName == "Vector3" then
  2825. result[1] = makeSubProp(prop,".X",{Name = "float"})
  2826. result[2] = makeSubProp(prop,".Y",{Name = "float"})
  2827. result[3] = makeSubProp(prop,".Z",{Name = "float"})
  2828. elseif typeName == "CFrame" then
  2829. result[1] = makeSubProp(prop,".Position",{Name = "Vector3"})
  2830. result[2] = makeSubProp(prop,".RightVector",{Name = "Vector3"})
  2831. result[3] = makeSubProp(prop,".UpVector",{Name = "Vector3"})
  2832. result[4] = makeSubProp(prop,".LookVector",{Name = "Vector3"})
  2833. elseif typeName == "UDim" then
  2834. result[1] = makeSubProp(prop,".Scale",{Name = "float"})
  2835. result[2] = makeSubProp(prop,".Offset",{Name = "int"})
  2836. elseif typeName == "UDim2" then
  2837. result[1] = makeSubProp(prop,".X",{Name = "UDim"})
  2838. result[2] = makeSubProp(prop,".Y",{Name = "UDim"})
  2839. elseif typeName == "Rect" then
  2840. result[1] = makeSubProp(prop,".Min.X",{Name = "float"},"X0")
  2841. result[2] = makeSubProp(prop,".Min.Y",{Name = "float"},"Y0")
  2842. result[3] = makeSubProp(prop,".Max.X",{Name = "float"},"X1")
  2843. result[4] = makeSubProp(prop,".Max.Y",{Name = "float"},"Y1")
  2844. elseif typeName == "PhysicalProperties" then
  2845. result[1] = makeSubProp(prop,".Density",{Name = "float"})
  2846. result[2] = makeSubProp(prop,".Elasticity",{Name = "float"})
  2847. result[3] = makeSubProp(prop,".ElasticityWeight",{Name = "float"})
  2848. result[4] = makeSubProp(prop,".Friction",{Name = "float"})
  2849. result[5] = makeSubProp(prop,".FrictionWeight",{Name = "float"})
  2850. elseif typeName == "Ray" then
  2851. result[1] = makeSubProp(prop,".Origin",{Name = "Vector3"})
  2852. result[2] = makeSubProp(prop,".Direction",{Name = "Vector3"})
  2853. elseif typeName == "NumberRange" then
  2854. result[1] = makeSubProp(prop,".Min",{Name = "float"})
  2855. result[2] = makeSubProp(prop,".Max",{Name = "float"})
  2856. elseif typeName == "Faces" then
  2857. result[1] = makeSubProp(prop,".Back",{Name = "bool"})
  2858. result[2] = makeSubProp(prop,".Bottom",{Name = "bool"})
  2859. result[3] = makeSubProp(prop,".Front",{Name = "bool"})
  2860. result[4] = makeSubProp(prop,".Left",{Name = "bool"})
  2861. result[5] = makeSubProp(prop,".Right",{Name = "bool"})
  2862. result[6] = makeSubProp(prop,".Top",{Name = "bool"})
  2863. elseif typeName == "Axes" then
  2864. result[1] = makeSubProp(prop,".X",{Name = "bool"})
  2865. result[2] = makeSubProp(prop,".Y",{Name = "bool"})
  2866. result[3] = makeSubProp(prop,".Z",{Name = "bool"})
  2867. end
  2868.  
  2869. if prop.Name == "SoundId" and prop.Class == "Sound" then
  2870. result[1] = Properties.SoundPreviewProp
  2871. end
  2872.  
  2873. return result
  2874. end
  2875.  
  2876. Properties.Update = function()
  2877. table.clear(viewList)
  2878.  
  2879. local nameWidthCache = Properties.NameWidthCache
  2880. local lastCategory
  2881. local count = 1
  2882. local maxWidth,maxDepth = 0,1
  2883.  
  2884. local textServ = service.TextService
  2885. local getTextSize = textServ.GetTextSize
  2886. local font = Enum.Font.SourceSans
  2887. local size = Vector2.new(math.huge,20)
  2888. local stringSplit = string.split
  2889. local entryIndent = Properties.EntryIndent
  2890. local isFirstScaleType = Settings.Properties.ScaleType == 0
  2891. local find,lower = string.find,string.lower
  2892. local searchText = (#Properties.SearchText > 0 and lower(Properties.SearchText))
  2893.  
  2894. local function recur(props,depth)
  2895. for i = 1,#props do
  2896. local prop = props[i]
  2897. local propName = prop.Name
  2898. local subName = prop.SubName
  2899. local category = prop.Category
  2900.  
  2901. local visible
  2902. if searchText and depth == 1 then
  2903. if find(lower(propName),searchText,1,true) then
  2904. visible = true
  2905. end
  2906. else
  2907. visible = true
  2908. end
  2909.  
  2910. if visible and lastCategory ~= category then
  2911. viewList[count] = {CategoryName = category}
  2912. count = count + 1
  2913. lastCategory = category
  2914. end
  2915.  
  2916. if (expanded["CAT_"..category] and visible) or prop.SpecialRow then
  2917. if depth > 1 then prop.Depth = depth if depth > maxDepth then maxDepth = depth end end
  2918.  
  2919. if isFirstScaleType then
  2920. local nameArr = subName and stringSplit(subName,".")
  2921. local displayName = prop.DisplayName or (nameArr and nameArr[#nameArr]) or propName
  2922.  
  2923. local nameWidth = nameWidthCache[displayName]
  2924. if not nameWidth then nameWidth = getTextSize(textServ,displayName,14,font,size).X nameWidthCache[displayName] = nameWidth end
  2925.  
  2926. local totalWidth = nameWidth + entryIndent*depth
  2927. if totalWidth > maxWidth then
  2928. maxWidth = totalWidth
  2929. end
  2930. end
  2931.  
  2932. viewList[count] = prop
  2933. count = count + 1
  2934.  
  2935. local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  2936. if expanded[fullName] then
  2937. local nextDepth = depth+1
  2938. local expandedProps = Properties.GetExpandedProps(prop)
  2939. if #expandedProps > 0 then
  2940. recur(expandedProps,nextDepth)
  2941. end
  2942. end
  2943. end
  2944. end
  2945. end
  2946. recur(props,1)
  2947.  
  2948. inputProp = nil
  2949. Properties.ViewWidth = maxWidth + 9 + Properties.EntryOffset
  2950. Properties.UpdateView()
  2951. end
  2952.  
  2953. Properties.NewPropEntry = function(index)
  2954. local newEntry = Properties.EntryTemplate:Clone()
  2955. local nameFrame = newEntry.NameFrame
  2956. local valueFrame = newEntry.ValueFrame
  2957. local newCheckbox = Lib.Checkbox.new(1)
  2958. newCheckbox.Gui.Position = UDim2.new(0,3,0,3)
  2959. newCheckbox.Gui.Parent = valueFrame
  2960. newCheckbox.OnInput:Connect(function()
  2961. local prop = viewList[index + Properties.Index]
  2962. if not prop then return end
  2963.  
  2964. if prop.ValueType.Name == "PhysicalProperties" then
  2965. Properties.SetProp(prop,newCheckbox.Toggled and true or nil)
  2966. else
  2967. Properties.SetProp(prop,newCheckbox.Toggled)
  2968. end
  2969. end)
  2970. checkboxes[index] = newCheckbox
  2971.  
  2972. local iconFrame = Main.MiscIcons:GetLabel()
  2973. iconFrame.Position = UDim2.new(0,2,0,3)
  2974. iconFrame.Parent = newEntry.ValueFrame.RightButton
  2975.  
  2976. newEntry.Position = UDim2.new(0,0,0,23*(index-1))
  2977.  
  2978. nameFrame.Expand.InputBegan:Connect(function(input)
  2979. local prop = viewList[index + Properties.Index]
  2980. if not prop or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  2981.  
  2982. local fullName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  2983.  
  2984. Main.MiscIcons:DisplayByKey(newEntry.NameFrame.Expand.Icon, expanded[fullName] and "Collapse_Over" or "Expand_Over")
  2985. end)
  2986.  
  2987. nameFrame.Expand.InputEnded:Connect(function(input)
  2988. local prop = viewList[index + Properties.Index]
  2989. if not prop or input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  2990.  
  2991. local fullName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  2992.  
  2993. Main.MiscIcons:DisplayByKey(newEntry.NameFrame.Expand.Icon, expanded[fullName] and "Collapse" or "Expand")
  2994. end)
  2995.  
  2996. nameFrame.Expand.MouseButton1Down:Connect(function()
  2997. local prop = viewList[index + Properties.Index]
  2998. if not prop then return end
  2999.  
  3000. local fullName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  3001. if not prop.CategoryName and not Properties.ExpandableTypes[prop.ValueType and prop.ValueType.Name] and not Properties.ExpandableProps[fullName] then return end
  3002.  
  3003. expanded[fullName] = not expanded[fullName]
  3004. Properties.Update()
  3005. Properties.Refresh()
  3006. end)
  3007.  
  3008. nameFrame.PropName.InputBegan:Connect(function(input)
  3009. local prop = viewList[index + Properties.Index]
  3010. if not prop then return end
  3011. if input.UserInputType == Enum.UserInputType.MouseMovement and not nameFrame.PropName.TextFits then
  3012. local fullNameFrame = Properties.FullNameFrame
  3013. local nameArr = string.split(prop.Class.."."..prop.Name..(prop.SubName or ""),".")
  3014. local dispName = prop.DisplayName or nameArr[#nameArr]
  3015. local sizeX = service.TextService:GetTextSize(dispName,14,Enum.Font.SourceSans,Vector2.new(math.huge,20)).X
  3016.  
  3017. fullNameFrame.TextLabel.Text = dispName
  3018. --fullNameFrame.Position = UDim2.new(0,Properties.EntryIndent*(prop.Depth or 1) + Properties.EntryOffset,0,23*(index-1))
  3019. fullNameFrame.Size = UDim2.new(0,sizeX + 4,0,22)
  3020. fullNameFrame.Visible = true
  3021. Properties.FullNameFrameIndex = index
  3022. Properties.FullNameFrameAttach.SetData(fullNameFrame, {Target = nameFrame})
  3023. Properties.FullNameFrameAttach.Enable()
  3024. end
  3025. end)
  3026.  
  3027. nameFrame.PropName.InputEnded:Connect(function(input)
  3028. if input.UserInputType == Enum.UserInputType.MouseMovement and Properties.FullNameFrameIndex == index then
  3029. Properties.FullNameFrame.Visible = false
  3030. Properties.FullNameFrameAttach.Disable()
  3031. end
  3032. end)
  3033.  
  3034. valueFrame.ValueBox.MouseButton1Down:Connect(function()
  3035. local prop = viewList[index + Properties.Index]
  3036. if not prop then return end
  3037.  
  3038. Properties.SetInputProp(prop,index)
  3039. end)
  3040.  
  3041. valueFrame.ColorButton.MouseButton1Down:Connect(function()
  3042. local prop = viewList[index + Properties.Index]
  3043. if not prop then return end
  3044.  
  3045. Properties.SetInputProp(prop,index,"color")
  3046. end)
  3047.  
  3048. valueFrame.RightButton.MouseButton1Click:Connect(function()
  3049. local prop = viewList[index + Properties.Index]
  3050. if not prop then return end
  3051.  
  3052. local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  3053. local inputFullName = inputProp and (inputProp.Class.."."..inputProp.Name..(inputProp.SubName or ""))
  3054.  
  3055. if fullName == inputFullName and inputProp.ValueType.Category == "Class" then
  3056. inputProp = nil
  3057. Properties.SetProp(prop,nil)
  3058. else
  3059. Properties.SetInputProp(prop,index,"right")
  3060. end
  3061. end)
  3062.  
  3063. nameFrame.ToggleAttributes.MouseButton1Click:Connect(function()
  3064. Settings.Properties.ShowAttributes = not Settings.Properties.ShowAttributes
  3065. Properties.ShowExplorerProps()
  3066. end)
  3067.  
  3068. newEntry.RowButton.MouseButton1Click:Connect(function()
  3069. Properties.DisplayAddAttributeWindow()
  3070. end)
  3071.  
  3072. newEntry.EditAttributeButton.MouseButton1Down:Connect(function()
  3073. local prop = viewList[index + Properties.Index]
  3074. if not prop then return end
  3075.  
  3076. Properties.DisplayAttributeContext(prop)
  3077. end)
  3078.  
  3079. valueFrame.SoundPreview.ControlButton.MouseButton1Click:Connect(function()
  3080. if Properties.PreviewSound and Properties.PreviewSound.Playing then
  3081. Properties.SetSoundPreview(false)
  3082. else
  3083. local soundObj = Properties.FindFirstObjWhichIsA("Sound")
  3084. if soundObj then Properties.SetSoundPreview(soundObj) end
  3085. end
  3086. end)
  3087.  
  3088. valueFrame.SoundPreview.InputBegan:Connect(function(input)
  3089. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  3090.  
  3091. local releaseEvent,mouseEvent
  3092. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  3093. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  3094. releaseEvent:Disconnect()
  3095. mouseEvent:Disconnect()
  3096. end)
  3097.  
  3098. local timeLine = newEntry.ValueFrame.SoundPreview.TimeLine
  3099. local soundObj = Properties.FindFirstObjWhichIsA("Sound")
  3100. if soundObj then Properties.SetSoundPreview(soundObj,true) end
  3101.  
  3102. local function update(input)
  3103. local sound = Properties.PreviewSound
  3104. if not sound or sound.TimeLength == 0 then return end
  3105.  
  3106. local mouseX = input.Position.X
  3107. local timeLineSize = timeLine.AbsoluteSize
  3108. local relaX = mouseX - timeLine.AbsolutePosition.X
  3109.  
  3110. if timeLineSize.X <= 1 then return end
  3111. if relaX < 0 then relaX = 0 elseif relaX >= timeLineSize.X then relaX = timeLineSize.X-1 end
  3112.  
  3113. local perc = (relaX/(timeLineSize.X-1))
  3114. sound.TimePosition = perc*sound.TimeLength
  3115. timeLine.Slider.Position = UDim2.new(perc,-4,0,-8)
  3116. end
  3117. update(input)
  3118.  
  3119. mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  3120. if input.UserInputType == Enum.UserInputType.MouseMovement then
  3121. update(input)
  3122. end
  3123. end)
  3124. end)
  3125.  
  3126. newEntry.Parent = propsFrame
  3127.  
  3128. return {
  3129. Gui = newEntry,
  3130. GuiElems = {
  3131. NameFrame = nameFrame,
  3132. ValueFrame = valueFrame,
  3133. PropName = nameFrame.PropName,
  3134. ValueBox = valueFrame.ValueBox,
  3135. Expand = nameFrame.Expand,
  3136. ColorButton = valueFrame.ColorButton,
  3137. ColorPreview = valueFrame.ColorButton.ColorPreview,
  3138. Gradient = valueFrame.ColorButton.ColorPreview.UIGradient,
  3139. EnumArrow = valueFrame.EnumArrow,
  3140. Checkbox = valueFrame.Checkbox,
  3141. RightButton = valueFrame.RightButton,
  3142. RightButtonIcon = iconFrame,
  3143. RowButton = newEntry.RowButton,
  3144. EditAttributeButton = newEntry.EditAttributeButton,
  3145. ToggleAttributes = nameFrame.ToggleAttributes,
  3146. SoundPreview = valueFrame.SoundPreview,
  3147. SoundPreviewSlider = valueFrame.SoundPreview.TimeLine.Slider
  3148. }
  3149. }
  3150. end
  3151.  
  3152. Properties.GetSoundPreviewEntry = function()
  3153. for i = 1,#viewList do
  3154. if viewList[i] == Properties.SoundPreviewProp then
  3155. return propEntries[i - Properties.Index]
  3156. end
  3157. end
  3158. end
  3159.  
  3160. Properties.SetSoundPreview = function(soundObj,noplay)
  3161. local sound = Properties.PreviewSound
  3162. if not sound then
  3163. sound = Instance.new("Sound")
  3164. sound.Name = "Preview"
  3165. sound.Paused:Connect(function()
  3166. local entry = Properties.GetSoundPreviewEntry()
  3167. if entry then Main.MiscIcons:DisplayByKey(entry.GuiElems.SoundPreview.ControlButton.Icon, "Play") end
  3168. end)
  3169. sound.Resumed:Connect(function() Properties.Refresh() end)
  3170. sound.Ended:Connect(function()
  3171. local entry = Properties.GetSoundPreviewEntry()
  3172. if entry then entry.GuiElems.SoundPreviewSlider.Position = UDim2.new(0,-4,0,-8) end
  3173. Properties.Refresh()
  3174. end)
  3175. sound.Parent = window.Gui
  3176. Properties.PreviewSound = sound
  3177. end
  3178.  
  3179. if not soundObj then
  3180. sound:Pause()
  3181. else
  3182. local newId = sound.SoundId ~= soundObj.SoundId
  3183. sound.SoundId = soundObj.SoundId
  3184. sound.PlaybackSpeed = soundObj.PlaybackSpeed
  3185. sound.Volume = soundObj.Volume
  3186. if newId then sound.TimePosition = 0 end
  3187. if not noplay then sound:Resume() end
  3188.  
  3189. coroutine.wrap(function()
  3190. local previewTime = tick()
  3191. Properties.SoundPreviewTime = previewTime
  3192. while previewTime == Properties.SoundPreviewTime and sound.Playing do
  3193. local entry = Properties.GetSoundPreviewEntry()
  3194. if entry then
  3195. local tl = sound.TimeLength
  3196. local perc = sound.TimePosition/(tl == 0 and 1 or tl)
  3197. entry.GuiElems.SoundPreviewSlider.Position = UDim2.new(perc,-4,0,-8)
  3198. end
  3199. Lib.FastWait()
  3200. end
  3201. end)()
  3202. Properties.Refresh()
  3203. end
  3204. end
  3205.  
  3206. Properties.DisplayAttributeContext = function(prop)
  3207. local context = Properties.AttributeContext
  3208. if not context then
  3209. context = Lib.ContextMenu.new()
  3210. context.Iconless = true
  3211. context.Width = 80
  3212. end
  3213. context:Clear()
  3214.  
  3215. context:Add({Name = "Edit", OnClick = function()
  3216. Properties.DisplayAddAttributeWindow(prop)
  3217. end})
  3218. context:Add({Name = "Delete", OnClick = function()
  3219. Properties.SetProp(prop,nil,true)
  3220. Properties.ShowExplorerProps()
  3221. end})
  3222.  
  3223. context:Show()
  3224. end
  3225.  
  3226. Properties.DisplayAddAttributeWindow = function(editAttr)
  3227. local win = Properties.AddAttributeWindow
  3228. if not win then
  3229. win = Lib.Window.new()
  3230. win.Alignable = false
  3231. win.Resizable = false
  3232. win:SetTitle("Add Attribute")
  3233. win:SetSize(200,130)
  3234.  
  3235. local saveButton = Lib.Button.new()
  3236. local nameLabel = Lib.Label.new()
  3237. nameLabel.Text = "Name"
  3238. nameLabel.Position = UDim2.new(0,30,0,10)
  3239. nameLabel.Size = UDim2.new(0,40,0,20)
  3240. win:Add(nameLabel)
  3241.  
  3242. local nameBox = Lib.ViewportTextBox.new()
  3243. nameBox.Position = UDim2.new(0,75,0,10)
  3244. nameBox.Size = UDim2.new(0,120,0,20)
  3245. win:Add(nameBox,"NameBox")
  3246. nameBox.TextBox:GetPropertyChangedSignal("Text"):Connect(function()
  3247. saveButton:SetDisabled(#nameBox:GetText() == 0)
  3248. end)
  3249.  
  3250. local typeLabel = Lib.Label.new()
  3251. typeLabel.Text = "Type"
  3252. typeLabel.Position = UDim2.new(0,30,0,40)
  3253. typeLabel.Size = UDim2.new(0,40,0,20)
  3254. win:Add(typeLabel)
  3255.  
  3256. local typeChooser = Lib.DropDown.new()
  3257. typeChooser.CanBeEmpty = false
  3258. typeChooser.Position = UDim2.new(0,75,0,40)
  3259. typeChooser.Size = UDim2.new(0,120,0,20)
  3260. typeChooser:SetOptions(Properties.AllowedAttributeTypes)
  3261. win:Add(typeChooser,"TypeChooser")
  3262.  
  3263. local errorLabel = Lib.Label.new()
  3264. errorLabel.Text = ""
  3265. errorLabel.Position = UDim2.new(0,5,1,-45)
  3266. errorLabel.Size = UDim2.new(1,-10,0,20)
  3267. errorLabel.TextColor3 = Settings.Theme.Important
  3268. win.ErrorLabel = errorLabel
  3269. win:Add(errorLabel,"Error")
  3270.  
  3271. local cancelButton = Lib.Button.new()
  3272. cancelButton.Text = "Cancel"
  3273. cancelButton.Position = UDim2.new(1,-97,1,-25)
  3274. cancelButton.Size = UDim2.new(0,92,0,20)
  3275. cancelButton.OnClick:Connect(function()
  3276. win:Close()
  3277. end)
  3278. win:Add(cancelButton)
  3279.  
  3280. saveButton.Text = "Save"
  3281. saveButton.Position = UDim2.new(0,5,1,-25)
  3282. saveButton.Size = UDim2.new(0,92,0,20)
  3283. saveButton.OnClick:Connect(function()
  3284. local name = nameBox:GetText()
  3285. if #name > 100 then
  3286. errorLabel.Text = "Error: Name over 100 chars"
  3287. return
  3288. elseif name:sub(1,3) == "RBX" then
  3289. errorLabel.Text = "Error: Name begins with 'RBX'"
  3290. return
  3291. end
  3292.  
  3293. local typ = typeChooser.Selected
  3294. local valType = {Name = Properties.TypeNameConvert[typ] or typ, Category = "DataType"}
  3295. local attrProp = {IsAttribute = true, Name = "ATTR_"..name, AttributeName = name, DisplayName = name, Class = "Instance", ValueType = valType, Category = "Attributes", Tags = {}}
  3296.  
  3297. Settings.Properties.ShowAttributes = true
  3298. Properties.SetProp(attrProp,Properties.DefaultPropValue[valType.Name],true,Properties.EditingAttribute)
  3299. Properties.ShowExplorerProps()
  3300. win:Close()
  3301. end)
  3302. win:Add(saveButton,"SaveButton")
  3303.  
  3304. Properties.AddAttributeWindow = win
  3305. end
  3306.  
  3307. Properties.EditingAttribute = editAttr
  3308. win:SetTitle(editAttr and "Edit Attribute "..editAttr.AttributeName or "Add Attribute")
  3309. win.Elements.Error.Text = ""
  3310. win.Elements.NameBox:SetText("")
  3311. win.Elements.SaveButton:SetDisabled(true)
  3312. win.Elements.TypeChooser:SetSelected(1)
  3313. win:Show()
  3314. end
  3315.  
  3316. Properties.IsTextEditable = function(prop)
  3317. local typeData = prop.ValueType
  3318. local typeName = typeData.Name
  3319.  
  3320. return typeName ~= "bool" and typeData.Category ~= "Enum" and typeData.Category ~= "Class" and typeName ~= "BrickColor"
  3321. end
  3322.  
  3323. Properties.DisplayEnumDropdown = function(entryIndex)
  3324. local context = Properties.EnumContext
  3325. if not context then
  3326. context = Lib.ContextMenu.new()
  3327. context.Iconless = true
  3328. context.MaxHeight = 200
  3329. context.ReverseYOffset = 22
  3330. Properties.EnumDropdown = context
  3331. end
  3332.  
  3333. if not inputProp or inputProp.ValueType.Category ~= "Enum" then return end
  3334. local prop = inputProp
  3335.  
  3336. local entry = propEntries[entryIndex]
  3337. local valueFrame = entry.GuiElems.ValueFrame
  3338.  
  3339. local enum = Enum[prop.ValueType.Name]
  3340. if not enum then return end
  3341.  
  3342. local sorted = {}
  3343. for name,enum in next,enum:GetEnumItems() do
  3344. sorted[#sorted+1] = enum
  3345. end
  3346. table.sort(sorted,function(a,b) return a.Name < b.Name end)
  3347.  
  3348. context:Clear()
  3349.  
  3350. local function onClick(name)
  3351. if prop ~= inputProp then return end
  3352.  
  3353. local enumItem = enum[name]
  3354. inputProp = nil
  3355. Properties.SetProp(prop,enumItem)
  3356. end
  3357.  
  3358. for i = 1,#sorted do
  3359. local enumItem = sorted[i]
  3360. context:Add({Name = enumItem.Name, OnClick = onClick})
  3361. end
  3362.  
  3363. context.Width = valueFrame.AbsoluteSize.X
  3364. context:Show(valueFrame.AbsolutePosition.X, valueFrame.AbsolutePosition.Y + 22)
  3365. end
  3366.  
  3367. Properties.DisplayBrickColorEditor = function(prop,entryIndex,col)
  3368. local editor = Properties.BrickColorEditor
  3369. if not editor then
  3370. editor = Lib.BrickColorPicker.new()
  3371. editor.Gui.DisplayOrder = Main.DisplayOrders.Menu
  3372. editor.ReverseYOffset = 22
  3373.  
  3374. editor.OnSelect:Connect(function(col)
  3375. if not editor.CurrentProp or editor.CurrentProp.ValueType.Name ~= "BrickColor" then return end
  3376.  
  3377. if editor.CurrentProp == inputProp then inputProp = nil end
  3378. Properties.SetProp(editor.CurrentProp,BrickColor.new(col))
  3379. end)
  3380.  
  3381. editor.OnMoreColors:Connect(function() -- TODO: Special Case BasePart.BrickColor to BasePart.Color
  3382. editor:Close()
  3383. local colProp
  3384. for i,v in pairs(API.Classes.BasePart.Properties) do
  3385. if v.Name == "Color" then
  3386. colProp = v
  3387. break
  3388. end
  3389. end
  3390. Properties.DisplayColorEditor(colProp,editor.SavedColor.Color)
  3391. end)
  3392.  
  3393. Properties.BrickColorEditor = editor
  3394. end
  3395.  
  3396. local entry = propEntries[entryIndex]
  3397. local valueFrame = entry.GuiElems.ValueFrame
  3398.  
  3399. editor.CurrentProp = prop
  3400. editor.SavedColor = col
  3401. if prop and prop.Class == "BasePart" and prop.Name == "BrickColor" then
  3402. editor:SetMoreColorsVisible(true)
  3403. else
  3404. editor:SetMoreColorsVisible(false)
  3405. end
  3406. editor:Show(valueFrame.AbsolutePosition.X, valueFrame.AbsolutePosition.Y + 22)
  3407. end
  3408.  
  3409. Properties.DisplayColorEditor = function(prop,col)
  3410. local editor = Properties.ColorEditor
  3411. if not editor then
  3412. editor = Lib.ColorPicker.new()
  3413.  
  3414. editor.OnSelect:Connect(function(col)
  3415. if not editor.CurrentProp then return end
  3416. local typeName = editor.CurrentProp.ValueType.Name
  3417. if typeName ~= "Color3" and typeName ~= "BrickColor" then return end
  3418.  
  3419. local colVal = (typeName == "Color3" and col or BrickColor.new(col))
  3420.  
  3421. if editor.CurrentProp == inputProp then inputProp = nil end
  3422. Properties.SetProp(editor.CurrentProp,colVal)
  3423. end)
  3424.  
  3425. Properties.ColorEditor = editor
  3426. end
  3427.  
  3428. editor.CurrentProp = prop
  3429. if col then
  3430. editor:SetColor(col)
  3431. else
  3432. local firstVal = Properties.GetFirstPropVal(prop)
  3433. if firstVal then editor:SetColor(firstVal) end
  3434. end
  3435. editor:Show()
  3436. end
  3437.  
  3438. Properties.DisplayNumberSequenceEditor = function(prop,seq)
  3439. local editor = Properties.NumberSequenceEditor
  3440. if not editor then
  3441. editor = Lib.NumberSequenceEditor.new()
  3442.  
  3443. editor.OnSelect:Connect(function(val)
  3444. if not editor.CurrentProp or editor.CurrentProp.ValueType.Name ~= "NumberSequence" then return end
  3445.  
  3446. if editor.CurrentProp == inputProp then inputProp = nil end
  3447. Properties.SetProp(editor.CurrentProp,val)
  3448. end)
  3449.  
  3450. Properties.NumberSequenceEditor = editor
  3451. end
  3452.  
  3453. editor.CurrentProp = prop
  3454. if seq then
  3455. editor:SetSequence(seq)
  3456. else
  3457. local firstVal = Properties.GetFirstPropVal(prop)
  3458. if firstVal then editor:SetSequence(firstVal) end
  3459. end
  3460. editor:Show()
  3461. end
  3462.  
  3463. Properties.DisplayColorSequenceEditor = function(prop,seq)
  3464. local editor = Properties.ColorSequenceEditor
  3465. if not editor then
  3466. editor = Lib.ColorSequenceEditor.new()
  3467.  
  3468. editor.OnSelect:Connect(function(val)
  3469. if not editor.CurrentProp or editor.CurrentProp.ValueType.Name ~= "ColorSequence" then return end
  3470.  
  3471. if editor.CurrentProp == inputProp then inputProp = nil end
  3472. Properties.SetProp(editor.CurrentProp,val)
  3473. end)
  3474.  
  3475. Properties.ColorSequenceEditor = editor
  3476. end
  3477.  
  3478. editor.CurrentProp = prop
  3479. if seq then
  3480. editor:SetSequence(seq)
  3481. else
  3482. local firstVal = Properties.GetFirstPropVal(prop)
  3483. if firstVal then editor:SetSequence(firstVal) end
  3484. end
  3485. editor:Show()
  3486. end
  3487.  
  3488. Properties.GetFirstPropVal = function(prop)
  3489. local first = Properties.FindFirstObjWhichIsA(prop.Class)
  3490. if first then
  3491. return Properties.GetPropVal(prop,first)
  3492. end
  3493. end
  3494.  
  3495. Properties.GetPropVal = function(prop,obj)
  3496. if prop.MultiType then return "<Multiple Types>" end
  3497. if not obj then return end
  3498.  
  3499. local propVal
  3500. if prop.IsAttribute then
  3501. propVal = getAttribute(obj,prop.AttributeName)
  3502. if propVal == nil then return nil end
  3503.  
  3504. local typ = typeof(propVal)
  3505. local currentType = Properties.TypeNameConvert[typ] or typ
  3506. if prop.RootType then
  3507. if prop.RootType.Name ~= currentType then
  3508. return nil
  3509. end
  3510. elseif prop.ValueType.Name ~= currentType then
  3511. return nil
  3512. end
  3513. else
  3514. propVal = obj[prop.Name]
  3515. end
  3516. if prop.SubName then
  3517. local indexes = string.split(prop.SubName,".")
  3518. for i = 1,#indexes do
  3519. local indexName = indexes[i]
  3520. if #indexName > 0 and propVal then
  3521. propVal = propVal[indexName]
  3522. end
  3523. end
  3524. end
  3525.  
  3526. return propVal
  3527. end
  3528.  
  3529. Properties.SelectObject = function(obj)
  3530. if inputProp and inputProp.ValueType.Category == "Class" then
  3531. local prop = inputProp
  3532. inputProp = nil
  3533.  
  3534. if isa(obj,prop.ValueType.Name) then
  3535. Properties.SetProp(prop,obj)
  3536. else
  3537. Properties.Refresh()
  3538. end
  3539.  
  3540. return true
  3541. end
  3542.  
  3543. return false
  3544. end
  3545.  
  3546. Properties.DisplayProp = function(prop,entryIndex)
  3547. local propName = prop.Name
  3548. local typeData = prop.ValueType
  3549. local typeName = typeData.Name
  3550. local tags = prop.Tags
  3551. local gName = prop.Class.."."..prop.Name..(prop.SubName or "")
  3552. local propObj = autoUpdateObjs[gName]
  3553. local entryData = propEntries[entryIndex]
  3554. local UDim2 = UDim2
  3555.  
  3556. local guiElems = entryData.GuiElems
  3557. local valueFrame = guiElems.ValueFrame
  3558. local valueBox = guiElems.ValueBox
  3559. local colorButton = guiElems.ColorButton
  3560. local colorPreview = guiElems.ColorPreview
  3561. local gradient = guiElems.Gradient
  3562. local enumArrow = guiElems.EnumArrow
  3563. local checkbox = guiElems.Checkbox
  3564. local rightButton = guiElems.RightButton
  3565. local soundPreview = guiElems.SoundPreview
  3566.  
  3567. local propVal = Properties.GetPropVal(prop,propObj)
  3568. local inputFullName = inputProp and (inputProp.Class.."."..inputProp.Name..(inputProp.SubName or ""))
  3569.  
  3570. local offset = 4
  3571. local endOffset = 6
  3572.  
  3573. -- Offsetting the ValueBox for ValueType specific buttons
  3574. if (typeName == "Color3" or typeName == "BrickColor" or typeName == "ColorSequence") then
  3575. colorButton.Visible = true
  3576. enumArrow.Visible = false
  3577. if propVal then
  3578. gradient.Color = (typeName == "Color3" and ColorSequence.new(propVal)) or (typeName == "BrickColor" and ColorSequence.new(propVal.Color)) or propVal
  3579. else
  3580. gradient.Color = ColorSequence.new(Color3.new(1,1,1))
  3581. end
  3582. colorPreview.BorderColor3 = (typeName == "ColorSequence" and Color3.new(1,1,1) or Color3.new(0,0,0))
  3583. offset = 22
  3584. endOffset = 24 + (typeName == "ColorSequence" and 20 or 0)
  3585. elseif typeData.Category == "Enum" then
  3586. colorButton.Visible = false
  3587. enumArrow.Visible = not prop.Tags.ReadOnly
  3588. endOffset = 22
  3589. elseif (gName == inputFullName and typeData.Category == "Class") or typeName == "NumberSequence" then
  3590. colorButton.Visible = false
  3591. enumArrow.Visible = false
  3592. endOffset = 26
  3593. else
  3594. colorButton.Visible = false
  3595. enumArrow.Visible = false
  3596. end
  3597.  
  3598. valueBox.Position = UDim2.new(0,offset,0,0)
  3599. valueBox.Size = UDim2.new(1,-endOffset,1,0)
  3600.  
  3601. -- Right button
  3602. if inputFullName == gName and typeData.Category == "Class" then
  3603. Main.MiscIcons:DisplayByKey(guiElems.RightButtonIcon, "Delete")
  3604. guiElems.RightButtonIcon.Visible = true
  3605. rightButton.Text = ""
  3606. rightButton.Visible = true
  3607. elseif typeName == "NumberSequence" or typeName == "ColorSequence" then
  3608. guiElems.RightButtonIcon.Visible = false
  3609. rightButton.Text = "..."
  3610. rightButton.Visible = true
  3611. else
  3612. rightButton.Visible = false
  3613. end
  3614.  
  3615. -- Displays the correct ValueBox for the ValueType, and sets it to the prop value
  3616. if typeName == "bool" or typeName == "PhysicalProperties" then
  3617. valueBox.Visible = false
  3618. checkbox.Visible = true
  3619. soundPreview.Visible = false
  3620. checkboxes[entryIndex].Disabled = tags.ReadOnly
  3621. if typeName == "PhysicalProperties" and autoUpdateObjs[gName] then
  3622. checkboxes[entryIndex]:SetState(propVal and true or false)
  3623. else
  3624. checkboxes[entryIndex]:SetState(propVal)
  3625. end
  3626. elseif typeName == "SoundPlayer" then
  3627. valueBox.Visible = false
  3628. checkbox.Visible = false
  3629. soundPreview.Visible = true
  3630. local playing = Properties.PreviewSound and Properties.PreviewSound.Playing
  3631. Main.MiscIcons:DisplayByKey(soundPreview.ControlButton.Icon, playing and "Pause" or "Play")
  3632. else
  3633. valueBox.Visible = true
  3634. checkbox.Visible = false
  3635. soundPreview.Visible = false
  3636.  
  3637. if propVal ~= nil then
  3638. if typeName == "Color3" then
  3639. valueBox.Text = "["..Lib.ColorToBytes(propVal).."]"
  3640. elseif typeData.Category == "Enum" then
  3641. valueBox.Text = propVal.Name
  3642. elseif Properties.RoundableTypes[typeName] and Settings.Properties.NumberRounding then
  3643. local rawStr = Properties.ValueToString(prop,propVal)
  3644. valueBox.Text = rawStr:gsub("-?%d+%.%d+",function(num)
  3645. return tostring(tonumber(("%."..Settings.Properties.NumberRounding.."f"):format(num)))
  3646. end)
  3647. else
  3648. valueBox.Text = Properties.ValueToString(prop,propVal)
  3649. end
  3650. else
  3651. valueBox.Text = ""
  3652. end
  3653.  
  3654. valueBox.TextColor3 = tags.ReadOnly and Settings.Theme.PlaceholderText or Settings.Theme.Text
  3655. end
  3656. end
  3657.  
  3658. Properties.Refresh = function()
  3659. local maxEntries = math.max(math.ceil((propsFrame.AbsoluteSize.Y) / 23),0)
  3660. local maxX = propsFrame.AbsoluteSize.X
  3661. local valueWidth = math.max(Properties.MinInputWidth,maxX-Properties.ViewWidth)
  3662. local inputPropVisible = false
  3663. local isa = game.IsA
  3664. local UDim2 = UDim2
  3665. local stringSplit = string.split
  3666. local scaleType = Settings.Properties.ScaleType
  3667.  
  3668. -- Clear connections
  3669. for i = 1,#propCons do
  3670. propCons[i]:Disconnect()
  3671. end
  3672. table.clear(propCons)
  3673.  
  3674. -- Hide full name viewer
  3675. Properties.FullNameFrame.Visible = false
  3676. Properties.FullNameFrameAttach.Disable()
  3677.  
  3678. for i = 1,maxEntries do
  3679. local entryData = propEntries[i]
  3680. if not propEntries[i] then entryData = Properties.NewPropEntry(i) propEntries[i] = entryData end
  3681.  
  3682. local entry = entryData.Gui
  3683. local guiElems = entryData.GuiElems
  3684. local nameFrame = guiElems.NameFrame
  3685. local propNameLabel = guiElems.PropName
  3686. local valueFrame = guiElems.ValueFrame
  3687. local expand = guiElems.Expand
  3688. local valueBox = guiElems.ValueBox
  3689. local propNameBox = guiElems.PropName
  3690. local rightButton = guiElems.RightButton
  3691. local editAttributeButton = guiElems.EditAttributeButton
  3692. local toggleAttributes = guiElems.ToggleAttributes
  3693.  
  3694. local prop = viewList[i + Properties.Index]
  3695. if prop then
  3696. local entryXOffset = (scaleType == 0 and scrollH.Index or 0)
  3697. entry.Visible = true
  3698. entry.Position = UDim2.new(0,-entryXOffset,0,entry.Position.Y.Offset)
  3699. entry.Size = UDim2.new(scaleType == 0 and 0 or 1, scaleType == 0 and Properties.ViewWidth + valueWidth or 0,0,22)
  3700.  
  3701. if prop.SpecialRow then
  3702. if prop.SpecialRow == "AddAttribute" then
  3703. nameFrame.Visible = false
  3704. valueFrame.Visible = false
  3705. guiElems.RowButton.Visible = true
  3706. end
  3707. else
  3708. -- Revert special row stuff
  3709. nameFrame.Visible = true
  3710. guiElems.RowButton.Visible = false
  3711.  
  3712. local depth = Properties.EntryIndent*(prop.Depth or 1)
  3713. local leftOffset = depth + Properties.EntryOffset
  3714. nameFrame.Position = UDim2.new(0,leftOffset,0,0)
  3715. propNameLabel.Size = UDim2.new(1,-2 - (scaleType == 0 and 0 or 6),1,0)
  3716.  
  3717. local gName = (prop.CategoryName and "CAT_"..prop.CategoryName) or prop.Class.."."..prop.Name..(prop.SubName or "")
  3718.  
  3719. if prop.CategoryName then
  3720. entry.BackgroundColor3 = Settings.Theme.Main1
  3721. valueFrame.Visible = false
  3722.  
  3723. propNameBox.Text = prop.CategoryName
  3724. propNameBox.Font = Enum.Font.SourceSansBold
  3725. expand.Visible = true
  3726. propNameBox.TextColor3 = Settings.Theme.Text
  3727. nameFrame.BackgroundTransparency = 1
  3728. nameFrame.Size = UDim2.new(1,0,1,0)
  3729. editAttributeButton.Visible = false
  3730.  
  3731. local showingAttrs = Settings.Properties.ShowAttributes
  3732. toggleAttributes.Position = UDim2.new(1,-85-leftOffset,0,0)
  3733. toggleAttributes.Text = (showingAttrs and "[Setting: ON]" or "[Setting: OFF]")
  3734. toggleAttributes.TextColor3 = Settings.Theme.Text
  3735. toggleAttributes.Visible = (prop.CategoryName == "Attributes")
  3736. else
  3737. local propName = prop.Name
  3738. local typeData = prop.ValueType
  3739. local typeName = typeData.Name
  3740. local tags = prop.Tags
  3741. local propObj = autoUpdateObjs[gName]
  3742.  
  3743. local attributeOffset = (prop.IsAttribute and 20 or 0)
  3744. editAttributeButton.Visible = (prop.IsAttribute and not prop.RootType)
  3745. toggleAttributes.Visible = false
  3746.  
  3747. -- Moving around the frames
  3748. if scaleType == 0 then
  3749. nameFrame.Size = UDim2.new(0,Properties.ViewWidth - leftOffset - 1,1,0)
  3750. valueFrame.Position = UDim2.new(0,Properties.ViewWidth,0,0)
  3751. valueFrame.Size = UDim2.new(0,valueWidth - attributeOffset,1,0)
  3752. else
  3753. nameFrame.Size = UDim2.new(0.5,-leftOffset - 1,1,0)
  3754. valueFrame.Position = UDim2.new(0.5,0,0,0)
  3755. valueFrame.Size = UDim2.new(0.5,-attributeOffset,1,0)
  3756. end
  3757.  
  3758. local nameArr = stringSplit(gName,".")
  3759. propNameBox.Text = prop.DisplayName or nameArr[#nameArr]
  3760. propNameBox.Font = Enum.Font.SourceSans
  3761. entry.BackgroundColor3 = Settings.Theme.Main2
  3762. valueFrame.Visible = true
  3763.  
  3764. expand.Visible = typeData.Category == "DataType" and Properties.ExpandableTypes[typeName] or Properties.ExpandableProps[gName]
  3765. propNameBox.TextColor3 = tags.ReadOnly and Settings.Theme.PlaceholderText or Settings.Theme.Text
  3766.  
  3767. -- Display property value
  3768. Properties.DisplayProp(prop,i)
  3769. if propObj then
  3770. if prop.IsAttribute then
  3771. propCons[#propCons+1] = getAttributeChangedSignal(propObj,prop.AttributeName):Connect(function()
  3772. Properties.DisplayProp(prop,i)
  3773. end)
  3774. else
  3775. propCons[#propCons+1] = getPropChangedSignal(propObj,propName):Connect(function()
  3776. Properties.DisplayProp(prop,i)
  3777. end)
  3778. end
  3779. end
  3780.  
  3781. -- Position and resize Input Box
  3782. local beforeVisible = valueBox.Visible
  3783. local inputFullName = inputProp and (inputProp.Class.."."..inputProp.Name..(inputProp.SubName or ""))
  3784. if gName == inputFullName then
  3785. nameFrame.BackgroundColor3 = Settings.Theme.ListSelection
  3786. nameFrame.BackgroundTransparency = 0
  3787. if typeData.Category == "Class" or typeData.Category == "Enum" or typeName == "BrickColor" then
  3788. valueFrame.BackgroundColor3 = Settings.Theme.TextBox
  3789. valueFrame.BackgroundTransparency = 0
  3790. valueBox.Visible = true
  3791. else
  3792. inputPropVisible = true
  3793. local scale = (scaleType == 0 and 0 or 0.5)
  3794. local offset = (scaleType == 0 and Properties.ViewWidth-scrollH.Index or 0)
  3795. local endOffset = 0
  3796.  
  3797. if typeName == "Color3" or typeName == "ColorSequence" then
  3798. offset = offset + 22
  3799. end
  3800.  
  3801. if typeName == "NumberSequence" or typeName == "ColorSequence" then
  3802. endOffset = 20
  3803. end
  3804.  
  3805. inputBox.Position = UDim2.new(scale,offset,0,entry.Position.Y.Offset)
  3806. inputBox.Size = UDim2.new(1-scale,-offset-endOffset-attributeOffset,0,22)
  3807. inputBox.Visible = true
  3808. valueBox.Visible = false
  3809. end
  3810. else
  3811. nameFrame.BackgroundColor3 = Settings.Theme.Main1
  3812. nameFrame.BackgroundTransparency = 1
  3813. valueFrame.BackgroundColor3 = Settings.Theme.Main1
  3814. valueFrame.BackgroundTransparency = 1
  3815. valueBox.Visible = beforeVisible
  3816. end
  3817. end
  3818.  
  3819. -- Expand
  3820. if prop.CategoryName or Properties.ExpandableTypes[prop.ValueType and prop.ValueType.Name] or Properties.ExpandableProps[gName] then
  3821. if Lib.CheckMouseInGui(expand) then
  3822. Main.MiscIcons:DisplayByKey(expand.Icon, expanded[gName] and "Collapse_Over" or "Expand_Over")
  3823. else
  3824. Main.MiscIcons:DisplayByKey(expand.Icon, expanded[gName] and "Collapse" or "Expand")
  3825. end
  3826. expand.Visible = true
  3827. else
  3828. expand.Visible = false
  3829. end
  3830. end
  3831. entry.Visible = true
  3832. else
  3833. entry.Visible = false
  3834. end
  3835. end
  3836.  
  3837. if not inputPropVisible then
  3838. inputBox.Visible = false
  3839. end
  3840.  
  3841. for i = maxEntries+1,#propEntries do
  3842. propEntries[i].Gui:Destroy()
  3843. propEntries[i] = nil
  3844. checkboxes[i] = nil
  3845. end
  3846. end
  3847.  
  3848. Properties.SetProp = function(prop,val,noupdate,prevAttribute)
  3849. local sList = Explorer.Selection.List
  3850. local propName = prop.Name
  3851. local subName = prop.SubName
  3852. local propClass = prop.Class
  3853. local typeData = prop.ValueType
  3854. local typeName = typeData.Name
  3855. local attributeName = prop.AttributeName
  3856. local rootTypeData = prop.RootType
  3857. local rootTypeName = rootTypeData and rootTypeData.Name
  3858. local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  3859. local Vector3 = Vector3
  3860.  
  3861. for i = 1,#sList do
  3862. local node = sList[i]
  3863. local obj = node.Obj
  3864.  
  3865. if isa(obj,propClass) then
  3866. pcall(function()
  3867. local setVal = val
  3868. local root
  3869. if prop.IsAttribute then
  3870. root = getAttribute(obj,attributeName)
  3871. else
  3872. root = obj[propName]
  3873. end
  3874.  
  3875. if prevAttribute then
  3876. if prevAttribute.ValueType.Name == typeName then
  3877. setVal = getAttribute(obj,prevAttribute.AttributeName) or setVal
  3878. end
  3879. setAttribute(obj,prevAttribute.AttributeName,nil)
  3880. end
  3881.  
  3882. if rootTypeName then
  3883. if rootTypeName == "Vector2" then
  3884. setVal = Vector2.new((subName == ".X" and setVal) or root.X, (subName == ".Y" and setVal) or root.Y)
  3885. elseif rootTypeName == "Vector3" then
  3886. setVal = Vector3.new((subName == ".X" and setVal) or root.X, (subName == ".Y" and setVal) or root.Y, (subName == ".Z" and setVal) or root.Z)
  3887. elseif rootTypeName == "UDim" then
  3888. setVal = UDim.new((subName == ".Scale" and setVal) or root.Scale, (subName == ".Offset" and setVal) or root.Offset)
  3889. elseif rootTypeName == "UDim2" then
  3890. local rootX,rootY = root.X,root.Y
  3891. local X_UDim = (subName == ".X" and setVal) or UDim.new((subName == ".X.Scale" and setVal) or rootX.Scale, (subName == ".X.Offset" and setVal) or rootX.Offset)
  3892. local Y_UDim = (subName == ".Y" and setVal) or UDim.new((subName == ".Y.Scale" and setVal) or rootY.Scale, (subName == ".Y.Offset" and setVal) or rootY.Offset)
  3893. setVal = UDim2.new(X_UDim,Y_UDim)
  3894. elseif rootTypeName == "CFrame" then
  3895. local rootPos,rootRight,rootUp,rootLook = root.Position,root.RightVector,root.UpVector,root.LookVector
  3896. local pos = (subName == ".Position" and setVal) or Vector3.new((subName == ".Position.X" and setVal) or rootPos.X, (subName == ".Position.Y" and setVal) or rootPos.Y, (subName == ".Position.Z" and setVal) or rootPos.Z)
  3897. local rightV = (subName == ".RightVector" and setVal) or Vector3.new((subName == ".RightVector.X" and setVal) or rootRight.X, (subName == ".RightVector.Y" and setVal) or rootRight.Y, (subName == ".RightVector.Z" and setVal) or rootRight.Z)
  3898. local upV = (subName == ".UpVector" and setVal) or Vector3.new((subName == ".UpVector.X" and setVal) or rootUp.X, (subName == ".UpVector.Y" and setVal) or rootUp.Y, (subName == ".UpVector.Z" and setVal) or rootUp.Z)
  3899. local lookV = (subName == ".LookVector" and setVal) or Vector3.new((subName == ".LookVector.X" and setVal) or rootLook.X, (subName == ".RightVector.Y" and setVal) or rootLook.Y, (subName == ".RightVector.Z" and setVal) or rootLook.Z)
  3900. setVal = CFrame.fromMatrix(pos,rightV,upV,-lookV)
  3901. elseif rootTypeName == "Rect" then
  3902. local rootMin,rootMax = root.Min,root.Max
  3903. local min = Vector2.new((subName == ".Min.X" and setVal) or rootMin.X, (subName == ".Min.Y" and setVal) or rootMin.Y)
  3904. local max = Vector2.new((subName == ".Max.X" and setVal) or rootMax.X, (subName == ".Max.Y" and setVal) or rootMax.Y)
  3905. setVal = Rect.new(min,max)
  3906. elseif rootTypeName == "PhysicalProperties" then
  3907. local rootProps = PhysicalProperties.new(obj.Material)
  3908. local density = (subName == ".Density" and setVal) or (root and root.Density) or rootProps.Density
  3909. local friction = (subName == ".Friction" and setVal) or (root and root.Friction) or rootProps.Friction
  3910. local elasticity = (subName == ".Elasticity" and setVal) or (root and root.Elasticity) or rootProps.Elasticity
  3911. local frictionWeight = (subName == ".FrictionWeight" and setVal) or (root and root.FrictionWeight) or rootProps.FrictionWeight
  3912. local elasticityWeight = (subName == ".ElasticityWeight" and setVal) or (root and root.ElasticityWeight) or rootProps.ElasticityWeight
  3913. setVal = PhysicalProperties.new(density,friction,elasticity,frictionWeight,elasticityWeight)
  3914. elseif rootTypeName == "Ray" then
  3915. local rootOrigin,rootDirection = root.Origin,root.Direction
  3916. local origin = (subName == ".Origin" and setVal) or Vector3.new((subName == ".Origin.X" and setVal) or rootOrigin.X, (subName == ".Origin.Y" and setVal) or rootOrigin.Y, (subName == ".Origin.Z" and setVal) or rootOrigin.Z)
  3917. local direction = (subName == ".Direction" and setVal) or Vector3.new((subName == ".Direction.X" and setVal) or rootDirection.X, (subName == ".Direction.Y" and setVal) or rootDirection.Y, (subName == ".Direction.Z" and setVal) or rootDirection.Z)
  3918. setVal = Ray.new(origin,direction)
  3919. elseif rootTypeName == "Faces" then
  3920. local faces = {}
  3921. local faceList = {"Back","Bottom","Front","Left","Right","Top"}
  3922. for _,face in pairs(faceList) do
  3923. local val
  3924. if subName == "."..face then
  3925. val = setVal
  3926. else
  3927. val = root[face]
  3928. end
  3929. if val then faces[#faces+1] = Enum.NormalId[face] end
  3930. end
  3931. setVal = Faces.new(unpack(faces))
  3932. elseif rootTypeName == "Axes" then
  3933. local axes = {}
  3934. local axesList = {"X","Y","Z"}
  3935. for _,axe in pairs(axesList) do
  3936. local val
  3937. if subName == "."..axe then
  3938. val = setVal
  3939. else
  3940. val = root[axe]
  3941. end
  3942. if val then axes[#axes+1] = Enum.Axis[axe] end
  3943. end
  3944. setVal = Axes.new(unpack(axes))
  3945. elseif rootTypeName == "NumberRange" then
  3946. setVal = NumberRange.new(subName == ".Min" and setVal or root.Min, subName == ".Max" and setVal or root.Max)
  3947. end
  3948. end
  3949.  
  3950. if typeName == "PhysicalProperties" and setVal then
  3951. setVal = root or PhysicalProperties.new(obj.Material)
  3952. end
  3953.  
  3954. if prop.IsAttribute then
  3955. setAttribute(obj,attributeName,setVal)
  3956. else
  3957. obj[propName] = setVal
  3958. end
  3959. end)
  3960. end
  3961. end
  3962.  
  3963. if not noupdate then
  3964. Properties.ComputeConflicts(prop)
  3965. end
  3966. end
  3967.  
  3968. Properties.InitInputBox = function()
  3969. inputBox = create({
  3970. {1,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderSizePixel=0,Name="InputBox",Size=UDim2.new(0,200,0,22),Visible=false,ZIndex=2,}},
  3971. {2,"TextBox",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BackgroundTransparency=1,BorderColor3=Color3.new(0.062745101749897,0.51764708757401,1),BorderSizePixel=0,ClearTextOnFocus=false,Font=3,Parent={1},PlaceholderColor3=Color3.new(0.69803923368454,0.69803923368454,0.69803923368454),Position=UDim2.new(0,3,0,0),Size=UDim2.new(1,-6,1,0),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,ZIndex=2,}},
  3972. })
  3973. inputTextBox = inputBox.TextBox
  3974. inputBox.BackgroundColor3 = Settings.Theme.TextBox
  3975. inputBox.Parent = Properties.Window.GuiElems.Content.List
  3976.  
  3977. inputTextBox.FocusLost:Connect(function()
  3978. if not inputProp then return end
  3979.  
  3980. local prop = inputProp
  3981. inputProp = nil
  3982. local val = Properties.StringToValue(prop,inputTextBox.Text)
  3983. if val then Properties.SetProp(prop,val) else Properties.Refresh() end
  3984. end)
  3985.  
  3986. inputTextBox.Focused:Connect(function()
  3987. inputTextBox.SelectionStart = 1
  3988. inputTextBox.CursorPosition = #inputTextBox.Text + 1
  3989. end)
  3990.  
  3991. Lib.ViewportTextBox.convert(inputTextBox)
  3992. end
  3993.  
  3994. Properties.SetInputProp = function(prop,entryIndex,special)
  3995. local typeData = prop.ValueType
  3996. local typeName = typeData.Name
  3997. local fullName = prop.Class.."."..prop.Name..(prop.SubName or "")
  3998. local propObj = autoUpdateObjs[fullName]
  3999. local propVal = Properties.GetPropVal(prop,propObj)
  4000.  
  4001. if prop.Tags.ReadOnly then return end
  4002.  
  4003. inputProp = prop
  4004. if special then
  4005. if special == "color" then
  4006. if typeName == "Color3" then
  4007. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  4008. Properties.DisplayColorEditor(prop,propVal)
  4009. elseif typeName == "BrickColor" then
  4010. Properties.DisplayBrickColorEditor(prop,entryIndex,propVal)
  4011. elseif typeName == "ColorSequence" then
  4012. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  4013. Properties.DisplayColorSequenceEditor(prop,propVal)
  4014. end
  4015. elseif special == "right" then
  4016. if typeName == "NumberSequence" then
  4017. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  4018. Properties.DisplayNumberSequenceEditor(prop,propVal)
  4019. elseif typeName == "ColorSequence" then
  4020. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  4021. Properties.DisplayColorSequenceEditor(prop,propVal)
  4022. end
  4023. end
  4024. else
  4025. if Properties.IsTextEditable(prop) then
  4026. inputTextBox.Text = propVal and Properties.ValueToString(prop,propVal) or ""
  4027. inputTextBox:CaptureFocus()
  4028. elseif typeData.Category == "Enum" then
  4029. Properties.DisplayEnumDropdown(entryIndex)
  4030. elseif typeName == "BrickColor" then
  4031. Properties.DisplayBrickColorEditor(prop,entryIndex,propVal)
  4032. end
  4033. end
  4034. Properties.Refresh()
  4035. end
  4036.  
  4037. Properties.InitSearch = function()
  4038. local searchBox = Properties.GuiElems.ToolBar.SearchFrame.SearchBox
  4039.  
  4040. Lib.ViewportTextBox.convert(searchBox)
  4041.  
  4042. searchBox:GetPropertyChangedSignal("Text"):Connect(function()
  4043. Properties.SearchText = searchBox.Text
  4044. Properties.Update()
  4045. Properties.Refresh()
  4046. end)
  4047. end
  4048.  
  4049. Properties.InitEntryStuff = function()
  4050. Properties.EntryTemplate = create({
  4051. {1,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),Font=3,Name="Entry",Position=UDim2.new(0,1,0,1),Size=UDim2.new(0,250,0,22),Text="",TextSize=14,}},
  4052. {2,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BackgroundTransparency=1,BorderColor3=Color3.new(0.33725491166115,0.49019610881805,0.73725491762161),BorderSizePixel=0,Name="NameFrame",Parent={1},Position=UDim2.new(0,20,0,0),Size=UDim2.new(1,-40,1,0),}},
  4053. {3,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="PropName",Parent={2},Position=UDim2.new(0,2,0,0),Size=UDim2.new(1,-2,1,0),Text="Anchored",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,TextTruncate=1,TextXAlignment=0,}},
  4054. {4,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Font=3,Name="Expand",Parent={2},Position=UDim2.new(0,-20,0,1),Size=UDim2.new(0,20,0,20),Text="",TextSize=14,Visible=false,}},
  4055. {5,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642383285",ImageRectOffset=Vector2.new(144,16),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={4},Position=UDim2.new(0,2,0,2),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  4056. {6,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=4,Name="ToggleAttributes",Parent={2},Position=UDim2.new(1,-85,0,0),Size=UDim2.new(0,85,0,22),Text="[SETTING: OFF]",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,Visible=false,}},
  4057. {7,"Frame",{BackgroundColor3=Color3.new(0.04313725605607,0.35294118523598,0.68627452850342),BackgroundTransparency=1,BorderColor3=Color3.new(0.33725491166115,0.49019607901573,0.73725491762161),BorderSizePixel=0,Name="ValueFrame",Parent={1},Position=UDim2.new(1,-100,0,0),Size=UDim2.new(0,80,1,0),}},
  4058. {8,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderColor3=Color3.new(0.33725491166115,0.49019610881805,0.73725491762161),BorderSizePixel=0,Name="Line",Parent={7},Position=UDim2.new(0,-1,0,0),Size=UDim2.new(0,1,1,0),}},
  4059. {9,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="ColorButton",Parent={7},Size=UDim2.new(0,20,0,22),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  4060. {10,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0,0,0),Name="ColorPreview",Parent={9},Position=UDim2.new(0,5,0,6),Size=UDim2.new(0,10,0,10),}},
  4061. {11,"UIGradient",{Parent={10},}},
  4062. {12,"Frame",{BackgroundTransparency=1,Name="EnumArrow",Parent={7},Position=UDim2.new(1,-16,0,3),Size=UDim2.new(0,16,0,16),Visible=false,}},
  4063. {13,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={12},Position=UDim2.new(0,8,0,9),Size=UDim2.new(0,1,0,1),}},
  4064. {14,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={12},Position=UDim2.new(0,7,0,8),Size=UDim2.new(0,3,0,1),}},
  4065. {15,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={12},Position=UDim2.new(0,6,0,7),Size=UDim2.new(0,5,0,1),}},
  4066. {16,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="ValueBox",Parent={7},Position=UDim2.new(0,4,0,0),Size=UDim2.new(1,-8,1,0),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,TextTruncate=1,TextXAlignment=0,}},
  4067. {17,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="RightButton",Parent={7},Position=UDim2.new(1,-20,0,0),Size=UDim2.new(0,20,0,22),Text="...",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  4068. {18,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="SettingsButton",Parent={7},Position=UDim2.new(1,-20,0,0),Size=UDim2.new(0,20,0,22),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  4069. {19,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="SoundPreview",Parent={7},Size=UDim2.new(1,0,1,0),Visible=false,}},
  4070. {20,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="ControlButton",Parent={19},Size=UDim2.new(0,20,0,22),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  4071. {21,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642383285",ImageRectOffset=Vector2.new(144,16),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={20},Position=UDim2.new(0,2,0,3),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  4072. {22,"Frame",{BackgroundColor3=Color3.new(0.3137255012989,0.3137255012989,0.3137255012989),BorderSizePixel=0,Name="TimeLine",Parent={19},Position=UDim2.new(0,26,0.5,-1),Size=UDim2.new(1,-34,0,2),}},
  4073. {23,"Frame",{BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),Name="Slider",Parent={22},Position=UDim2.new(0,-4,0,-8),Size=UDim2.new(0,8,0,18),}},
  4074. {24,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="EditAttributeButton",Parent={1},Position=UDim2.new(1,-20,0,0),Size=UDim2.new(0,20,0,22),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  4075. {25,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034718180",ImageTransparency=0.20000000298023,Name="Icon",Parent={24},Position=UDim2.new(0,2,0,3),Size=UDim2.new(0,16,0,16),}},
  4076. {26,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderSizePixel=0,Font=3,Name="RowButton",Parent={1},Size=UDim2.new(1,0,1,0),Text="Add Attribute",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,Visible=false,}},
  4077. })
  4078.  
  4079. local fullNameFrame = Lib.Frame.new()
  4080. local label = Lib.Label.new()
  4081. label.Parent = fullNameFrame.Gui
  4082. label.Position = UDim2.new(0,2,0,0)
  4083. label.Size = UDim2.new(1,-4,1,0)
  4084. fullNameFrame.Visible = false
  4085. fullNameFrame.Parent = window.Gui
  4086.  
  4087. Properties.FullNameFrame = fullNameFrame
  4088. Properties.FullNameFrameAttach = Lib.AttachTo(fullNameFrame)
  4089. end
  4090.  
  4091. Properties.Init = function() -- TODO: MAKE BETTER
  4092. local guiItems = create({
  4093. {1,"Folder",{Name="Items",}},
  4094. {2,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="ToolBar",Parent={1},Size=UDim2.new(1,0,0,22),}},
  4095. {3,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.1176470592618,0.1176470592618,0.1176470592618),BorderSizePixel=0,Name="SearchFrame",Parent={2},Position=UDim2.new(0,3,0,1),Size=UDim2.new(1,-6,0,18),}},
  4096. {4,"TextBox",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClearTextOnFocus=false,Font=3,Name="SearchBox",Parent={3},PlaceholderColor3=Color3.new(0.39215689897537,0.39215689897537,0.39215689897537),PlaceholderText="Search properties",Position=UDim2.new(0,4,0,0),Size=UDim2.new(1,-24,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,}},
  4097. {5,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
  4098. {6,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Reset",Parent={3},Position=UDim2.new(1,-17,0,1),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  4099. {7,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034718129",ImageColor3=Color3.new(0.39215686917305,0.39215686917305,0.39215686917305),Parent={6},Size=UDim2.new(0,16,0,16),}},
  4100. {8,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Refresh",Parent={2},Position=UDim2.new(1,-20,0,1),Size=UDim2.new(0,18,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,Visible=false,}},
  4101. {9,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5642310344",Parent={8},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,12,0,12),}},
  4102. {10,"Frame",{BackgroundColor3=Color3.new(0.15686275064945,0.15686275064945,0.15686275064945),BorderSizePixel=0,Name="ScrollCorner",Parent={1},Position=UDim2.new(1,-16,1,-16),Size=UDim2.new(0,16,0,16),Visible=false,}},
  4103. {11,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ClipsDescendants=true,Name="List",Parent={1},Position=UDim2.new(0,0,0,23),Size=UDim2.new(1,0,1,-23),}},
  4104. })
  4105.  
  4106. -- Vars
  4107. categoryOrder = API.CategoryOrder
  4108. for category,_ in next,categoryOrder do
  4109. if not Properties.CollapsedCategories[category] then
  4110. expanded["CAT_"..category] = true
  4111. end
  4112. end
  4113. expanded["Sound.SoundId"] = true
  4114.  
  4115. -- Init window
  4116. window = Lib.Window.new()
  4117. Properties.Window = window
  4118. window:SetTitle("Properties")
  4119.  
  4120. toolBar = guiItems.ToolBar
  4121. propsFrame = guiItems.List
  4122.  
  4123. Properties.GuiElems.ToolBar = toolBar
  4124. Properties.GuiElems.PropsFrame = propsFrame
  4125.  
  4126. Properties.InitEntryStuff()
  4127.  
  4128. -- Window events
  4129. window.GuiElems.Main:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  4130. if Properties.Window:IsContentVisible() then
  4131. Properties.UpdateView()
  4132. Properties.Refresh()
  4133. end
  4134. end)
  4135. window.OnActivate:Connect(function()
  4136. Properties.UpdateView()
  4137. Properties.Update()
  4138. Properties.Refresh()
  4139. end)
  4140. window.OnRestore:Connect(function()
  4141. Properties.UpdateView()
  4142. Properties.Update()
  4143. Properties.Refresh()
  4144. end)
  4145.  
  4146. -- Init scrollbars
  4147. scrollV = Lib.ScrollBar.new()
  4148. scrollV.WheelIncrement = 3
  4149. scrollV.Gui.Position = UDim2.new(1,-16,0,23)
  4150. scrollV:SetScrollFrame(propsFrame)
  4151. scrollV.Scrolled:Connect(function()
  4152. Properties.Index = scrollV.Index
  4153. Properties.Refresh()
  4154. end)
  4155.  
  4156. scrollH = Lib.ScrollBar.new(true)
  4157. scrollH.Increment = 5
  4158. scrollH.WheelIncrement = 20
  4159. scrollH.Gui.Position = UDim2.new(0,0,1,-16)
  4160. scrollH.Scrolled:Connect(function()
  4161. Properties.Refresh()
  4162. end)
  4163.  
  4164. -- Setup Gui
  4165. window.GuiElems.Line.Position = UDim2.new(0,0,0,22)
  4166. toolBar.Parent = window.GuiElems.Content
  4167. propsFrame.Parent = window.GuiElems.Content
  4168. guiItems.ScrollCorner.Parent = window.GuiElems.Content
  4169. scrollV.Gui.Parent = window.GuiElems.Content
  4170. scrollH.Gui.Parent = window.GuiElems.Content
  4171. Properties.InitInputBox()
  4172. Properties.InitSearch()
  4173. end
  4174.  
  4175. return Properties
  4176. end
  4177.  
  4178. return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  4179. end,
  4180. ScriptViewer = function()
  4181. --[[
  4182. Script Viewer App Module
  4183.  
  4184. A script viewer that is basically a notepad
  4185. ]]
  4186.  
  4187. -- Common Locals
  4188. local Main,Lib,Apps,Settings -- Main Containers
  4189. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  4190. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  4191.  
  4192. local function initDeps(data)
  4193. Main = data.Main
  4194. Lib = data.Lib
  4195. Apps = data.Apps
  4196. Settings = data.Settings
  4197.  
  4198. API = data.API
  4199. RMD = data.RMD
  4200. env = data.env
  4201. service = data.service
  4202. plr = data.plr
  4203. create = data.create
  4204. createSimple = data.createSimple
  4205. end
  4206.  
  4207. local function initAfterMain()
  4208. Explorer = Apps.Explorer
  4209. Properties = Apps.Properties
  4210. ScriptViewer = Apps.ScriptViewer
  4211. Notebook = Apps.Notebook
  4212. end
  4213.  
  4214. local function main()
  4215. local ScriptViewer = {}
  4216. local window, codeFrame
  4217. local PreviousScr = nil
  4218.  
  4219. ScriptViewer.ViewScript = function(scr)
  4220. local success, source = pcall(env.decompile or function() end, scr)
  4221. if not success or not source then source, PreviousScr = "-- DEX - Source failed to decompile", nil else PreviousScr = scr end
  4222. codeFrame:SetText(source)
  4223. window:Show()
  4224. end
  4225.  
  4226. ScriptViewer.Init = function()
  4227. window = Lib.Window.new()
  4228. window:SetTitle("Script Viewer")
  4229. window:Resize(500,400)
  4230. ScriptViewer.Window = window
  4231.  
  4232. codeFrame = Lib.CodeFrame.new()
  4233. codeFrame.Frame.Position = UDim2.new(0,0,0,20)
  4234. codeFrame.Frame.Size = UDim2.new(1,0,1,-20)
  4235. codeFrame.Frame.Parent = window.GuiElems.Content
  4236.  
  4237. -- TODO: REMOVE AND MAKE BETTER
  4238. local copy = Instance.new("TextButton",window.GuiElems.Content)
  4239. copy.BackgroundTransparency = 1
  4240. copy.Size = UDim2.new(0.5,0,0,20)
  4241. copy.Text = "Copy to Clipboard"
  4242. copy.TextColor3 = Color3.new(1,1,1)
  4243.  
  4244. copy.MouseButton1Click:Connect(function()
  4245. local source = codeFrame:GetText()
  4246. setclipboard(source)
  4247. end)
  4248.  
  4249. local save = Instance.new("TextButton",window.GuiElems.Content)
  4250. save.BackgroundTransparency = 1
  4251. save.Position = UDim2.new(0.35,0,0,0)
  4252. save.Size = UDim2.new(0.3,0,0,20)
  4253. save.Text = "Save to File"
  4254. save.TextColor3 = Color3.new(1,1,1)
  4255.  
  4256. save.MouseButton1Click:Connect(function()
  4257. local source = codeFrame:GetText()
  4258. local filename = "Place_"..game.PlaceId.."_Script_"..os.time()..".txt"
  4259.  
  4260. writefile(filename,source)
  4261. if movefileas then -- TODO: USE ENV
  4262. movefileas(filename,".txt")
  4263. end
  4264. end)
  4265.  
  4266. local dumpbtn = Instance.new("TextButton",window.GuiElems.Content)
  4267. dumpbtn.BackgroundTransparency = 1
  4268. dumpbtn.Position = UDim2.new(0.7,0,0,0)
  4269. dumpbtn.Size = UDim2.new(0.3,0,0,20)
  4270. dumpbtn.Text = "Dump Functions"
  4271. dumpbtn.TextColor3 = Color3.new(1,1,1)
  4272.  
  4273. dumpbtn.MouseButton1Click:Connect(function()
  4274. if PreviousScr ~= nil then
  4275. pcall(function()
  4276. -- thanks King.Kevin#6025 you'll obviously be credited (no discord tag since that can easily be impersonated)
  4277. local getgc = getgc or get_gc_objects
  4278. local getupvalues = (debug and debug.getupvalues) or getupvalues or getupvals
  4279. local getconstants = (debug and debug.getconstants) or getconstants or getconsts
  4280. local getinfo = (debug and (debug.getinfo or debug.info)) or getinfo
  4281. local original = ("\n-- // Function Dumper made by King.Kevin\n-- // Script Path: %s\n\n--[["):format(PreviousScr:GetFullName())
  4282. local dump = original
  4283. local functions, function_count, data_base = {}, 0, {}
  4284. function functions:add_to_dump(str, indentation, new_line)
  4285. local new_line = new_line or true
  4286. dump = dump .. ("%s%s%s"):format(string.rep(" ", indentation), tostring(str), new_line and "\n" or "")
  4287. end
  4288. function functions:get_function_name(func)
  4289. local n = getinfo(func).name
  4290. return n ~= "" and n or "Unknown Name"
  4291. end
  4292. function functions:dump_table(input, indent, index)
  4293. local indent = indent < 0 and 0 or indent
  4294. functions:add_to_dump(("%s [%s] %s"):format(tostring(index), tostring(typeof(input)), tostring(input)), indent - 1)
  4295. local count = 0
  4296. for index, value in pairs(input) do
  4297. count = count + 1
  4298. if type(value) == "function" then
  4299. functions:add_to_dump(("%d [function] = %s"):format(count, functions:get_function_name(value)), indent)
  4300. elseif type(value) == "table" then
  4301. if not data_base[value] then
  4302. data_base[value] = true
  4303. functions:add_to_dump(("%d [table]:"):format(count), indent)
  4304. functions:dump_table(value, indent + 1, index)
  4305. else
  4306. functions:add_to_dump(("%d [table] (Recursive table detected)"):format(count), indent)
  4307. end
  4308. else
  4309. functions:add_to_dump(("%d [%s] = %s"):format(count, tostring(typeof(value)), tostring(value)), indent)
  4310. end
  4311. end
  4312. end
  4313. function functions:dump_function(input, indent)
  4314. functions:add_to_dump(("\nFunction Dump: %s"):format(functions:get_function_name(input)), indent)
  4315. functions:add_to_dump(("\nFunction Upvalues: %s"):format(functions:get_function_name(input)), indent)
  4316. for index, upvalue in pairs(getupvalues(input)) do
  4317. if type(upvalue) == "function" then
  4318. functions:add_to_dump(("%d [function] = %s"):format(index, functions:get_function_name(upvalue)), indent + 1)
  4319. elseif type(upvalue) == "table" then
  4320. if not data_base[upvalue] then
  4321. data_base[upvalue] = true
  4322. functions:add_to_dump(("%d [table]:"):format(index), indent + 1)
  4323. functions:dump_table(upvalue, indent + 2, index)
  4324. else
  4325. functions:add_to_dump(("%d [table] (Recursive table detected)"):format(index), indent + 1)
  4326. end
  4327. else
  4328. functions:add_to_dump(("%d [%s] = %s"):format(index, tostring(typeof(upvalue)), tostring(upvalue)), indent + 1)
  4329. end
  4330. end
  4331. functions:add_to_dump(("\nFunction Constants: %s"):format(functions:get_function_name(input)), indent)
  4332. for index, constant in pairs(getconstants(input)) do
  4333. if type(constant) == "function" then
  4334. functions:add_to_dump(("%d [function] = %s"):format(index, functions:get_function_name(constant)), indent + 1)
  4335. elseif type(constant) == "table" then
  4336. if not data_base[constant] then
  4337. data_base[constant] = true
  4338. functions:add_to_dump(("%d [table]:"):format(index), indent + 1)
  4339. functions:dump_table(constant, indent + 2, index)
  4340. else
  4341. functions:add_to_dump(("%d [table] (Recursive table detected)"):format(index), indent + 1)
  4342. end
  4343. else
  4344. functions:add_to_dump(("%d [%s] = %s"):format(index, tostring(typeof(constant)), tostring(constant)), indent + 1)
  4345. end
  4346. end
  4347. end
  4348. for _, _function in pairs(getgc()) do
  4349. if typeof(_function) == "function" and getfenv(_function).script and getfenv(_function).script == PreviousScr then
  4350. functions:dump_function(_function, 0)
  4351. functions:add_to_dump("\n" .. ("="):rep(100), 0, false)
  4352. end
  4353. end
  4354. local source = codeFrame:GetText()
  4355. if dump ~= original then source = source .. dump .. "]]" end
  4356. codeFrame:SetText(source)
  4357. end)
  4358. end
  4359. end)
  4360. end
  4361.  
  4362. return ScriptViewer
  4363. end
  4364.  
  4365. return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  4366. end,
  4367. Lib = function()
  4368. --[[
  4369. Lib Module
  4370.  
  4371. Container for functions and classes
  4372. ]]
  4373.  
  4374. -- Common Locals
  4375. local Main,Lib,Apps,Settings -- Main Containers
  4376. local Explorer, Properties, ScriptViewer, Notebook -- Major Apps
  4377. local API,RMD,env,service,plr,create,createSimple -- Main Locals
  4378.  
  4379. local function initDeps(data)
  4380. Main = data.Main
  4381. Lib = data.Lib
  4382. Apps = data.Apps
  4383. Settings = data.Settings
  4384.  
  4385. API = data.API
  4386. RMD = data.RMD
  4387. env = data.env
  4388. service = data.service
  4389. plr = data.plr
  4390. create = data.create
  4391. createSimple = data.createSimple
  4392. end
  4393.  
  4394. local function initAfterMain()
  4395. Explorer = Apps.Explorer
  4396. Properties = Apps.Properties
  4397. ScriptViewer = Apps.ScriptViewer
  4398. Notebook = Apps.Notebook
  4399. end
  4400.  
  4401. local function main()
  4402. local Lib = {}
  4403.  
  4404. local renderStepped = service.RunService.RenderStepped
  4405. local signalWait = renderStepped.wait
  4406. local PH = newproxy() -- Placeholder, must be replaced in constructor
  4407. local SIGNAL = newproxy()
  4408.  
  4409. -- Usually for classes that work with a Roblox Object
  4410. local function initObj(props,mt)
  4411. local type = type
  4412. local function copy(t)
  4413. local res = {}
  4414. for i,v in pairs(t) do
  4415. if v == SIGNAL then
  4416. res[i] = Lib.Signal.new()
  4417. elseif type(v) == "table" then
  4418. res[i] = copy(v)
  4419. else
  4420. res[i] = v
  4421. end
  4422. end
  4423. return res
  4424. end
  4425.  
  4426. local newObj = copy(props)
  4427. return setmetatable(newObj,mt)
  4428. end
  4429.  
  4430. local function getGuiMT(props,funcs)
  4431. return {__index = function(self,ind) if not props[ind] then return funcs[ind] or self.Gui[ind] end end,
  4432. __newindex = function(self,ind,val) if not props[ind] then self.Gui[ind] = val else rawset(self,ind,val) end end}
  4433. end
  4434.  
  4435. -- Functions
  4436.  
  4437. Lib.FormatLuaString = (function()
  4438. local string = string
  4439. local gsub = string.gsub
  4440. local format = string.format
  4441. local char = string.char
  4442. local cleanTable = {['"'] = '\\"', ['\\'] = '\\\\'}
  4443. for i = 0,31 do
  4444. cleanTable[char(i)] = "\\"..format("%03d",i)
  4445. end
  4446. for i = 127,255 do
  4447. cleanTable[char(i)] = "\\"..format("%03d",i)
  4448. end
  4449.  
  4450. return function(str)
  4451. return gsub(str,"[\"\\\0-\31\127-\255]",cleanTable)
  4452. end
  4453. end)()
  4454.  
  4455. Lib.CheckMouseInGui = function(gui)
  4456. if gui == nil then return false end
  4457. local mouse = Main.Mouse
  4458. local guiPosition = gui.AbsolutePosition
  4459. local guiSize = gui.AbsoluteSize
  4460.  
  4461. return mouse.X >= guiPosition.X and mouse.X < guiPosition.X + guiSize.X and mouse.Y >= guiPosition.Y and mouse.Y < guiPosition.Y + guiSize.Y
  4462. end
  4463.  
  4464. Lib.IsShiftDown = function()
  4465. return service.UserInputService:IsKeyDown(Enum.KeyCode.LeftShift) or service.UserInputService:IsKeyDown(Enum.KeyCode.RightShift)
  4466. end
  4467.  
  4468. Lib.IsCtrlDown = function()
  4469. return service.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or service.UserInputService:IsKeyDown(Enum.KeyCode.RightControl)
  4470. end
  4471.  
  4472. Lib.CreateArrow = function(size,num,dir)
  4473. local max = num
  4474. local arrowFrame = createSimple("Frame",{
  4475. BackgroundTransparency = 1,
  4476. Name = "Arrow",
  4477. Size = UDim2.new(0,size,0,size)
  4478. })
  4479. if dir == "up" then
  4480. for i = 1,num do
  4481. local newLine = createSimple("Frame",{
  4482. BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  4483. BorderSizePixel = 0,
  4484. Position = UDim2.new(0,math.floor(size/2)-(i-1),0,math.floor(size/2)+i-math.floor(max/2)-1),
  4485. Size = UDim2.new(0,i+(i-1),0,1),
  4486. Parent = arrowFrame
  4487. })
  4488. end
  4489. return arrowFrame
  4490. elseif dir == "down" then
  4491. for i = 1,num do
  4492. local newLine = createSimple("Frame",{
  4493. BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  4494. BorderSizePixel = 0,
  4495. Position = UDim2.new(0,math.floor(size/2)-(i-1),0,math.floor(size/2)-i+math.floor(max/2)+1),
  4496. Size = UDim2.new(0,i+(i-1),0,1),
  4497. Parent = arrowFrame
  4498. })
  4499. end
  4500. return arrowFrame
  4501. elseif dir == "left" then
  4502. for i = 1,num do
  4503. local newLine = createSimple("Frame",{
  4504. BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  4505. BorderSizePixel = 0,
  4506. Position = UDim2.new(0,math.floor(size/2)+i-math.floor(max/2)-1,0,math.floor(size/2)-(i-1)),
  4507. Size = UDim2.new(0,1,0,i+(i-1)),
  4508. Parent = arrowFrame
  4509. })
  4510. end
  4511. return arrowFrame
  4512. elseif dir == "right" then
  4513. for i = 1,num do
  4514. local newLine = createSimple("Frame",{
  4515. BackgroundColor3 = Color3.new(220/255,220/255,220/255),
  4516. BorderSizePixel = 0,
  4517. Position = UDim2.new(0,math.floor(size/2)-i+math.floor(max/2)+1,0,math.floor(size/2)-(i-1)),
  4518. Size = UDim2.new(0,1,0,i+(i-1)),
  4519. Parent = arrowFrame
  4520. })
  4521. end
  4522. return arrowFrame
  4523. end
  4524. error("r u ok")
  4525. end
  4526.  
  4527. Lib.ParseXML = (function()
  4528. local func = function()
  4529. -- Only exists to parse RMD
  4530. -- from https://github.com/jonathanpoelen/xmlparser
  4531.  
  4532. local string, print, pairs = string, print, pairs
  4533.  
  4534. -- http://lua-users.org/wiki/StringTrim
  4535. local trim = function(s)
  4536. local from = s:match"^%s*()"
  4537. return from > #s and "" or s:match(".*%S", from)
  4538. end
  4539.  
  4540. local gtchar = string.byte('>', 1)
  4541. local slashchar = string.byte('/', 1)
  4542. local D = string.byte('D', 1)
  4543. local E = string.byte('E', 1)
  4544.  
  4545. function parse(s, evalEntities)
  4546. -- remove comments
  4547. s = s:gsub('<!%-%-(.-)%-%->', '')
  4548.  
  4549. local entities, tentities = {}
  4550.  
  4551. if evalEntities then
  4552. local pos = s:find('<[_%w]')
  4553. if pos then
  4554. s:sub(1, pos):gsub('<!ENTITY%s+([_%w]+)%s+(.)(.-)%2', function(name, q, entity)
  4555. entities[#entities+1] = {name=name, value=entity}
  4556. end)
  4557. tentities = createEntityTable(entities)
  4558. s = replaceEntities(s:sub(pos), tentities)
  4559. end
  4560. end
  4561.  
  4562. local t, l = {}, {}
  4563.  
  4564. local addtext = function(txt)
  4565. txt = txt:match'^%s*(.*%S)' or ''
  4566. if #txt ~= 0 then
  4567. t[#t+1] = {text=txt}
  4568. end
  4569. end
  4570.  
  4571. s:gsub('<([?!/]?)([-:_%w]+)%s*(/?>?)([^<]*)', function(type, name, closed, txt)
  4572. -- open
  4573. if #type == 0 then
  4574. local a = {}
  4575. if #closed == 0 then
  4576. local len = 0
  4577. for all,aname,_,value,starttxt in string.gmatch(txt, "(.-([-_%w]+)%s*=%s*(.)(.-)%3%s*(/?>?))") do
  4578. len = len + #all
  4579. a[aname] = value
  4580. if #starttxt ~= 0 then
  4581. txt = txt:sub(len+1)
  4582. closed = starttxt
  4583. break
  4584. end
  4585. end
  4586. end
  4587. t[#t+1] = {tag=name, attrs=a, children={}}
  4588.  
  4589. if closed:byte(1) ~= slashchar then
  4590. l[#l+1] = t
  4591. t = t[#t].children
  4592. end
  4593.  
  4594. addtext(txt)
  4595. -- close
  4596. elseif '/' == type then
  4597. t = l[#l]
  4598. l[#l] = nil
  4599.  
  4600. addtext(txt)
  4601. -- ENTITY
  4602. elseif '!' == type then
  4603. if E == name:byte(1) then
  4604. txt:gsub('([_%w]+)%s+(.)(.-)%2', function(name, q, entity)
  4605. entities[#entities+1] = {name=name, value=entity}
  4606. end, 1)
  4607. end
  4608. -- elseif '?' == type then
  4609. -- print('? ' .. name .. ' // ' .. attrs .. '$$')
  4610. -- elseif '-' == type then
  4611. -- print('comment ' .. name .. ' // ' .. attrs .. '$$')
  4612. -- else
  4613. -- print('o ' .. #p .. ' // ' .. name .. ' // ' .. attrs .. '$$')
  4614. end
  4615. end)
  4616.  
  4617. return {children=t, entities=entities, tentities=tentities}
  4618. end
  4619.  
  4620. function parseText(txt)
  4621. return parse(txt)
  4622. end
  4623.  
  4624. function defaultEntityTable()
  4625. return { quot='"', apos='\'', lt='<', gt='>', amp='&', tab='\t', nbsp=' ', }
  4626. end
  4627.  
  4628. function replaceEntities(s, entities)
  4629. return s:gsub('&([^;]+);', entities)
  4630. end
  4631.  
  4632. function createEntityTable(docEntities, resultEntities)
  4633. entities = resultEntities or defaultEntityTable()
  4634. for _,e in pairs(docEntities) do
  4635. e.value = replaceEntities(e.value, entities)
  4636. entities[e.name] = e.value
  4637. end
  4638. return entities
  4639. end
  4640.  
  4641. return parseText
  4642. end
  4643. local newEnv = setmetatable({},{__index = getfenv()})
  4644. setfenv(func,newEnv)
  4645. return func()
  4646. end)()
  4647.  
  4648. Lib.FastWait = function(s)
  4649. if not s then return signalWait(renderStepped) end
  4650. local start = tick()
  4651. while tick() - start < s do signalWait(renderStepped) end
  4652. end
  4653.  
  4654. Lib.ButtonAnim = function(button,data)
  4655. local holding = false
  4656. local disabled = false
  4657. local mode = data and data.Mode or 1
  4658. local control = {}
  4659.  
  4660. if mode == 2 then
  4661. local lerpTo = data.LerpTo or Color3.new(0,0,0)
  4662. local delta = data.LerpDelta or 0.2
  4663. control.StartColor = data.StartColor or button.BackgroundColor3
  4664. control.PressColor = data.PressColor or control.StartColor:lerp(lerpTo,delta)
  4665. control.HoverColor = data.HoverColor or control.StartColor:lerp(control.PressColor,0.6)
  4666. control.OutlineColor = data.OutlineColor
  4667. end
  4668.  
  4669. button.InputBegan:Connect(function(input)
  4670. if disabled then return end
  4671. if input.UserInputType == Enum.UserInputType.MouseMovement and not holding then
  4672. if mode == 1 then
  4673. button.BackgroundTransparency = 0.4
  4674. elseif mode == 2 then
  4675. button.BackgroundColor3 = control.HoverColor
  4676. end
  4677. elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  4678. holding = true
  4679. if mode == 1 then
  4680. button.BackgroundTransparency = 0
  4681. elseif mode == 2 then
  4682. button.BackgroundColor3 = control.PressColor
  4683. if control.OutlineColor then button.BorderColor3 = control.PressColor end
  4684. end
  4685. end
  4686. end)
  4687.  
  4688. button.InputEnded:Connect(function(input)
  4689. if disabled then return end
  4690. if input.UserInputType == Enum.UserInputType.MouseMovement and not holding then
  4691. if mode == 1 then
  4692. button.BackgroundTransparency = 1
  4693. elseif mode == 2 then
  4694. button.BackgroundColor3 = control.StartColor
  4695. end
  4696. elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  4697. holding = false
  4698. if mode == 1 then
  4699. button.BackgroundTransparency = Lib.CheckMouseInGui(button) and 0.4 or 1
  4700. elseif mode == 2 then
  4701. button.BackgroundColor3 = Lib.CheckMouseInGui(button) and control.HoverColor or control.StartColor
  4702. if control.OutlineColor then button.BorderColor3 = control.OutlineColor end
  4703. end
  4704. end
  4705. end)
  4706.  
  4707. control.Disable = function()
  4708. disabled = true
  4709. holding = false
  4710.  
  4711. if mode == 1 then
  4712. button.BackgroundTransparency = 1
  4713. elseif mode == 2 then
  4714. button.BackgroundColor3 = control.StartColor
  4715. end
  4716. end
  4717.  
  4718. control.Enable = function()
  4719. disabled = false
  4720. end
  4721.  
  4722. return control
  4723. end
  4724.  
  4725. Lib.FindAndRemove = function(t,item)
  4726. local pos = table.find(t,item)
  4727. if pos then table.remove(t,pos) end
  4728. end
  4729.  
  4730. Lib.AttachTo = function(obj,data)
  4731. local target,posOffX,posOffY,sizeOffX,sizeOffY,resize,con
  4732. local disabled = false
  4733.  
  4734. local function update()
  4735. if not obj or not target then return end
  4736.  
  4737. local targetPos = target.AbsolutePosition
  4738. local targetSize = target.AbsoluteSize
  4739. obj.Position = UDim2.new(0,targetPos.X + posOffX,0,targetPos.Y + posOffY)
  4740. if resize then obj.Size = UDim2.new(0,targetSize.X + sizeOffX,0,targetSize.Y + sizeOffY) end
  4741. end
  4742.  
  4743. local function setup(o,data)
  4744. obj = o
  4745. data = data or {}
  4746. target = data.Target
  4747. posOffX = data.PosOffX or 0
  4748. posOffY = data.PosOffY or 0
  4749. sizeOffX = data.SizeOffX or 0
  4750. sizeOffY = data.SizeOffY or 0
  4751. resize = data.Resize or false
  4752.  
  4753. if con then con:Disconnect() con = nil end
  4754. if target then
  4755. con = target.Changed:Connect(function(prop)
  4756. if not disabled and prop == "AbsolutePosition" or prop == "AbsoluteSize" then
  4757. update()
  4758. end
  4759. end)
  4760. end
  4761.  
  4762. update()
  4763. end
  4764. setup(obj,data)
  4765.  
  4766. return {
  4767. SetData = function(obj,data)
  4768. setup(obj,data)
  4769. end,
  4770. Enable = function()
  4771. disabled = false
  4772. update()
  4773. end,
  4774. Disable = function()
  4775. disabled = true
  4776. end,
  4777. Destroy = function()
  4778. con:Disconnect()
  4779. con = nil
  4780. end,
  4781. }
  4782. end
  4783.  
  4784. Lib.ProtectedGuis = {}
  4785.  
  4786. Lib.ShowGui = function(gui)
  4787. if env.protectgui then
  4788. env.protectgui(gui)
  4789. end
  4790. gui.Parent = Main.GuiHolder
  4791. end
  4792.  
  4793. Lib.ColorToBytes = function(col)
  4794. local round = math.round
  4795. return string.format("%d, %d, %d",round(col.r*255),round(col.g*255),round(col.b*255))
  4796. end
  4797.  
  4798. Lib.ReadFile = function(filename)
  4799. if not env.readfile then return end
  4800.  
  4801. local s,contents = pcall(env.readfile,filename)
  4802. if s and contents then return contents end
  4803. end
  4804.  
  4805. Lib.DeferFunc = function(f,...)
  4806. signalWait(renderStepped)
  4807. return f(...)
  4808. end
  4809.  
  4810. Lib.LoadCustomAsset = function(filepath)
  4811. if not env.getcustomasset or not env.isfile or not env.isfile(filepath) then return end
  4812.  
  4813. return env.getcustomasset(filepath)
  4814. end
  4815.  
  4816. Lib.FetchCustomAsset = function(url,filepath)
  4817. if not env.writefile then return end
  4818.  
  4819. local s,data = pcall(game.HttpGet,game,url)
  4820. if not s then return end
  4821.  
  4822. env.writefile(filepath,data)
  4823. return Lib.LoadCustomAsset(filepath)
  4824. end
  4825.  
  4826. -- Classes
  4827.  
  4828. Lib.Signal = (function()
  4829. local funcs = {}
  4830.  
  4831. local disconnect = function(con)
  4832. local pos = table.find(con.Signal.Connections,con)
  4833. if pos then table.remove(con.Signal.Connections,pos) end
  4834. end
  4835.  
  4836. funcs.Connect = function(self,func)
  4837. if type(func) ~= "function" then error("Attempt to connect a non-function") end
  4838. local con = {
  4839. Signal = self,
  4840. Func = func,
  4841. Disconnect = disconnect
  4842. }
  4843. self.Connections[#self.Connections+1] = con
  4844. return con
  4845. end
  4846.  
  4847. funcs.Fire = function(self,...)
  4848. for i,v in next,self.Connections do
  4849. xpcall(coroutine.wrap(v.Func),function(e) warn(e.."\n"..debug.traceback()) end,...)
  4850. end
  4851. end
  4852.  
  4853. local mt = {
  4854. __index = funcs,
  4855. __tostring = function(self)
  4856. return "Signal: " .. tostring(#self.Connections) .. " Connections"
  4857. end
  4858. }
  4859.  
  4860. local function new()
  4861. local obj = {}
  4862. obj.Connections = {}
  4863.  
  4864. return setmetatable(obj,mt)
  4865. end
  4866.  
  4867. return {new = new}
  4868. end)()
  4869.  
  4870. Lib.Set = (function()
  4871. local funcs = {}
  4872.  
  4873. funcs.Add = function(self,obj)
  4874. if self.Map[obj] then return end
  4875.  
  4876. local list = self.List
  4877. list[#list+1] = obj
  4878. self.Map[obj] = true
  4879. self.Changed:Fire()
  4880. end
  4881.  
  4882. funcs.AddTable = function(self,t)
  4883. local changed
  4884. local list,map = self.List,self.Map
  4885. for i = 1,#t do
  4886. local elem = t[i]
  4887. if not map[elem] then
  4888. list[#list+1] = elem
  4889. map[elem] = true
  4890. changed = true
  4891. end
  4892. end
  4893. if changed then self.Changed:Fire() end
  4894. end
  4895.  
  4896. funcs.Remove = function(self,obj)
  4897. if not self.Map[obj] then return end
  4898.  
  4899. local list = self.List
  4900. local pos = table.find(list,obj)
  4901. if pos then table.remove(list,pos) end
  4902. self.Map[obj] = nil
  4903. self.Changed:Fire()
  4904. end
  4905.  
  4906. funcs.RemoveTable = function(self,t)
  4907. local changed
  4908. local list,map = self.List,self.Map
  4909. local removeSet = {}
  4910. for i = 1,#t do
  4911. local elem = t[i]
  4912. map[elem] = nil
  4913. removeSet[elem] = true
  4914. end
  4915.  
  4916. for i = #list,1,-1 do
  4917. local elem = list[i]
  4918. if removeSet[elem] then
  4919. table.remove(list,i)
  4920. changed = true
  4921. end
  4922. end
  4923. if changed then self.Changed:Fire() end
  4924. end
  4925.  
  4926. funcs.Set = function(self,obj)
  4927. if #self.List == 1 and self.List[1] == obj then return end
  4928.  
  4929. self.List = {obj}
  4930. self.Map = {[obj] = true}
  4931. self.Changed:Fire()
  4932. end
  4933.  
  4934. funcs.SetTable = function(self,t)
  4935. local newList,newMap = {},{}
  4936. self.List,self.Map = newList,newMap
  4937. table.move(t,1,#t,1,newList)
  4938. for i = 1,#t do
  4939. newMap[t[i]] = true
  4940. end
  4941. self.Changed:Fire()
  4942. end
  4943.  
  4944. funcs.Clear = function(self)
  4945. if #self.List == 0 then return end
  4946. self.List = {}
  4947. self.Map = {}
  4948. self.Changed:Fire()
  4949. end
  4950.  
  4951. local mt = {__index = funcs}
  4952.  
  4953. local function new()
  4954. local obj = setmetatable({
  4955. List = {},
  4956. Map = {},
  4957. Changed = Lib.Signal.new()
  4958. },mt)
  4959.  
  4960. return obj
  4961. end
  4962.  
  4963. return {new = new}
  4964. end)()
  4965.  
  4966. Lib.IconMap = (function()
  4967. local funcs = {}
  4968.  
  4969. funcs.GetLabel = function(self)
  4970. local label = Instance.new("ImageLabel")
  4971. self:SetupLabel(label)
  4972. return label
  4973. end
  4974.  
  4975. funcs.SetupLabel = function(self,obj)
  4976. obj.BackgroundTransparency = 1
  4977. obj.ImageRectOffset = Vector2.new(0,0)
  4978. obj.ImageRectSize = Vector2.new(self.IconSizeX,self.IconSizeY)
  4979. obj.ScaleType = Enum.ScaleType.Crop
  4980. obj.Size = UDim2.new(0,self.IconSizeX,0,self.IconSizeY)
  4981. end
  4982.  
  4983. funcs.Display = function(self,obj,index)
  4984. obj.Image = self.MapId
  4985. if not self.NumX then
  4986. obj.ImageRectOffset = Vector2.new(self.IconSizeX*index, 0)
  4987. else
  4988. obj.ImageRectOffset = Vector2.new(self.IconSizeX*(index % self.NumX), self.IconSizeY*math.floor(index / self.NumX))
  4989. end
  4990. end
  4991.  
  4992. funcs.DisplayByKey = function(self,obj,key)
  4993. if self.IndexDict[key] then
  4994. self:Display(obj,self.IndexDict[key])
  4995. end
  4996. end
  4997.  
  4998. funcs.SetDict = function(self,dict)
  4999. self.IndexDict = dict
  5000. end
  5001.  
  5002. local mt = {}
  5003. mt.__index = funcs
  5004.  
  5005. local function new(mapId,mapSizeX,mapSizeY,iconSizeX,iconSizeY)
  5006. local obj = setmetatable({
  5007. MapId = mapId,
  5008. MapSizeX = mapSizeX,
  5009. MapSizeY = mapSizeY,
  5010. IconSizeX = iconSizeX,
  5011. IconSizeY = iconSizeY,
  5012. NumX = mapSizeX/iconSizeX,
  5013. IndexDict = {}
  5014. },mt)
  5015. return obj
  5016. end
  5017.  
  5018. local function newLinear(mapId,iconSizeX,iconSizeY)
  5019. local obj = setmetatable({
  5020. MapId = mapId,
  5021. IconSizeX = iconSizeX,
  5022. IconSizeY = iconSizeY,
  5023. IndexDict = {}
  5024. },mt)
  5025. return obj
  5026. end
  5027.  
  5028. return {new = new, newLinear = newLinear}
  5029. end)()
  5030.  
  5031. Lib.ScrollBar = (function()
  5032. local funcs = {}
  5033. local user = service.UserInputService
  5034. local mouse = plr:GetMouse()
  5035. local checkMouseInGui = Lib.CheckMouseInGui
  5036. local createArrow = Lib.CreateArrow
  5037.  
  5038. local function drawThumb(self)
  5039. local total = self.TotalSpace
  5040. local visible = self.VisibleSpace
  5041. local index = self.Index
  5042. local scrollThumb = self.GuiElems.ScrollThumb
  5043. local scrollThumbFrame = self.GuiElems.ScrollThumbFrame
  5044.  
  5045. if not (self:CanScrollUp() or self:CanScrollDown()) then
  5046. scrollThumb.Visible = false
  5047. else
  5048. scrollThumb.Visible = true
  5049. end
  5050.  
  5051. if self.Horizontal then
  5052. scrollThumb.Size = UDim2.new(visible/total,0,1,0)
  5053. if scrollThumb.AbsoluteSize.X < 16 then
  5054. scrollThumb.Size = UDim2.new(0,16,1,0)
  5055. end
  5056. local fs = scrollThumbFrame.AbsoluteSize.X
  5057. local bs = scrollThumb.AbsoluteSize.X
  5058. scrollThumb.Position = UDim2.new(self:GetScrollPercent()*(fs-bs)/fs,0,0,0)
  5059. else
  5060. scrollThumb.Size = UDim2.new(1,0,visible/total,0)
  5061. if scrollThumb.AbsoluteSize.Y < 16 then
  5062. scrollThumb.Size = UDim2.new(1,0,0,16)
  5063. end
  5064. local fs = scrollThumbFrame.AbsoluteSize.Y
  5065. local bs = scrollThumb.AbsoluteSize.Y
  5066. scrollThumb.Position = UDim2.new(0,0,self:GetScrollPercent()*(fs-bs)/fs,0)
  5067. end
  5068. end
  5069.  
  5070. local function createFrame(self)
  5071. local newFrame = createSimple("Frame",{Style=0,Active=true,AnchorPoint=Vector2.new(0,0),BackgroundColor3=Color3.new(0.35294118523598,0.35294118523598,0.35294118523598),BackgroundTransparency=0,BorderColor3=Color3.new(0.10588236153126,0.16470588743687,0.20784315466881),BorderSizePixel=0,ClipsDescendants=false,Draggable=false,Position=UDim2.new(1,-16,0,0),Rotation=0,Selectable=false,Size=UDim2.new(0,16,1,0),SizeConstraint=0,Visible=true,ZIndex=1,Name="ScrollBar",})
  5072. local button1 = nil
  5073. local button2 = nil
  5074.  
  5075. if self.Horizontal then
  5076. newFrame.Size = UDim2.new(1,0,0,16)
  5077. button1 = createSimple("ImageButton",{
  5078. Parent = newFrame,
  5079. Name = "Left",
  5080. Size = UDim2.new(0,16,0,16),
  5081. BackgroundTransparency = 1,
  5082. BorderSizePixel = 0,
  5083. AutoButtonColor = false
  5084. })
  5085. createArrow(16,4,"left").Parent = button1
  5086. button2 = createSimple("ImageButton",{
  5087. Parent = newFrame,
  5088. Name = "Right",
  5089. Position = UDim2.new(1,-16,0,0),
  5090. Size = UDim2.new(0,16,0,16),
  5091. BackgroundTransparency = 1,
  5092. BorderSizePixel = 0,
  5093. AutoButtonColor = false
  5094. })
  5095. createArrow(16,4,"right").Parent = button2
  5096. else
  5097. newFrame.Size = UDim2.new(0,16,1,0)
  5098. button1 = createSimple("ImageButton",{
  5099. Parent = newFrame,
  5100. Name = "Up",
  5101. Size = UDim2.new(0,16,0,16),
  5102. BackgroundTransparency = 1,
  5103. BorderSizePixel = 0,
  5104. AutoButtonColor = false
  5105. })
  5106. createArrow(16,4,"up").Parent = button1
  5107. button2 = createSimple("ImageButton",{
  5108. Parent = newFrame,
  5109. Name = "Down",
  5110. Position = UDim2.new(0,0,1,-16),
  5111. Size = UDim2.new(0,16,0,16),
  5112. BackgroundTransparency = 1,
  5113. BorderSizePixel = 0,
  5114. AutoButtonColor = false
  5115. })
  5116. createArrow(16,4,"down").Parent = button2
  5117. end
  5118.  
  5119. local scrollThumbFrame = createSimple("Frame",{
  5120. BackgroundTransparency = 1,
  5121. Parent = newFrame
  5122. })
  5123. if self.Horizontal then
  5124. scrollThumbFrame.Position = UDim2.new(0,16,0,0)
  5125. scrollThumbFrame.Size = UDim2.new(1,-32,1,0)
  5126. else
  5127. scrollThumbFrame.Position = UDim2.new(0,0,0,16)
  5128. scrollThumbFrame.Size = UDim2.new(1,0,1,-32)
  5129. end
  5130.  
  5131. local scrollThumb = createSimple("Frame",{
  5132. BackgroundColor3 = Color3.new(120/255,120/255,120/255),
  5133. BorderSizePixel = 0,
  5134. Parent = scrollThumbFrame
  5135. })
  5136.  
  5137. local markerFrame = createSimple("Frame",{
  5138. BackgroundTransparency = 1,
  5139. Name = "Markers",
  5140. Size = UDim2.new(1,0,1,0),
  5141. Parent = scrollThumbFrame
  5142. })
  5143.  
  5144. local buttonPress = false
  5145. local thumbPress = false
  5146. local thumbFramePress = false
  5147.  
  5148. --local thumbColor = Color3.new(120/255,120/255,120/255)
  5149. --local thumbSelectColor = Color3.new(140/255,140/255,140/255)
  5150. button1.InputBegan:Connect(function(input)
  5151. if input.UserInputType == Enum.UserInputType.MouseMovement and not buttonPress and self:CanScrollUp() then button1.BackgroundTransparency = 0.8 end
  5152. if input.UserInputType ~= Enum.UserInputType.MouseButton1 or not self:CanScrollUp() then return end
  5153. buttonPress = true
  5154. button1.BackgroundTransparency = 0.5
  5155. if self:CanScrollUp() then self:ScrollUp() self.Scrolled:Fire() end
  5156. local buttonTick = tick()
  5157. local releaseEvent
  5158. releaseEvent = user.InputEnded:Connect(function(input)
  5159. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  5160. releaseEvent:Disconnect()
  5161. if checkMouseInGui(button1) and self:CanScrollUp() then button1.BackgroundTransparency = 0.8 else button1.BackgroundTransparency = 1 end
  5162. buttonPress = false
  5163. end)
  5164. while buttonPress do
  5165. if tick() - buttonTick >= 0.3 and self:CanScrollUp() then
  5166. self:ScrollUp()
  5167. self.Scrolled:Fire()
  5168. end
  5169. wait()
  5170. end
  5171. end)
  5172. button1.InputEnded:Connect(function(input)
  5173. if input.UserInputType == Enum.UserInputType.MouseMovement and not buttonPress then button1.BackgroundTransparency = 1 end
  5174. end)
  5175. button2.InputBegan:Connect(function(input)
  5176. if input.UserInputType == Enum.UserInputType.MouseMovement and not buttonPress and self:CanScrollDown() then button2.BackgroundTransparency = 0.8 end
  5177. if input.UserInputType ~= Enum.UserInputType.MouseButton1 or not self:CanScrollDown() then return end
  5178. buttonPress = true
  5179. button2.BackgroundTransparency = 0.5
  5180. if self:CanScrollDown() then self:ScrollDown() self.Scrolled:Fire() end
  5181. local buttonTick = tick()
  5182. local releaseEvent
  5183. releaseEvent = user.InputEnded:Connect(function(input)
  5184. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  5185. releaseEvent:Disconnect()
  5186. if checkMouseInGui(button2) and self:CanScrollDown() then button2.BackgroundTransparency = 0.8 else button2.BackgroundTransparency = 1 end
  5187. buttonPress = false
  5188. end)
  5189. while buttonPress do
  5190. if tick() - buttonTick >= 0.3 and self:CanScrollDown() then
  5191. self:ScrollDown()
  5192. self.Scrolled:Fire()
  5193. end
  5194. wait()
  5195. end
  5196. end)
  5197. button2.InputEnded:Connect(function(input)
  5198. if input.UserInputType == Enum.UserInputType.MouseMovement and not buttonPress then button2.BackgroundTransparency = 1 end
  5199. end)
  5200.  
  5201. scrollThumb.InputBegan:Connect(function(input)
  5202. if input.UserInputType == Enum.UserInputType.MouseMovement and not thumbPress then scrollThumb.BackgroundTransparency = 0.2 scrollThumb.BackgroundColor3 = self.ThumbSelectColor end
  5203. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  5204.  
  5205. local dir = self.Horizontal and "X" or "Y"
  5206. local lastThumbPos = nil
  5207.  
  5208. buttonPress = false
  5209. thumbFramePress = false
  5210. thumbPress = true
  5211. scrollThumb.BackgroundTransparency = 0
  5212. local mouseOffset = mouse[dir] - scrollThumb.AbsolutePosition[dir]
  5213. local mouseStart = mouse[dir]
  5214. local releaseEvent
  5215. local mouseEvent
  5216. releaseEvent = user.InputEnded:Connect(function(input)
  5217. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  5218. releaseEvent:Disconnect()
  5219. if mouseEvent then mouseEvent:Disconnect() end
  5220. if checkMouseInGui(scrollThumb) then scrollThumb.BackgroundTransparency = 0.2 else scrollThumb.BackgroundTransparency = 0 scrollThumb.BackgroundColor3 = self.ThumbColor end
  5221. thumbPress = false
  5222. end)
  5223. self:Update()
  5224.  
  5225. mouseEvent = user.InputChanged:Connect(function(input)
  5226. if input.UserInputType == Enum.UserInputType.MouseMovement and thumbPress and releaseEvent.Connected then
  5227. local thumbFrameSize = scrollThumbFrame.AbsoluteSize[dir]-scrollThumb.AbsoluteSize[dir]
  5228. local pos = mouse[dir] - scrollThumbFrame.AbsolutePosition[dir] - mouseOffset
  5229. if pos > thumbFrameSize then
  5230. pos = thumbFrameSize
  5231. elseif pos < 0 then
  5232. pos = 0
  5233. end
  5234. if lastThumbPos ~= pos then
  5235. lastThumbPos = pos
  5236. self:ScrollTo(math.floor(0.5+pos/thumbFrameSize*(self.TotalSpace-self.VisibleSpace)))
  5237. end
  5238. wait()
  5239. end
  5240. end)
  5241. end)
  5242. scrollThumb.InputEnded:Connect(function(input)
  5243. if input.UserInputType == Enum.UserInputType.MouseMovement and not thumbPress then scrollThumb.BackgroundTransparency = 0 scrollThumb.BackgroundColor3 = self.ThumbColor end
  5244. end)
  5245. scrollThumbFrame.InputBegan:Connect(function(input)
  5246. if input.UserInputType ~= Enum.UserInputType.MouseButton1 or checkMouseInGui(scrollThumb) then return end
  5247.  
  5248. local dir = self.Horizontal and "X" or "Y"
  5249. local scrollDir = 0
  5250. if mouse[dir] >= scrollThumb.AbsolutePosition[dir] + scrollThumb.AbsoluteSize[dir] then
  5251. scrollDir = 1
  5252. end
  5253.  
  5254. local function doTick()
  5255. local scrollSize = self.VisibleSpace - 1
  5256. if scrollDir == 0 and mouse[dir] < scrollThumb.AbsolutePosition[dir] then
  5257. self:ScrollTo(self.Index - scrollSize)
  5258. elseif scrollDir == 1 and mouse[dir] >= scrollThumb.AbsolutePosition[dir] + scrollThumb.AbsoluteSize[dir] then
  5259. self:ScrollTo(self.Index + scrollSize)
  5260. end
  5261. end
  5262.  
  5263. thumbPress = false
  5264. thumbFramePress = true
  5265. doTick()
  5266. local thumbFrameTick = tick()
  5267. local releaseEvent
  5268. releaseEvent = user.InputEnded:Connect(function(input)
  5269. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  5270. releaseEvent:Disconnect()
  5271. thumbFramePress = false
  5272. end)
  5273. while thumbFramePress do
  5274. if tick() - thumbFrameTick >= 0.3 and checkMouseInGui(scrollThumbFrame) then
  5275. doTick()
  5276. end
  5277. wait()
  5278. end
  5279. end)
  5280.  
  5281. newFrame.MouseWheelForward:Connect(function()
  5282. self:ScrollTo(self.Index - self.WheelIncrement)
  5283. end)
  5284.  
  5285. newFrame.MouseWheelBackward:Connect(function()
  5286. self:ScrollTo(self.Index + self.WheelIncrement)
  5287. end)
  5288.  
  5289. self.GuiElems.ScrollThumb = scrollThumb
  5290. self.GuiElems.ScrollThumbFrame = scrollThumbFrame
  5291. self.GuiElems.Button1 = button1
  5292. self.GuiElems.Button2 = button2
  5293. self.GuiElems.MarkerFrame = markerFrame
  5294.  
  5295. return newFrame
  5296. end
  5297.  
  5298. funcs.Update = function(self,nocallback)
  5299. local total = self.TotalSpace
  5300. local visible = self.VisibleSpace
  5301. local index = self.Index
  5302. local button1 = self.GuiElems.Button1
  5303. local button2 = self.GuiElems.Button2
  5304.  
  5305. self.Index = math.clamp(self.Index,0,math.max(0,total-visible))
  5306.  
  5307. if self.LastTotalSpace ~= self.TotalSpace then
  5308. self.LastTotalSpace = self.TotalSpace
  5309. self:UpdateMarkers()
  5310. end
  5311.  
  5312. if self:CanScrollUp() then
  5313. for i,v in pairs(button1.Arrow:GetChildren()) do
  5314. v.BackgroundTransparency = 0
  5315. end
  5316. else
  5317. button1.BackgroundTransparency = 1
  5318. for i,v in pairs(button1.Arrow:GetChildren()) do
  5319. v.BackgroundTransparency = 0.5
  5320. end
  5321. end
  5322. if self:CanScrollDown() then
  5323. for i,v in pairs(button2.Arrow:GetChildren()) do
  5324. v.BackgroundTransparency = 0
  5325. end
  5326. else
  5327. button2.BackgroundTransparency = 1
  5328. for i,v in pairs(button2.Arrow:GetChildren()) do
  5329. v.BackgroundTransparency = 0.5
  5330. end
  5331. end
  5332.  
  5333. drawThumb(self)
  5334. end
  5335.  
  5336. funcs.UpdateMarkers = function(self)
  5337. local markerFrame = self.GuiElems.MarkerFrame
  5338. markerFrame:ClearAllChildren()
  5339.  
  5340. for i,v in pairs(self.Markers) do
  5341. if i < self.TotalSpace then
  5342. createSimple("Frame",{
  5343. BackgroundTransparency = 0,
  5344. BackgroundColor3 = v,
  5345. BorderSizePixel = 0,
  5346. Position = self.Horizontal and UDim2.new(i/self.TotalSpace,0,1,-6) or UDim2.new(1,-6,i/self.TotalSpace,0),
  5347. Size = self.Horizontal and UDim2.new(0,1,0,6) or UDim2.new(0,6,0,1),
  5348. Name = "Marker"..tostring(i),
  5349. Parent = markerFrame
  5350. })
  5351. end
  5352. end
  5353. end
  5354.  
  5355. funcs.AddMarker = function(self,ind,color)
  5356. self.Markers[ind] = color or Color3.new(0,0,0)
  5357. end
  5358. funcs.ScrollTo = function(self,ind,nocallback)
  5359. self.Index = ind
  5360. self:Update()
  5361. if not nocallback then
  5362. self.Scrolled:Fire()
  5363. end
  5364. end
  5365. funcs.ScrollUp = function(self)
  5366. self.Index = self.Index - self.Increment
  5367. self:Update()
  5368. end
  5369. funcs.ScrollDown = function(self)
  5370. self.Index = self.Index + self.Increment
  5371. self:Update()
  5372. end
  5373. funcs.CanScrollUp = function(self)
  5374. return self.Index > 0
  5375. end
  5376. funcs.CanScrollDown = function(self)
  5377. return self.Index + self.VisibleSpace < self.TotalSpace
  5378. end
  5379. funcs.GetScrollPercent = function(self)
  5380. return self.Index/(self.TotalSpace-self.VisibleSpace)
  5381. end
  5382. funcs.SetScrollPercent = function(self,perc)
  5383. self.Index = math.floor(perc*(self.TotalSpace-self.VisibleSpace))
  5384. self:Update()
  5385. end
  5386.  
  5387. funcs.Texture = function(self,data)
  5388. self.ThumbColor = data.ThumbColor or Color3.new(0,0,0)
  5389. self.ThumbSelectColor = data.ThumbSelectColor or Color3.new(0,0,0)
  5390. self.GuiElems.ScrollThumb.BackgroundColor3 = data.ThumbColor or Color3.new(0,0,0)
  5391. self.Gui.BackgroundColor3 = data.FrameColor or Color3.new(0,0,0)
  5392. self.GuiElems.Button1.BackgroundColor3 = data.ButtonColor or Color3.new(0,0,0)
  5393. self.GuiElems.Button2.BackgroundColor3 = data.ButtonColor or Color3.new(0,0,0)
  5394. for i,v in pairs(self.GuiElems.Button1.Arrow:GetChildren()) do
  5395. v.BackgroundColor3 = data.ArrowColor or Color3.new(0,0,0)
  5396. end
  5397. for i,v in pairs(self.GuiElems.Button2.Arrow:GetChildren()) do
  5398. v.BackgroundColor3 = data.ArrowColor or Color3.new(0,0,0)
  5399. end
  5400. end
  5401.  
  5402. funcs.SetScrollFrame = function(self,frame)
  5403. if self.ScrollUpEvent then self.ScrollUpEvent:Disconnect() self.ScrollUpEvent = nil end
  5404. if self.ScrollDownEvent then self.ScrollDownEvent:Disconnect() self.ScrollDownEvent = nil end
  5405. self.ScrollUpEvent = frame.MouseWheelForward:Connect(function() self:ScrollTo(self.Index - self.WheelIncrement) end)
  5406. self.ScrollDownEvent = frame.MouseWheelBackward:Connect(function() self:ScrollTo(self.Index + self.WheelIncrement) end)
  5407. end
  5408.  
  5409. local mt = {}
  5410. mt.__index = funcs
  5411.  
  5412. local function new(hor)
  5413. local obj = setmetatable({
  5414. Index = 0,
  5415. VisibleSpace = 0,
  5416. TotalSpace = 0,
  5417. Increment = 1,
  5418. WheelIncrement = 1,
  5419. Markers = {},
  5420. GuiElems = {},
  5421. Horizontal = hor,
  5422. LastTotalSpace = 0,
  5423. Scrolled = Lib.Signal.new()
  5424. },mt)
  5425. obj.Gui = createFrame(obj)
  5426. obj:Texture({
  5427. ThumbColor = Color3.fromRGB(60,60,60),
  5428. ThumbSelectColor = Color3.fromRGB(75,75,75),
  5429. ArrowColor = Color3.new(1,1,1),
  5430. FrameColor = Color3.fromRGB(40,40,40),
  5431. ButtonColor = Color3.fromRGB(75,75,75)
  5432. })
  5433. return obj
  5434. end
  5435.  
  5436. return {new = new}
  5437. end)()
  5438.  
  5439. Lib.Window = (function()
  5440. local funcs = {}
  5441. local static = {MinWidth = 200, FreeWidth = 200}
  5442. local mouse = plr:GetMouse()
  5443. local sidesGui,alignIndicator
  5444. local visibleWindows = {}
  5445. local leftSide = {Width = 300, Windows = {}, ResizeCons = {}, Hidden = true}
  5446. local rightSide = {Width = 300, Windows = {}, ResizeCons = {}, Hidden = true}
  5447.  
  5448. local displayOrderStart
  5449. local sideDisplayOrder
  5450. local sideTweenInfo = TweenInfo.new(0.3,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  5451. local tweens = {}
  5452. local isA = game.IsA
  5453.  
  5454. local theme = {
  5455. MainColor1 = Color3.fromRGB(52,52,52),
  5456. MainColor2 = Color3.fromRGB(45,45,45),
  5457. Button = Color3.fromRGB(60,60,60)
  5458. }
  5459.  
  5460. local function stopTweens()
  5461. for i = 1,#tweens do
  5462. tweens[i]:Cancel()
  5463. end
  5464. tweens = {}
  5465. end
  5466.  
  5467. local function resizeHook(self,resizer,dir)
  5468. local guiMain = self.GuiElems.Main
  5469. resizer.InputBegan:Connect(function(input)
  5470. if not self.Dragging and not self.Resizing and self.Resizable and self.ResizableInternal then
  5471. local isH = dir:find("[WE]") and true
  5472. local isV = dir:find("[NS]") and true
  5473. local signX = dir:find("W",1,true) and -1 or 1
  5474. local signY = dir:find("N",1,true) and -1 or 1
  5475.  
  5476. if self.Minimized and isV then return end
  5477.  
  5478. if input.UserInputType == Enum.UserInputType.MouseMovement then
  5479. resizer.BackgroundTransparency = 0.5
  5480. elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  5481. local releaseEvent,mouseEvent
  5482.  
  5483. local offX = mouse.X - resizer.AbsolutePosition.X
  5484. local offY = mouse.Y - resizer.AbsolutePosition.Y
  5485.  
  5486. self.Resizing = resizer
  5487. resizer.BackgroundTransparency = 1
  5488.  
  5489. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  5490. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  5491. releaseEvent:Disconnect()
  5492. mouseEvent:Disconnect()
  5493. self.Resizing = false
  5494. resizer.BackgroundTransparency = 1
  5495. end
  5496. end)
  5497.  
  5498. mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  5499. if self.Resizable and self.ResizableInternal and input.UserInputType == Enum.UserInputType.MouseMovement then
  5500. self:StopTweens()
  5501. local deltaX = input.Position.X - resizer.AbsolutePosition.X - offX
  5502. local deltaY = input.Position.Y - resizer.AbsolutePosition.Y - offY
  5503.  
  5504. if guiMain.AbsoluteSize.X + deltaX*signX < self.MinX then deltaX = signX*(self.MinX - guiMain.AbsoluteSize.X) end
  5505. if guiMain.AbsoluteSize.Y + deltaY*signY < self.MinY then deltaY = signY*(self.MinY - guiMain.AbsoluteSize.Y) end
  5506. if signY < 0 and guiMain.AbsolutePosition.Y + deltaY < 0 then deltaY = -guiMain.AbsolutePosition.Y end
  5507.  
  5508. guiMain.Position = guiMain.Position + UDim2.new(0,(signX < 0 and deltaX or 0),0,(signY < 0 and deltaY or 0))
  5509. self.SizeX = self.SizeX + (isH and deltaX*signX or 0)
  5510. self.SizeY = self.SizeY + (isV and deltaY*signY or 0)
  5511. guiMain.Size = UDim2.new(0,self.SizeX,0,self.Minimized and 20 or self.SizeY)
  5512.  
  5513. --if isH then self.SizeX = guiMain.AbsoluteSize.X end
  5514. --if isV then self.SizeY = guiMain.AbsoluteSize.Y end
  5515. end
  5516. end)
  5517. end
  5518. end
  5519. end)
  5520.  
  5521. resizer.InputEnded:Connect(function(input)
  5522. if input.UserInputType == Enum.UserInputType.MouseMovement and self.Resizing ~= resizer then
  5523. resizer.BackgroundTransparency = 1
  5524. end
  5525. end)
  5526. end
  5527.  
  5528. local updateWindows
  5529.  
  5530. local function moveToTop(window)
  5531. local found = table.find(visibleWindows,window)
  5532. if found then
  5533. table.remove(visibleWindows,found)
  5534. table.insert(visibleWindows,1,window)
  5535. updateWindows()
  5536. end
  5537. end
  5538.  
  5539. local function sideHasRoom(side,neededSize)
  5540. local maxY = sidesGui.AbsoluteSize.Y - (math.max(0,#side.Windows - 1) * 4)
  5541. local inc = 0
  5542. for i,v in pairs(side.Windows) do
  5543. inc = inc + (v.MinY or 100)
  5544. if inc > maxY - neededSize then return false end
  5545. end
  5546.  
  5547. return true
  5548. end
  5549.  
  5550. local function getSideInsertPos(side,curY)
  5551. local pos = #side.Windows + 1
  5552. local range = {0,sidesGui.AbsoluteSize.Y}
  5553.  
  5554. for i,v in pairs(side.Windows) do
  5555. local midPos = v.PosY + v.SizeY/2
  5556. if curY <= midPos then
  5557. pos = i
  5558. range[2] = midPos
  5559. break
  5560. else
  5561. range[1] = midPos
  5562. end
  5563. end
  5564.  
  5565. return pos,range
  5566. end
  5567.  
  5568. local function focusInput(self,obj)
  5569. if isA(obj,"GuiButton") then
  5570. obj.MouseButton1Down:Connect(function()
  5571. moveToTop(self)
  5572. end)
  5573. elseif isA(obj,"TextBox") then
  5574. obj.Focused:Connect(function()
  5575. moveToTop(self)
  5576. end)
  5577. end
  5578. end
  5579.  
  5580. local createGui = function(self)
  5581. local gui = create({
  5582. {1,"ScreenGui",{Name="Window",}},
  5583. {2,"Frame",{Active=true,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="Main",Parent={1},Position=UDim2.new(0.40000000596046,0,0.40000000596046,0),Size=UDim2.new(0,300,0,300),}},
  5584. {3,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,Name="Content",Parent={2},Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,1,-20),ClipsDescendants=true}},
  5585. {4,"Frame",{BackgroundColor3=Color3.fromRGB(33,33,33),BorderSizePixel=0,Name="Line",Parent={3},Size=UDim2.new(1,0,0,1),}},
  5586. {5,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="TopBar",Parent={2},Size=UDim2.new(1,0,0,20),}},
  5587. {6,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={5},Position=UDim2.new(0,5,0,0),Size=UDim2.new(1,-10,0,20),Text="Window",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,}},
  5588. {7,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Close",Parent={5},Position=UDim2.new(1,-18,0,2),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  5589. {8,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5054663650",Parent={7},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,10,0,10),}},
  5590. {9,"UICorner",{CornerRadius=UDim.new(0,4),Parent={7},}},
  5591. {10,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Minimize",Parent={5},Position=UDim2.new(1,-36,0,2),Size=UDim2.new(0,16,0,16),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  5592. {11,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://5034768003",Parent={10},Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,10,0,10),}},
  5593. {12,"UICorner",{CornerRadius=UDim.new(0,4),Parent={10},}},
  5594. {13,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Image="rbxassetid://1427967925",Name="Outlines",Parent={2},Position=UDim2.new(0,-5,0,-5),ScaleType=1,Size=UDim2.new(1,10,1,10),SliceCenter=Rect.new(6,6,25,25),TileSize=UDim2.new(0,20,0,20),}},
  5595. {14,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="ResizeControls",Parent={2},Position=UDim2.new(0,-5,0,-5),Size=UDim2.new(1,10,1,10),}},
  5596. {15,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="North",Parent={14},Position=UDim2.new(0,5,0,0),Size=UDim2.new(1,-10,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  5597. {16,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="South",Parent={14},Position=UDim2.new(0,5,1,-5),Size=UDim2.new(1,-10,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  5598. {17,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="NorthEast",Parent={14},Position=UDim2.new(1,-5,0,0),Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  5599. {18,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="East",Parent={14},Position=UDim2.new(1,-5,0,5),Size=UDim2.new(0,5,1,-10),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  5600. {19,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="West",Parent={14},Position=UDim2.new(0,0,0,5),Size=UDim2.new(0,5,1,-10),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  5601. {20,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="SouthEast",Parent={14},Position=UDim2.new(1,-5,1,-5),Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  5602. {21,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="NorthWest",Parent={14},Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  5603. {22,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.27450981736183,0.27450981736183,0.27450981736183),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="SouthWest",Parent={14},Position=UDim2.new(0,0,1,-5),Size=UDim2.new(0,5,0,5),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  5604. })
  5605.  
  5606. local guiMain = gui.Main
  5607. local guiTopBar = guiMain.TopBar
  5608. local guiResizeControls = guiMain.ResizeControls
  5609.  
  5610. self.GuiElems.Main = guiMain
  5611. self.GuiElems.TopBar = guiMain.TopBar
  5612. self.GuiElems.Content = guiMain.Content
  5613. self.GuiElems.Line = guiMain.Content.Line
  5614. self.GuiElems.Outlines = guiMain.Outlines
  5615. self.GuiElems.Title = guiTopBar.Title
  5616. self.GuiElems.Close = guiTopBar.Close
  5617. self.GuiElems.Minimize = guiTopBar.Minimize
  5618. self.GuiElems.ResizeControls = guiResizeControls
  5619. self.ContentPane = guiMain.Content
  5620.  
  5621. guiTopBar.InputBegan:Connect(function(input)
  5622. if input.UserInputType == Enum.UserInputType.MouseButton1 and self.Draggable then
  5623. local releaseEvent,mouseEvent
  5624.  
  5625. local maxX = sidesGui.AbsoluteSize.X
  5626. local initX = guiMain.AbsolutePosition.X
  5627. local initY = guiMain.AbsolutePosition.Y
  5628. local offX = mouse.X - initX
  5629. local offY = mouse.Y - initY
  5630.  
  5631. local alignInsertPos,alignInsertSide
  5632.  
  5633. guiDragging = true
  5634.  
  5635. releaseEvent = clonerefs(game:GetService("UserInputService")).InputEnded:Connect(function(input)
  5636. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  5637. releaseEvent:Disconnect()
  5638. mouseEvent:Disconnect()
  5639. guiDragging = false
  5640. alignIndicator.Parent = nil
  5641. if alignInsertSide then
  5642. local targetSide = (alignInsertSide == "left" and leftSide) or (alignInsertSide == "right" and rightSide)
  5643. self:AlignTo(targetSide,alignInsertPos)
  5644. end
  5645. end
  5646. end)
  5647.  
  5648. mouseEvent = clonerefs(game:GetService("UserInputService")).InputChanged:Connect(function(input)
  5649. if input.UserInputType == Enum.UserInputType.MouseMovement and self.Draggable and not self.Closed then
  5650. if self.Aligned then
  5651. if leftSide.Resizing or rightSide.Resizing then return end
  5652. local posX,posY = input.Position.X-offX,input.Position.Y-offY
  5653. local delta = math.sqrt((posX-initX)^2 + (posY-initY)^2)
  5654. if delta >= 5 then
  5655. self:SetAligned(false)
  5656. end
  5657. else
  5658. local inputX,inputY = input.Position.X,input.Position.Y
  5659. local posX,posY = inputX-offX,inputY-offY
  5660. if posY < 0 then posY = 0 end
  5661. guiMain.Position = UDim2.new(0,posX,0,posY)
  5662.  
  5663. if self.Resizable and self.Alignable then
  5664. if inputX < 25 then
  5665. if sideHasRoom(leftSide,self.MinY or 100) then
  5666. local insertPos,range = getSideInsertPos(leftSide,inputY)
  5667. alignIndicator.Indicator.Position = UDim2.new(0,-15,0,range[1])
  5668. alignIndicator.Indicator.Size = UDim2.new(0,40,0,range[2]-range[1])
  5669. Lib.ShowGui(alignIndicator)
  5670. alignInsertPos = insertPos
  5671. alignInsertSide = "left"
  5672. return
  5673. end
  5674. elseif inputX >= maxX - 25 then
  5675. if sideHasRoom(rightSide,self.MinY or 100) then
  5676. local insertPos,range = getSideInsertPos(rightSide,inputY)
  5677. alignIndicator.Indicator.Position = UDim2.new(0,maxX-25,0,range[1])
  5678. alignIndicator.Indicator.Size = UDim2.new(0,40,0,range[2]-range[1])
  5679. Lib.ShowGui(alignIndicator)
  5680. alignInsertPos = insertPos
  5681. alignInsertSide = "right"
  5682. return
  5683. end
  5684. end
  5685. end
  5686. alignIndicator.Parent = nil
  5687. alignInsertPos = nil
  5688. alignInsertSide = nil
  5689. end
  5690. end
  5691. end)
  5692. end
  5693. end)
  5694.  
  5695. guiTopBar.Close.MouseButton1Click:Connect(function()
  5696. if self.Closed then return end
  5697. self:Close()
  5698. end)
  5699.  
  5700. guiTopBar.Minimize.MouseButton1Click:Connect(function()
  5701. if self.Closed then return end
  5702. if self.Aligned then
  5703. self:SetAligned(false)
  5704. else
  5705. self:SetMinimized()
  5706. end
  5707. end)
  5708.  
  5709. guiTopBar.Minimize.MouseButton2Click:Connect(function()
  5710. if self.Closed then return end
  5711. if not self.Aligned then
  5712. self:SetMinimized(nil,2)
  5713. guiTopBar.Minimize.BackgroundTransparency = 1
  5714. end
  5715. end)
  5716.  
  5717. guiMain.InputBegan:Connect(function(input)
  5718. if input.UserInputType == Enum.UserInputType.MouseButton1 and not self.Aligned and not self.Closed then
  5719. moveToTop(self)
  5720. end
  5721. end)
  5722.  
  5723. guiMain:GetPropertyChangedSignal("AbsolutePosition"):Connect(function()
  5724. local absPos = guiMain.AbsolutePosition
  5725. self.PosX = absPos.X
  5726. self.PosY = absPos.Y
  5727. end)
  5728.  
  5729. resizeHook(self,guiResizeControls.North,"N")
  5730. resizeHook(self,guiResizeControls.NorthEast,"NE")
  5731. resizeHook(self,guiResizeControls.East,"E")
  5732. resizeHook(self,guiResizeControls.SouthEast,"SE")
  5733. resizeHook(self,guiResizeControls.South,"S")
  5734. resizeHook(self,guiResizeControls.SouthWest,"SW")
  5735. resizeHook(self,guiResizeControls.West,"W")
  5736. resizeHook(self,guiResizeControls.NorthWest,"NW")
  5737.  
  5738. guiMain.Size = UDim2.new(0,self.SizeX,0,self.SizeY)
  5739.  
  5740. gui.DescendantAdded:Connect(function(obj) focusInput(self,obj) end)
  5741. local descs = gui:GetDescendants()
  5742. for i = 1,#descs do
  5743. focusInput(self,descs[i])
  5744. end
  5745.  
  5746. self.MinimizeAnim = Lib.ButtonAnim(guiTopBar.Minimize)
  5747. self.CloseAnim = Lib.ButtonAnim(guiTopBar.Close)
  5748.  
  5749. return gui
  5750. end
  5751.  
  5752. local function updateSideFrames(noTween)
  5753. stopTweens()
  5754. leftSide.Frame.Size = UDim2.new(0,leftSide.Width,1,0)
  5755. rightSide.Frame.Size = UDim2.new(0,rightSide.Width,1,0)
  5756. leftSide.Frame.Resizer.Position = UDim2.new(0,leftSide.Width,0,0)
  5757. rightSide.Frame.Resizer.Position = UDim2.new(0,-5,0,0)
  5758.  
  5759. --leftSide.Frame.Visible = (#leftSide.Windows > 0)
  5760. --rightSide.Frame.Visible = (#rightSide.Windows > 0)
  5761.  
  5762. --[[if #leftSide.Windows > 0 and leftSide.Frame.Position == UDim2.new(0,-leftSide.Width-5,0,0) then
  5763. leftSide.Frame:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  5764. elseif #leftSide.Windows == 0 and leftSide.Frame.Position == UDim2.new(0,0,0,0) then
  5765. leftSide.Frame:TweenPosition(UDim2.new(0,-leftSide.Width-5,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  5766. end
  5767. local rightTweenPos = (#rightSide.Windows == 0 and UDim2.new(1,5,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  5768. rightSide.Frame:TweenPosition(rightTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)]]
  5769. local leftHidden = #leftSide.Windows == 0 or leftSide.Hidden
  5770. local rightHidden = #rightSide.Windows == 0 or rightSide.Hidden
  5771. local leftPos = (leftHidden and UDim2.new(0,-leftSide.Width-10,0,0) or UDim2.new(0,0,0,0))
  5772. local rightPos = (rightHidden and UDim2.new(1,10,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  5773.  
  5774. sidesGui.LeftToggle.Text = leftHidden and ">" or "<"
  5775. sidesGui.RightToggle.Text = rightHidden and "<" or ">"
  5776.  
  5777. if not noTween then
  5778. local function insertTween(...)
  5779. local tween = service.TweenService:Create(...)
  5780. tweens[#tweens+1] = tween
  5781. tween:Play()
  5782. end
  5783. insertTween(leftSide.Frame,sideTweenInfo,{Position = leftPos})
  5784. insertTween(rightSide.Frame,sideTweenInfo,{Position = rightPos})
  5785. insertTween(sidesGui.LeftToggle,sideTweenInfo,{Position = UDim2.new(0,#leftSide.Windows == 0 and -16 or 0,0,-36)})
  5786. insertTween(sidesGui.RightToggle,sideTweenInfo,{Position = UDim2.new(1,#rightSide.Windows == 0 and 0 or -16,0,-36)})
  5787. else
  5788. leftSide.Frame.Position = leftPos
  5789. rightSide.Frame.Position = rightPos
  5790. sidesGui.LeftToggle.Position = UDim2.new(0,#leftSide.Windows == 0 and -16 or 0,0,-36)
  5791. sidesGui.RightToggle.Position = UDim2.new(1,#rightSide.Windows == 0 and 0 or -16,0,-36)
  5792. end
  5793. end
  5794.  
  5795. local function getSideFramePos(side)
  5796. local leftHidden = #leftSide.Windows == 0 or leftSide.Hidden
  5797. local rightHidden = #rightSide.Windows == 0 or rightSide.Hidden
  5798. if side == leftSide then
  5799. return (leftHidden and UDim2.new(0,-leftSide.Width-10,0,0) or UDim2.new(0,0,0,0))
  5800. else
  5801. return (rightHidden and UDim2.new(1,10,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  5802. end
  5803. end
  5804.  
  5805. local function sideResized(side)
  5806. local currentPos = 0
  5807. local sideFramePos = getSideFramePos(side)
  5808. for i,v in pairs(side.Windows) do
  5809. v.SizeX = side.Width
  5810. v.GuiElems.Main.Size = UDim2.new(0,side.Width,0,v.SizeY)
  5811. v.GuiElems.Main.Position = UDim2.new(sideFramePos.X.Scale,sideFramePos.X.Offset,0,currentPos)
  5812. currentPos = currentPos + v.SizeY+4
  5813. end
  5814. end
  5815.  
  5816. local function sideResizerHook(resizer,dir,side,pos)
  5817. local mouse = Main.Mouse
  5818. local windows = side.Windows
  5819.  
  5820. resizer.InputBegan:Connect(function(input)
  5821. if not side.Resizing then
  5822. if input.UserInputType == Enum.UserInputType.MouseMovement then
  5823. resizer.BackgroundColor3 = theme.MainColor2
  5824. elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  5825. local releaseEvent,mouseEvent
  5826.  
  5827. local offX = mouse.X - resizer.AbsolutePosition.X
  5828. local offY = mouse.Y - resizer.AbsolutePosition.Y
  5829.  
  5830. side.Resizing = resizer
  5831. resizer.BackgroundColor3 = theme.MainColor2
  5832.  
  5833. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  5834. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  5835. releaseEvent:Disconnect()
  5836. mouseEvent:Disconnect()
  5837. side.Resizing = false
  5838. resizer.BackgroundColor3 = theme.Button
  5839. end
  5840. end)
  5841.  
  5842. mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  5843. if not resizer.Parent then
  5844. releaseEvent:Disconnect()
  5845. mouseEvent:Disconnect()
  5846. side.Resizing = false
  5847. return
  5848. end
  5849. if input.UserInputType == Enum.UserInputType.MouseMovement then
  5850. if dir == "V" then
  5851. local delta = input.Position.Y - resizer.AbsolutePosition.Y - offY
  5852.  
  5853. if delta > 0 then
  5854. local neededSize = delta
  5855. for i = pos+1,#windows do
  5856. local window = windows[i]
  5857. local newSize = math.max(window.SizeY-neededSize,(window.MinY or 100))
  5858. neededSize = neededSize - (window.SizeY - newSize)
  5859. window.SizeY = newSize
  5860. end
  5861. windows[pos].SizeY = windows[pos].SizeY + math.max(0,delta-neededSize)
  5862. else
  5863. local neededSize = -delta
  5864. for i = pos,1,-1 do
  5865. local window = windows[i]
  5866. local newSize = math.max(window.SizeY-neededSize,(window.MinY or 100))
  5867. neededSize = neededSize - (window.SizeY - newSize)
  5868. window.SizeY = newSize
  5869. end
  5870. windows[pos+1].SizeY = windows[pos+1].SizeY + math.max(0,-delta-neededSize)
  5871. end
  5872.  
  5873. updateSideFrames()
  5874. sideResized(side)
  5875. elseif dir == "H" then
  5876. local maxWidth = math.max(300,sidesGui.AbsoluteSize.X-static.FreeWidth)
  5877. local otherSide = (side == leftSide and rightSide or leftSide)
  5878. local delta = input.Position.X - resizer.AbsolutePosition.X - offX
  5879. delta = (side == leftSide and delta or -delta)
  5880.  
  5881. local proposedSize = math.max(static.MinWidth,side.Width + delta)
  5882. if proposedSize + otherSide.Width <= maxWidth then
  5883. side.Width = proposedSize
  5884. else
  5885. local newOtherSize = maxWidth - proposedSize
  5886. if newOtherSize >= static.MinWidth then
  5887. side.Width = proposedSize
  5888. otherSide.Width = newOtherSize
  5889. else
  5890. side.Width = maxWidth - static.MinWidth
  5891. otherSide.Width = static.MinWidth
  5892. end
  5893. end
  5894.  
  5895. updateSideFrames(true)
  5896. sideResized(side)
  5897. sideResized(otherSide)
  5898. end
  5899. end
  5900. end)
  5901. end
  5902. end
  5903. end)
  5904.  
  5905. resizer.InputEnded:Connect(function(input)
  5906. if input.UserInputType == Enum.UserInputType.MouseMovement and side.Resizing ~= resizer then
  5907. resizer.BackgroundColor3 = theme.Button
  5908. end
  5909. end)
  5910. end
  5911.  
  5912. local function renderSide(side,noTween) -- TODO: Use existing resizers
  5913. local currentPos = 0
  5914. local sideFramePos = getSideFramePos(side)
  5915. local template = side.WindowResizer:Clone()
  5916. for i,v in pairs(side.ResizeCons) do v:Disconnect() end
  5917. for i,v in pairs(side.Frame:GetChildren()) do if v.Name == "WindowResizer" then v:Destroy() end end
  5918. side.ResizeCons = {}
  5919. side.Resizing = nil
  5920.  
  5921. for i,v in pairs(side.Windows) do
  5922. v.SidePos = i
  5923. local isEnd = i == #side.Windows
  5924. local size = UDim2.new(0,side.Width,0,v.SizeY)
  5925. local pos = UDim2.new(sideFramePos.X.Scale,sideFramePos.X.Offset,0,currentPos)
  5926. Lib.ShowGui(v.Gui)
  5927. --v.GuiElems.Main:TweenSizeAndPosition(size,pos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  5928. if noTween then
  5929. v.GuiElems.Main.Size = size
  5930. v.GuiElems.Main.Position = pos
  5931. else
  5932. local tween = service.TweenService:Create(v.GuiElems.Main,sideTweenInfo,{Size = size, Position = pos})
  5933. tweens[#tweens+1] = tween
  5934. tween:Play()
  5935. end
  5936. currentPos = currentPos + v.SizeY+4
  5937.  
  5938. if not isEnd then
  5939. local newTemplate = template:Clone()
  5940. newTemplate.Position = UDim2.new(1,-side.Width,0,currentPos-4)
  5941. side.ResizeCons[#side.ResizeCons+1] = v.Gui.Main:GetPropertyChangedSignal("Size"):Connect(function()
  5942. newTemplate.Position = UDim2.new(1,-side.Width,0, v.GuiElems.Main.Position.Y.Offset + v.GuiElems.Main.Size.Y.Offset)
  5943. end)
  5944. side.ResizeCons[#side.ResizeCons+1] = v.Gui.Main:GetPropertyChangedSignal("Position"):Connect(function()
  5945. newTemplate.Position = UDim2.new(1,-side.Width,0, v.GuiElems.Main.Position.Y.Offset + v.GuiElems.Main.Size.Y.Offset)
  5946. end)
  5947. sideResizerHook(newTemplate,"V",side,i)
  5948. newTemplate.Parent = side.Frame
  5949. end
  5950. end
  5951.  
  5952. --side.Frame.Back.Position = UDim2.new(0,0,0,0)
  5953. --side.Frame.Back.Size = UDim2.new(0,side.Width,1,0)
  5954. end
  5955.  
  5956. local function updateSide(side,noTween)
  5957. local oldHeight = 0
  5958. local currentPos = 0
  5959. local neededSize = 0
  5960. local windows = side.Windows
  5961. local height = sidesGui.AbsoluteSize.Y - (math.max(0,#windows - 1) * 4)
  5962.  
  5963. for i,v in pairs(windows) do oldHeight = oldHeight + v.SizeY end
  5964. for i,v in pairs(windows) do
  5965. if i == #windows then
  5966. v.SizeY = height-currentPos
  5967. neededSize = math.max(0,(v.MinY or 100)-v.SizeY)
  5968. else
  5969. v.SizeY = math.max(math.floor(v.SizeY/oldHeight*height),v.MinY or 100)
  5970. end
  5971. currentPos = currentPos + v.SizeY
  5972. end
  5973.  
  5974. if neededSize > 0 then
  5975. for i = #windows-1,1,-1 do
  5976. local window = windows[i]
  5977. local newSize = math.max(window.SizeY-neededSize,(window.MinY or 100))
  5978. neededSize = neededSize - (window.SizeY - newSize)
  5979. window.SizeY = newSize
  5980. end
  5981. local lastWindow = windows[#windows]
  5982. lastWindow.SizeY = (lastWindow.MinY or 100)-neededSize
  5983. end
  5984. renderSide(side,noTween)
  5985. end
  5986.  
  5987. updateWindows = function(noTween)
  5988. updateSideFrames(noTween)
  5989. updateSide(leftSide,noTween)
  5990. updateSide(rightSide,noTween)
  5991. local count = 0
  5992. for i = #visibleWindows,1,-1 do
  5993. visibleWindows[i].Gui.DisplayOrder = displayOrderStart + count
  5994. Lib.ShowGui(visibleWindows[i].Gui)
  5995. count = count + 1
  5996. end
  5997.  
  5998. --[[local leftTweenPos = (#leftSide.Windows == 0 and UDim2.new(0,-leftSide.Width-5,0,0) or UDim2.new(0,0,0,0))
  5999. leftSide.Frame:TweenPosition(leftTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)
  6000. local rightTweenPos = (#rightSide.Windows == 0 and UDim2.new(1,5,0,0) or UDim2.new(1,-rightSide.Width,0,0))
  6001. rightSide.Frame:TweenPosition(rightTweenPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.3,true)]]
  6002. end
  6003.  
  6004. funcs.SetMinimized = function(self,set,mode)
  6005. local oldVal = self.Minimized
  6006. local newVal
  6007. if set == nil then newVal = not self.Minimized else newVal = set end
  6008. self.Minimized = newVal
  6009. if not mode then mode = 1 end
  6010.  
  6011. local resizeControls = self.GuiElems.ResizeControls
  6012. local minimizeControls = {"North","NorthEast","NorthWest","South","SouthEast","SouthWest"}
  6013. for i = 1,#minimizeControls do
  6014. local control = resizeControls:FindFirstChild(minimizeControls[i])
  6015. if control then control.Visible = not newVal end
  6016. end
  6017.  
  6018. if mode == 1 or mode == 2 then
  6019. self:StopTweens()
  6020. if mode == 1 then
  6021. self.GuiElems.Main:TweenSize(UDim2.new(0,self.SizeX,0,newVal and 20 or self.SizeY),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true)
  6022. else
  6023. local maxY = sidesGui.AbsoluteSize.Y
  6024. local newPos = UDim2.new(0,self.PosX,0,newVal and math.min(maxY-20,self.PosY + self.SizeY - 20) or math.max(0,self.PosY - self.SizeY + 20))
  6025.  
  6026. self.GuiElems.Main:TweenPosition(newPos,Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true)
  6027. self.GuiElems.Main:TweenSize(UDim2.new(0,self.SizeX,0,newVal and 20 or self.SizeY),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.25,true)
  6028. end
  6029. self.GuiElems.Minimize.ImageLabel.Image = newVal and "rbxassetid://5060023708" or "rbxassetid://5034768003"
  6030. end
  6031.  
  6032. if oldVal ~= newVal then
  6033. if newVal then
  6034. self.OnMinimize:Fire()
  6035. else
  6036. self.OnRestore:Fire()
  6037. end
  6038. end
  6039. end
  6040.  
  6041. funcs.Resize = function(self,sizeX,sizeY)
  6042. self.SizeX = sizeX or self.SizeX
  6043. self.SizeY = sizeY or self.SizeY
  6044. self.GuiElems.Main.Size = UDim2.new(0,self.SizeX,0,self.SizeY)
  6045. end
  6046.  
  6047. funcs.SetSize = funcs.Resize
  6048.  
  6049. funcs.SetTitle = function(self,title)
  6050. self.GuiElems.Title.Text = title
  6051. end
  6052.  
  6053. funcs.SetResizable = function(self,val)
  6054. self.Resizable = val
  6055. self.GuiElems.ResizeControls.Visible = self.Resizable and self.ResizableInternal
  6056. end
  6057.  
  6058. funcs.SetResizableInternal = function(self,val)
  6059. self.ResizableInternal = val
  6060. self.GuiElems.ResizeControls.Visible = self.Resizable and self.ResizableInternal
  6061. end
  6062.  
  6063. funcs.SetAligned = function(self,val)
  6064. self.Aligned = val
  6065. self:SetResizableInternal(not val)
  6066. self.GuiElems.Main.Active = not val
  6067. self.GuiElems.Main.Outlines.Visible = not val
  6068. if not val then
  6069. for i,v in pairs(leftSide.Windows) do if v == self then table.remove(leftSide.Windows,i) break end end
  6070. for i,v in pairs(rightSide.Windows) do if v == self then table.remove(rightSide.Windows,i) break end end
  6071. if not table.find(visibleWindows,self) then table.insert(visibleWindows,1,self) end
  6072. self.GuiElems.Minimize.ImageLabel.Image = "rbxassetid://5034768003"
  6073. self.Side = nil
  6074. updateWindows()
  6075. else
  6076. self:SetMinimized(false,3)
  6077. for i,v in pairs(visibleWindows) do if v == self then table.remove(visibleWindows,i) break end end
  6078. self.GuiElems.Minimize.ImageLabel.Image = "rbxassetid://5448127505"
  6079. end
  6080. end
  6081.  
  6082. funcs.Add = function(self,obj,name)
  6083. if type(obj) == "table" and obj.Gui and obj.Gui:IsA("GuiObject") then
  6084. obj.Gui.Parent = self.ContentPane
  6085. else
  6086. obj.Parent = self.ContentPane
  6087. end
  6088. if name then self.Elements[name] = obj end
  6089. end
  6090.  
  6091. funcs.GetElement = function(self,obj,name)
  6092. return self.Elements[name]
  6093. end
  6094.  
  6095. funcs.AlignTo = function(self,side,pos,size,silent)
  6096. if table.find(side.Windows,self) or self.Closed then return end
  6097.  
  6098. size = size or self.SizeY
  6099. if size > 0 and size <= 1 then
  6100. local totalSideHeight = 0
  6101. for i,v in pairs(side.Windows) do totalSideHeight = totalSideHeight + v.SizeY end
  6102. self.SizeY = (totalSideHeight > 0 and totalSideHeight * size * 2) or size
  6103. else
  6104. self.SizeY = (size > 0 and size or 100)
  6105. end
  6106.  
  6107. self:SetAligned(true)
  6108. self.Side = side
  6109. self.SizeX = side.Width
  6110. self.Gui.DisplayOrder = sideDisplayOrder + 1
  6111. for i,v in pairs(side.Windows) do v.Gui.DisplayOrder = sideDisplayOrder end
  6112. pos = math.min(#side.Windows+1, pos or 1)
  6113. self.SidePos = pos
  6114. table.insert(side.Windows, pos, self)
  6115.  
  6116. if not silent then
  6117. side.Hidden = false
  6118. end
  6119. updateWindows(silent)
  6120. end
  6121.  
  6122. funcs.Close = function(self)
  6123. self.Closed = true
  6124. self:SetResizableInternal(false)
  6125.  
  6126. Lib.FindAndRemove(leftSide.Windows,self)
  6127. Lib.FindAndRemove(rightSide.Windows,self)
  6128. Lib.FindAndRemove(visibleWindows,self)
  6129.  
  6130. self.MinimizeAnim.Disable()
  6131. self.CloseAnim.Disable()
  6132. self.ClosedSide = self.Side
  6133. self.Side = nil
  6134. self.OnDeactivate:Fire()
  6135.  
  6136. if not self.Aligned then
  6137. self:StopTweens()
  6138. local ti = TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  6139.  
  6140. local closeTime = tick()
  6141. self.LastClose = closeTime
  6142.  
  6143. self:DoTween(self.GuiElems.Main,ti,{Size = UDim2.new(0,self.SizeX,0,20)})
  6144. self:DoTween(self.GuiElems.Title,ti,{TextTransparency = 1})
  6145. self:DoTween(self.GuiElems.Minimize.ImageLabel,ti,{ImageTransparency = 1})
  6146. self:DoTween(self.GuiElems.Close.ImageLabel,ti,{ImageTransparency = 1})
  6147. Lib.FastWait(0.2)
  6148. if closeTime ~= self.LastClose then return end
  6149.  
  6150. self:DoTween(self.GuiElems.TopBar,ti,{BackgroundTransparency = 1})
  6151. self:DoTween(self.GuiElems.Outlines,ti,{ImageTransparency = 1})
  6152. Lib.FastWait(0.2)
  6153. if closeTime ~= self.LastClose then return end
  6154. end
  6155.  
  6156. self.Aligned = false
  6157. self.Gui.Parent = nil
  6158. updateWindows(true)
  6159. end
  6160.  
  6161. funcs.Hide = funcs.Close
  6162.  
  6163. funcs.IsVisible = function(self)
  6164. return not self.Closed and ((self.Side and not self.Side.Hidden) or not self.Side)
  6165. end
  6166.  
  6167. funcs.IsContentVisible = function(self)
  6168. return self:IsVisible() and not self.Minimized
  6169. end
  6170.  
  6171. funcs.Focus = function(self)
  6172. moveToTop(self)
  6173. end
  6174.  
  6175. funcs.MoveInBoundary = function(self)
  6176. local posX,posY = self.PosX,self.PosY
  6177. local maxX,maxY = sidesGui.AbsoluteSize.X,sidesGui.AbsoluteSize.Y
  6178. posX = math.min(posX,maxX-self.SizeX)
  6179. posY = math.min(posY,maxY-20)
  6180. self.GuiElems.Main.Position = UDim2.new(0,posX,0,posY)
  6181. end
  6182.  
  6183. funcs.DoTween = function(self,...)
  6184. local tween = service.TweenService:Create(...)
  6185. self.Tweens[#self.Tweens+1] = tween
  6186. tween:Play()
  6187. end
  6188.  
  6189. funcs.StopTweens = function(self)
  6190. for i,v in pairs(self.Tweens) do
  6191. v:Cancel()
  6192. end
  6193. self.Tweens = {}
  6194. end
  6195.  
  6196. funcs.Show = function(self,data)
  6197. return static.ShowWindow(self,data)
  6198. end
  6199.  
  6200. funcs.ShowAndFocus = function(self,data)
  6201. static.ShowWindow(self,data)
  6202. service.RunService.RenderStepped:wait()
  6203. self:Focus()
  6204. end
  6205.  
  6206. static.ShowWindow = function(window,data)
  6207. data = data or {}
  6208. local align = data.Align
  6209. local pos = data.Pos
  6210. local size = data.Size
  6211. local targetSide = (align == "left" and leftSide) or (align == "right" and rightSide)
  6212.  
  6213. if not window.Closed then
  6214. if not window.Aligned then
  6215. window:SetMinimized(false)
  6216. elseif window.Side and not data.Silent then
  6217. static.SetSideVisible(window.Side,true)
  6218. end
  6219. return
  6220. end
  6221.  
  6222. window.Closed = false
  6223. window.LastClose = tick()
  6224. window.GuiElems.Title.TextTransparency = 0
  6225. window.GuiElems.Minimize.ImageLabel.ImageTransparency = 0
  6226. window.GuiElems.Close.ImageLabel.ImageTransparency = 0
  6227. window.GuiElems.TopBar.BackgroundTransparency = 0
  6228. window.GuiElems.Outlines.ImageTransparency = 0
  6229. window.GuiElems.Minimize.ImageLabel.Image = "rbxassetid://5034768003"
  6230. window.GuiElems.Main.Active = true
  6231. window.GuiElems.Main.Outlines.Visible = true
  6232. window:SetMinimized(false,3)
  6233. window:SetResizableInternal(true)
  6234. window.MinimizeAnim.Enable()
  6235. window.CloseAnim.Enable()
  6236.  
  6237. if align then
  6238. window:AlignTo(targetSide,pos,size,data.Silent)
  6239. else
  6240. if align == nil and window.ClosedSide then -- Regular open
  6241. window:AlignTo(window.ClosedSide,window.SidePos,size,true)
  6242. static.SetSideVisible(window.ClosedSide,true)
  6243. else
  6244. if table.find(visibleWindows,window) then return end
  6245.  
  6246. -- TODO: make better
  6247. window.GuiElems.Main.Size = UDim2.new(0,window.SizeX,0,20)
  6248. local ti = TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  6249. window:StopTweens()
  6250. window:DoTween(window.GuiElems.Main,ti,{Size = UDim2.new(0,window.SizeX,0,window.SizeY)})
  6251.  
  6252. window.SizeY = size or window.SizeY
  6253. table.insert(visibleWindows,1,window)
  6254. updateWindows()
  6255. end
  6256. end
  6257.  
  6258. window.ClosedSide = nil
  6259. window.OnActivate:Fire()
  6260. end
  6261.  
  6262. static.ToggleSide = function(name)
  6263. local side = (name == "left" and leftSide or rightSide)
  6264. side.Hidden = not side.Hidden
  6265. for i,v in pairs(side.Windows) do
  6266. if side.Hidden then
  6267. v.OnDeactivate:Fire()
  6268. else
  6269. v.OnActivate:Fire()
  6270. end
  6271. end
  6272. updateWindows()
  6273. end
  6274.  
  6275. static.SetSideVisible = function(s,vis)
  6276. local side = (type(s) == "table" and s) or (s == "left" and leftSide or rightSide)
  6277. side.Hidden = not vis
  6278. for i,v in pairs(side.Windows) do
  6279. if side.Hidden then
  6280. v.OnDeactivate:Fire()
  6281. else
  6282. v.OnActivate:Fire()
  6283. end
  6284. end
  6285. updateWindows()
  6286. end
  6287.  
  6288. static.Init = function()
  6289. displayOrderStart = Main.DisplayOrders.Window
  6290. sideDisplayOrder = Main.DisplayOrders.SideWindow
  6291.  
  6292. sidesGui = Instance.new("ScreenGui")
  6293. local leftFrame = create({
  6294. {1,"Frame",{Active=true,Name="LeftSide",BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,}},
  6295. {2,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2549019753933,0.2549019753933,0.2549019753933),BorderSizePixel=0,Font=3,Name="Resizer",Parent={1},Size=UDim2.new(0,5,1,0),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  6296. {3,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={2},Position=UDim2.new(0,0,0,0),Size=UDim2.new(0,1,1,0),}},
  6297. {4,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2549019753933,0.2549019753933,0.2549019753933),BorderSizePixel=0,Font=3,Name="WindowResizer",Parent={1},Position=UDim2.new(1,-300,0,0),Size=UDim2.new(1,0,0,4),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  6298. {5,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={4},Size=UDim2.new(1,0,0,1),}},
  6299. })
  6300. leftSide.Frame = leftFrame
  6301. leftFrame.Position = UDim2.new(0,-leftSide.Width-10,0,0)
  6302. leftSide.WindowResizer = leftFrame.WindowResizer
  6303. leftFrame.WindowResizer.Parent = nil
  6304. leftFrame.Parent = sidesGui
  6305.  
  6306. local rightFrame = create({
  6307. {1,"Frame",{Active=true,Name="RightSide",BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,}},
  6308. {2,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2549019753933,0.2549019753933,0.2549019753933),BorderSizePixel=0,Font=3,Name="Resizer",Parent={1},Size=UDim2.new(0,5,1,0),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  6309. {3,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={2},Position=UDim2.new(0,4,0,0),Size=UDim2.new(0,1,1,0),}},
  6310. {4,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2549019753933,0.2549019753933,0.2549019753933),BorderSizePixel=0,Font=3,Name="WindowResizer",Parent={1},Position=UDim2.new(1,-300,0,0),Size=UDim2.new(1,0,0,4),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  6311. {5,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={4},Size=UDim2.new(1,0,0,1),}},
  6312. })
  6313. rightSide.Frame = rightFrame
  6314. rightFrame.Position = UDim2.new(1,10,0,0)
  6315. rightSide.WindowResizer = rightFrame.WindowResizer
  6316. rightFrame.WindowResizer.Parent = nil
  6317. rightFrame.Parent = sidesGui
  6318.  
  6319. sideResizerHook(leftFrame.Resizer,"H",leftSide)
  6320. sideResizerHook(rightFrame.Resizer,"H",rightSide)
  6321.  
  6322. alignIndicator = Instance.new("ScreenGui")
  6323. alignIndicator.DisplayOrder = Main.DisplayOrders.Core
  6324. local indicator = Instance.new("Frame",alignIndicator)
  6325. indicator.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
  6326. indicator.BorderSizePixel = 0
  6327. indicator.BackgroundTransparency = 0.8
  6328. indicator.Name = "Indicator"
  6329. local corner = Instance.new("UICorner",indicator)
  6330. corner.CornerRadius = UDim.new(0,10)
  6331.  
  6332. local leftToggle = create({{1,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderMode=2,Font=10,Name="LeftToggle",Position=UDim2.new(0,0,0,-36),Size=UDim2.new(0,16,0,36),Text="<",TextColor3=Color3.new(1,1,1),TextSize=14,}}})
  6333. local rightToggle = leftToggle:Clone()
  6334. rightToggle.Name = "RightToggle"
  6335. rightToggle.Position = UDim2.new(1,-16,0,-36)
  6336. Lib.ButtonAnim(leftToggle,{Mode = 2,PressColor = Color3.fromRGB(32,32,32)})
  6337. Lib.ButtonAnim(rightToggle,{Mode = 2,PressColor = Color3.fromRGB(32,32,32)})
  6338.  
  6339. leftToggle.MouseButton1Click:Connect(function()
  6340. static.ToggleSide("left")
  6341. end)
  6342.  
  6343. rightToggle.MouseButton1Click:Connect(function()
  6344. static.ToggleSide("right")
  6345. end)
  6346.  
  6347. leftToggle.Parent = sidesGui
  6348. rightToggle.Parent = sidesGui
  6349.  
  6350. sidesGui:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  6351. local maxWidth = math.max(300,sidesGui.AbsoluteSize.X-static.FreeWidth)
  6352. leftSide.Width = math.max(static.MinWidth,math.min(leftSide.Width,maxWidth-rightSide.Width))
  6353. rightSide.Width = math.max(static.MinWidth,math.min(rightSide.Width,maxWidth-leftSide.Width))
  6354. for i = 1,#visibleWindows do
  6355. visibleWindows[i]:MoveInBoundary()
  6356. end
  6357. updateWindows(true)
  6358. end)
  6359.  
  6360. sidesGui.DisplayOrder = sideDisplayOrder - 1
  6361. Lib.ShowGui(sidesGui)
  6362. updateSideFrames()
  6363. end
  6364.  
  6365. local mt = {__index = funcs}
  6366. static.new = function()
  6367. local obj = setmetatable({
  6368. Minimized = false,
  6369. Dragging = false,
  6370. Resizing = false,
  6371. Aligned = false,
  6372. Draggable = true,
  6373. Resizable = true,
  6374. ResizableInternal = true,
  6375. Alignable = true,
  6376. Closed = true,
  6377. SizeX = 300,
  6378. SizeY = 300,
  6379. MinX = 200,
  6380. MinY = 200,
  6381. PosX = 0,
  6382. PosY = 0,
  6383. GuiElems = {},
  6384. Tweens = {},
  6385. Elements = {},
  6386. OnActivate = Lib.Signal.new(),
  6387. OnDeactivate = Lib.Signal.new(),
  6388. OnMinimize = Lib.Signal.new(),
  6389. OnRestore = Lib.Signal.new()
  6390. },mt)
  6391. obj.Gui = createGui(obj)
  6392. return obj
  6393. end
  6394.  
  6395. return static
  6396. end)()
  6397.  
  6398. Lib.ContextMenu = (function()
  6399. local funcs = {}
  6400. local mouse
  6401.  
  6402. local function createGui(self)
  6403. local contextGui = create({
  6404. {1,"ScreenGui",{DisplayOrder=1000000,Name="Context",ZIndexBehavior=1,}},
  6405. {2,"Frame",{Active=true,BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),Name="Main",Parent={1},Position=UDim2.new(0.5,-100,0.5,-150),Size=UDim2.new(0,200,0,100),}},
  6406. {3,"UICorner",{CornerRadius=UDim.new(0,4),Parent={2},}},
  6407. {4,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),Name="Container",Parent={2},Position=UDim2.new(0,1,0,1),Size=UDim2.new(1,-2,1,-2),}},
  6408. {5,"UICorner",{CornerRadius=UDim.new(0,4),Parent={4},}},
  6409. {6,"ScrollingFrame",{Active=true,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BackgroundTransparency=1,BorderSizePixel=0,CanvasSize=UDim2.new(0,0,0,0),Name="List",Parent={4},Position=UDim2.new(0,2,0,2),ScrollBarImageColor3=Color3.new(0,0,0),ScrollBarThickness=4,Size=UDim2.new(1,-4,1,-4),VerticalScrollBarInset=1,}},
  6410. {7,"UIListLayout",{Parent={6},SortOrder=2,}},
  6411. {8,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="SearchFrame",Parent={4},Size=UDim2.new(1,0,0,24),Visible=false,}},
  6412. {9,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.1176470592618,0.1176470592618,0.1176470592618),BorderSizePixel=0,Name="SearchContainer",Parent={8},Position=UDim2.new(0,3,0,3),Size=UDim2.new(1,-6,0,18),}},
  6413. {10,"TextBox",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="SearchBox",Parent={9},PlaceholderColor3=Color3.new(0.39215689897537,0.39215689897537,0.39215689897537),PlaceholderText="Search",Position=UDim2.new(0,4,0,0),Size=UDim2.new(1,-8,0,18),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=0,}},
  6414. {11,"UICorner",{CornerRadius=UDim.new(0,2),Parent={9},}},
  6415. {12,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="Line",Parent={8},Position=UDim2.new(0,0,1,0),Size=UDim2.new(1,0,0,1),}},
  6416. {13,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BackgroundTransparency=1,BorderColor3=Color3.new(0.33725491166115,0.49019610881805,0.73725491762161),BorderSizePixel=0,Font=3,Name="Entry",Parent={1},Size=UDim2.new(1,0,0,22),Text="",TextSize=14,Visible=false,}},
  6417. {14,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="EntryName",Parent={13},Position=UDim2.new(0,24,0,0),Size=UDim2.new(1,-24,1,0),Text="Duplicate",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  6418. {15,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Shortcut",Parent={13},Position=UDim2.new(0,24,0,0),Size=UDim2.new(1,-30,1,0),Text="Ctrl+D",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  6419. {16,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,ImageRectOffset=Vector2.new(304,0),ImageRectSize=Vector2.new(16,16),Name="Icon",Parent={13},Position=UDim2.new(0,2,0,3),ScaleType=4,Size=UDim2.new(0,16,0,16),}},
  6420. {17,"UICorner",{CornerRadius=UDim.new(0,4),Parent={13},}},
  6421. {18,"Frame",{BackgroundColor3=Color3.new(0.21568629145622,0.21568629145622,0.21568629145622),BackgroundTransparency=1,BorderSizePixel=0,Name="Divider",Parent={1},Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,0,7),Visible=false,}},
  6422. {19,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="Line",Parent={18},Position=UDim2.new(0,0,0.5,0),Size=UDim2.new(1,0,0,1),}},
  6423. {20,"TextLabel",{AnchorPoint=Vector2.new(0,0.5),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="DividerName",Parent={18},Position=UDim2.new(0,2,0.5,0),Size=UDim2.new(1,-4,1,0),Text="Objects",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.60000002384186,TextXAlignment=0,Visible=false,}},
  6424. })
  6425. self.GuiElems.Main = contextGui.Main
  6426. self.GuiElems.List = contextGui.Main.Container.List
  6427. self.GuiElems.Entry = contextGui.Entry
  6428. self.GuiElems.Divider = contextGui.Divider
  6429. self.GuiElems.SearchFrame = contextGui.Main.Container.SearchFrame
  6430. self.GuiElems.SearchBar = self.GuiElems.SearchFrame.SearchContainer.SearchBox
  6431. Lib.ViewportTextBox.convert(self.GuiElems.SearchBar)
  6432.  
  6433. self.GuiElems.SearchBar:GetPropertyChangedSignal("Text"):Connect(function()
  6434. local lower,find = string.lower,string.find
  6435. local searchText = lower(self.GuiElems.SearchBar.Text)
  6436. local items = self.Items
  6437. local map = self.ItemToEntryMap
  6438.  
  6439. if searchText ~= "" then
  6440. local results = {}
  6441. local count = 1
  6442. for i = 1,#items do
  6443. local item = items[i]
  6444. local entry = map[item]
  6445. if entry then
  6446. if not item.Divider and find(lower(item.Name),searchText,1,true) then
  6447. results[count] = item
  6448. count = count + 1
  6449. else
  6450. entry.Visible = false
  6451. end
  6452. end
  6453. end
  6454. table.sort(results,function(a,b) return a.Name < b.Name end)
  6455. for i = 1,#results do
  6456. local entry = map[results[i]]
  6457. entry.LayoutOrder = i
  6458. entry.Visible = true
  6459. end
  6460. else
  6461. for i = 1,#items do
  6462. local entry = map[items[i]]
  6463. if entry then entry.LayoutOrder = i entry.Visible = true end
  6464. end
  6465. end
  6466.  
  6467. local toSize = self.GuiElems.List.UIListLayout.AbsoluteContentSize.Y + 6
  6468. self.GuiElems.List.CanvasSize = UDim2.new(0,0,0,toSize-6)
  6469. end)
  6470.  
  6471. return contextGui
  6472. end
  6473.  
  6474. funcs.Add = function(self,item)
  6475. local newItem = {
  6476. Name = item.Name or "Item",
  6477. Icon = item.Icon or "",
  6478. Shortcut = item.Shortcut or "",
  6479. OnClick = item.OnClick,
  6480. OnHover = item.OnHover,
  6481. Disabled = item.Disabled or false,
  6482. DisabledIcon = item.DisabledIcon or "",
  6483. IconMap = item.IconMap,
  6484. OnRightClick = item.OnRightClick
  6485. }
  6486. if self.QueuedDivider then
  6487. local text = self.QueuedDividerText and #self.QueuedDividerText > 0 and self.QueuedDividerText
  6488. self:AddDivider(text)
  6489. end
  6490. self.Items[#self.Items+1] = newItem
  6491. self.Updated = nil
  6492. end
  6493.  
  6494. funcs.AddRegistered = function(self,name,disabled)
  6495. if not self.Registered[name] then error(name.." is not registered") end
  6496.  
  6497. if self.QueuedDivider then
  6498. local text = self.QueuedDividerText and #self.QueuedDividerText > 0 and self.QueuedDividerText
  6499. self:AddDivider(text)
  6500. end
  6501. self.Registered[name].Disabled = disabled
  6502. self.Items[#self.Items+1] = self.Registered[name]
  6503. self.Updated = nil
  6504. end
  6505.  
  6506. funcs.Register = function(self,name,item)
  6507. self.Registered[name] = {
  6508. Name = item.Name or "Item",
  6509. Icon = item.Icon or "",
  6510. Shortcut = item.Shortcut or "",
  6511. OnClick = item.OnClick,
  6512. OnHover = item.OnHover,
  6513. DisabledIcon = item.DisabledIcon or "",
  6514. IconMap = item.IconMap,
  6515. OnRightClick = item.OnRightClick
  6516. }
  6517. end
  6518.  
  6519. funcs.UnRegister = function(self,name)
  6520. self.Registered[name] = nil
  6521. end
  6522.  
  6523. funcs.AddDivider = function(self,text)
  6524. self.QueuedDivider = false
  6525. local textWidth = text and service.TextService:GetTextSize(text,14,Enum.Font.SourceSans,Vector2.new(999999999,20)).X or nil
  6526. table.insert(self.Items,{Divider = true, Text = text, TextSize = textWidth and textWidth+4})
  6527. self.Updated = nil
  6528. end
  6529.  
  6530. funcs.QueueDivider = function(self,text)
  6531. self.QueuedDivider = true
  6532. self.QueuedDividerText = text or ""
  6533. end
  6534.  
  6535. funcs.Clear = function(self)
  6536. self.Items = {}
  6537. self.Updated = nil
  6538. end
  6539.  
  6540. funcs.Refresh = function(self)
  6541. for i,v in pairs(self.GuiElems.List:GetChildren()) do
  6542. if not v:IsA("UIListLayout") then
  6543. v:Destroy()
  6544. end
  6545. end
  6546. local map = {}
  6547. self.ItemToEntryMap = map
  6548.  
  6549. local dividerFrame = self.GuiElems.Divider
  6550. local contextList = self.GuiElems.List
  6551. local entryFrame = self.GuiElems.Entry
  6552. local items = self.Items
  6553.  
  6554. for i = 1,#items do
  6555. local item = items[i]
  6556. if item.Divider then
  6557. local newDivider = dividerFrame:Clone()
  6558. newDivider.Line.BackgroundColor3 = self.Theme.DividerColor
  6559. if item.Text then
  6560. newDivider.Size = UDim2.new(1,0,0,20)
  6561. newDivider.Line.Position = UDim2.new(0,item.TextSize,0.5,0)
  6562. newDivider.Line.Size = UDim2.new(1,-item.TextSize,0,1)
  6563. newDivider.DividerName.TextColor3 = self.Theme.TextColor
  6564. newDivider.DividerName.Text = item.Text
  6565. newDivider.DividerName.Visible = true
  6566. end
  6567. newDivider.Visible = true
  6568. map[item] = newDivider
  6569. newDivider.Parent = contextList
  6570. else
  6571. local newEntry = entryFrame:Clone()
  6572. newEntry.BackgroundColor3 = self.Theme.HighlightColor
  6573. newEntry.EntryName.TextColor3 = self.Theme.TextColor
  6574. newEntry.EntryName.Text = item.Name
  6575. newEntry.Shortcut.Text = item.Shortcut
  6576. if item.Disabled then
  6577. newEntry.EntryName.TextColor3 = Color3.new(150/255,150/255,150/255)
  6578. newEntry.Shortcut.TextColor3 = Color3.new(150/255,150/255,150/255)
  6579. end
  6580.  
  6581. if self.Iconless then
  6582. newEntry.EntryName.Position = UDim2.new(0,2,0,0)
  6583. newEntry.EntryName.Size = UDim2.new(1,-4,0,20)
  6584. newEntry.Icon.Visible = false
  6585. else
  6586. local iconIndex = item.Disabled and item.DisabledIcon or item.Icon
  6587. if item.IconMap then
  6588. if type(iconIndex) == "number" then
  6589. item.IconMap:Display(newEntry.Icon,iconIndex)
  6590. elseif type(iconIndex) == "string" then
  6591. item.IconMap:DisplayByKey(newEntry.Icon,iconIndex)
  6592. end
  6593. elseif type(iconIndex) == "string" then
  6594. newEntry.Icon.Image = iconIndex
  6595. end
  6596. end
  6597.  
  6598. if not item.Disabled then
  6599. if item.OnClick then
  6600. newEntry.MouseButton1Click:Connect(function()
  6601. item.OnClick(item.Name)
  6602. if not item.NoHide then
  6603. self:Hide()
  6604. end
  6605. end)
  6606. end
  6607.  
  6608. if item.OnRightClick then
  6609. newEntry.MouseButton2Click:Connect(function()
  6610. item.OnRightClick(item.Name)
  6611. if not item.NoHide then
  6612. self:Hide()
  6613. end
  6614. end)
  6615. end
  6616. end
  6617.  
  6618. newEntry.InputBegan:Connect(function(input)
  6619. if input.UserInputType == Enum.UserInputType.MouseMovement then
  6620. newEntry.BackgroundTransparency = 0
  6621. end
  6622. end)
  6623.  
  6624. newEntry.InputEnded:Connect(function(input)
  6625. if input.UserInputType == Enum.UserInputType.MouseMovement then
  6626. newEntry.BackgroundTransparency = 1
  6627. end
  6628. end)
  6629.  
  6630. newEntry.Visible = true
  6631. map[item] = newEntry
  6632. newEntry.Parent = contextList
  6633. end
  6634. end
  6635. self.Updated = true
  6636. end
  6637.  
  6638. funcs.Show = function(self,x,y)
  6639. -- Initialize Gui
  6640. local elems = self.GuiElems
  6641. elems.SearchFrame.Visible = self.SearchEnabled
  6642. elems.List.Position = UDim2.new(0,2,0,2 + (self.SearchEnabled and 24 or 0))
  6643. elems.List.Size = UDim2.new(1,-4,1,-4 - (self.SearchEnabled and 24 or 0))
  6644. if self.SearchEnabled and self.ClearSearchOnShow then elems.SearchBar.Text = "" end
  6645. self.GuiElems.List.CanvasPosition = Vector2.new(0,0)
  6646.  
  6647. if not self.Updated then
  6648. self:Refresh() -- Create entries
  6649. end
  6650.  
  6651. -- Vars
  6652. local reverseY = false
  6653. local x,y = x or mouse.X, y or mouse.Y
  6654. local maxX,maxY = mouse.ViewSizeX,mouse.ViewSizeY
  6655.  
  6656. -- Position and show
  6657. if x + self.Width > maxX then
  6658. x = self.ReverseX and x - self.Width or maxX - self.Width
  6659. end
  6660. elems.Main.Position = UDim2.new(0,x,0,y)
  6661. elems.Main.Size = UDim2.new(0,self.Width,0,0)
  6662. self.Gui.DisplayOrder = Main.DisplayOrders.Menu
  6663. Lib.ShowGui(self.Gui)
  6664.  
  6665. -- Size adjustment
  6666. local toSize = elems.List.UIListLayout.AbsoluteContentSize.Y + 6 -- Padding
  6667. if self.MaxHeight and toSize > self.MaxHeight then
  6668. elems.List.CanvasSize = UDim2.new(0,0,0,toSize-6)
  6669. toSize = self.MaxHeight
  6670. else
  6671. elems.List.CanvasSize = UDim2.new(0,0,0,0)
  6672. end
  6673. if y + toSize > maxY then reverseY = true end
  6674.  
  6675. -- Close event
  6676. local closable
  6677. if self.CloseEvent then self.CloseEvent:Disconnect() end
  6678. self.CloseEvent = service.UserInputService.InputBegan:Connect(function(input)
  6679. if not closable or input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  6680.  
  6681. if not Lib.CheckMouseInGui(elems.Main) then
  6682. self.CloseEvent:Disconnect()
  6683. self:Hide()
  6684. end
  6685. end)
  6686.  
  6687. -- Resize
  6688. if reverseY then
  6689. elems.Main.Position = UDim2.new(0,x,0,y-(self.ReverseYOffset or 0))
  6690. local newY = y - toSize - (self.ReverseYOffset or 0)
  6691. y = newY >= 0 and newY or 0
  6692. elems.Main:TweenSizeAndPosition(UDim2.new(0,self.Width,0,toSize),UDim2.new(0,x,0,y),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.2,true)
  6693. else
  6694. elems.Main:TweenSize(UDim2.new(0,self.Width,0,toSize),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,0.2,true)
  6695. end
  6696.  
  6697. -- Close debounce
  6698. Lib.FastWait()
  6699. if self.SearchEnabled and self.FocusSearchOnShow then elems.SearchBar:CaptureFocus() end
  6700. closable = true
  6701. end
  6702.  
  6703. funcs.Hide = function(self)
  6704. self.Gui.Parent = nil
  6705. end
  6706.  
  6707. funcs.ApplyTheme = function(self,data)
  6708. local theme = self.Theme
  6709. theme.ContentColor = data.ContentColor or Settings.Theme.Menu
  6710. theme.OutlineColor = data.OutlineColor or Settings.Theme.Menu
  6711. theme.DividerColor = data.DividerColor or Settings.Theme.Outline2
  6712. theme.TextColor = data.TextColor or Settings.Theme.Text
  6713. theme.HighlightColor = data.HighlightColor or Settings.Theme.Main1
  6714.  
  6715. self.GuiElems.Main.BackgroundColor3 = theme.OutlineColor
  6716. self.GuiElems.Main.Container.BackgroundColor3 = theme.ContentColor
  6717. end
  6718.  
  6719. local mt = {__index = funcs}
  6720. local function new()
  6721. if not mouse then mouse = Main.Mouse or service.Players.LocalPlayer:GetMouse() end
  6722.  
  6723. local obj = setmetatable({
  6724. Width = 200,
  6725. MaxHeight = nil,
  6726. Iconless = false,
  6727. SearchEnabled = false,
  6728. ClearSearchOnShow = true,
  6729. FocusSearchOnShow = true,
  6730. Updated = false,
  6731. QueuedDivider = false,
  6732. QueuedDividerText = "",
  6733. Items = {},
  6734. Registered = {},
  6735. GuiElems = {},
  6736. Theme = {}
  6737. },mt)
  6738. obj.Gui = createGui(obj)
  6739. obj:ApplyTheme({})
  6740. return obj
  6741. end
  6742.  
  6743. return {new = new}
  6744. end)()
  6745.  
  6746. Lib.CodeFrame = (function()
  6747. local funcs = {}
  6748.  
  6749. local typeMap = {
  6750. [1] = "String",
  6751. [2] = "String",
  6752. [3] = "String",
  6753. [4] = "Comment",
  6754. [5] = "Operator",
  6755. [6] = "Number",
  6756. [7] = "Keyword",
  6757. [8] = "BuiltIn",
  6758. [9] = "LocalMethod",
  6759. [10] = "LocalProperty",
  6760. [11] = "Nil",
  6761. [12] = "Bool",
  6762. [13] = "Function",
  6763. [14] = "Local",
  6764. [15] = "Self",
  6765. [16] = "FunctionName",
  6766. [17] = "Bracket"
  6767. }
  6768.  
  6769. local specialKeywordsTypes = {
  6770. ["nil"] = 11,
  6771. ["true"] = 12,
  6772. ["false"] = 12,
  6773. ["function"] = 13,
  6774. ["local"] = 14,
  6775. ["self"] = 15
  6776. }
  6777.  
  6778. local keywords = {
  6779. ["and"] = true,
  6780. ["break"] = true,
  6781. ["do"] = true,
  6782. ["else"] = true,
  6783. ["elseif"] = true,
  6784. ["end"] = true,
  6785. ["false"] = true,
  6786. ["for"] = true,
  6787. ["function"] = true,
  6788. ["if"] = true,
  6789. ["in"] = true,
  6790. ["local"] = true,
  6791. ["nil"] = true,
  6792. ["not"] = true,
  6793. ["or"] = true,
  6794. ["repeat"] = true,
  6795. ["return"] = true,
  6796. ["then"] = true,
  6797. ["true"] = true,
  6798. ["until"] = true,
  6799. ["while"] = true,
  6800. ["plugin"] = true
  6801. }
  6802.  
  6803. local builtIns = {
  6804. ["delay"] = true,
  6805. ["elapsedTime"] = true,
  6806. ["require"] = true,
  6807. ["spawn"] = true,
  6808. ["tick"] = true,
  6809. ["time"] = true,
  6810. ["typeof"] = true,
  6811. ["UserSettings"] = true,
  6812. ["wait"] = true,
  6813. ["warn"] = true,
  6814. ["game"] = true,
  6815. ["shared"] = true,
  6816. ["script"] = true,
  6817. ["workspace"] = true,
  6818. ["assert"] = true,
  6819. ["collectgarbage"] = true,
  6820. ["error"] = true,
  6821. ["getfenv"] = true,
  6822. ["getmetatable"] = true,
  6823. ["ipairs"] = true,
  6824. ["loadstring"] = true,
  6825. ["newproxy"] = true,
  6826. ["next"] = true,
  6827. ["pairs"] = true,
  6828. ["pcall"] = true,
  6829. ["print"] = true,
  6830. ["rawequal"] = true,
  6831. ["rawget"] = true,
  6832. ["rawset"] = true,
  6833. ["select"] = true,
  6834. ["setfenv"] = true,
  6835. ["setmetatable"] = true,
  6836. ["tonumber"] = true,
  6837. ["tostring"] = true,
  6838. ["type"] = true,
  6839. ["unpack"] = true,
  6840. ["xpcall"] = true,
  6841. ["_G"] = true,
  6842. ["_VERSION"] = true,
  6843. ["coroutine"] = true,
  6844. ["debug"] = true,
  6845. ["math"] = true,
  6846. ["os"] = true,
  6847. ["string"] = true,
  6848. ["table"] = true,
  6849. ["bit32"] = true,
  6850. ["utf8"] = true,
  6851. ["Axes"] = true,
  6852. ["BrickColor"] = true,
  6853. ["CFrame"] = true,
  6854. ["Color3"] = true,
  6855. ["ColorSequence"] = true,
  6856. ["ColorSequenceKeypoint"] = true,
  6857. ["DockWidgetPluginGuiInfo"] = true,
  6858. ["Enum"] = true,
  6859. ["Faces"] = true,
  6860. ["Instance"] = true,
  6861. ["NumberRange"] = true,
  6862. ["NumberSequence"] = true,
  6863. ["NumberSequenceKeypoint"] = true,
  6864. ["PathWaypoint"] = true,
  6865. ["PhysicalProperties"] = true,
  6866. ["Random"] = true,
  6867. ["Ray"] = true,
  6868. ["Rect"] = true,
  6869. ["Region3"] = true,
  6870. ["Region3int16"] = true,
  6871. ["TweenInfo"] = true,
  6872. ["UDim"] = true,
  6873. ["UDim2"] = true,
  6874. ["Vector2"] = true,
  6875. ["Vector2int16"] = true,
  6876. ["Vector3"] = true,
  6877. ["Vector3int16"] = true
  6878. }
  6879.  
  6880. local builtInInited = false
  6881.  
  6882. local richReplace = {
  6883. ["'"] = "&apos;",
  6884. ["\""] = "&quot;",
  6885. ["<"] = "&lt;",
  6886. [">"] = "&gt;",
  6887. ["&"] = "&amp;"
  6888. }
  6889.  
  6890. local tabSub = "\205"
  6891. local tabReplacement = (" %s%s "):format(tabSub,tabSub)
  6892.  
  6893. local tabJumps = {
  6894. [("[^%s] %s"):format(tabSub,tabSub)] = 0,
  6895. [(" %s%s"):format(tabSub,tabSub)] = -1,
  6896. [("%s%s "):format(tabSub,tabSub)] = 2,
  6897. [("%s [^%s]"):format(tabSub,tabSub)] = 1,
  6898. }
  6899.  
  6900. local tweenService = service.TweenService
  6901. local lineTweens = {}
  6902.  
  6903. local function initBuiltIn()
  6904. local env = getfenv()
  6905. local type = type
  6906. local tostring = tostring
  6907. for name,_ in next,builtIns do
  6908. local envVal = env[name]
  6909. if type(envVal) == "table" then
  6910. local items = {}
  6911. for i,v in next,envVal do
  6912. items[i] = true
  6913. end
  6914. builtIns[name] = items
  6915. end
  6916. end
  6917.  
  6918. local enumEntries = {}
  6919. local enums = Enum:GetEnums()
  6920. for i = 1,#enums do
  6921. enumEntries[tostring(enums[i])] = true
  6922. end
  6923. builtIns["Enum"] = enumEntries
  6924.  
  6925. builtInInited = true
  6926. end
  6927.  
  6928. local function setupEditBox(obj)
  6929. local editBox = obj.GuiElems.EditBox
  6930.  
  6931. editBox.Focused:Connect(function()
  6932. obj:ConnectEditBoxEvent()
  6933. obj.Editing = true
  6934. end)
  6935.  
  6936. editBox.FocusLost:Connect(function()
  6937. obj:DisconnectEditBoxEvent()
  6938. obj.Editing = false
  6939. end)
  6940.  
  6941. editBox:GetPropertyChangedSignal("Text"):Connect(function()
  6942. local text = editBox.Text
  6943. if #text == 0 or obj.EditBoxCopying then return end
  6944. editBox.Text = ""
  6945. obj:AppendText(text)
  6946. end)
  6947. end
  6948.  
  6949. local function setupMouseSelection(obj)
  6950. local mouse = plr:GetMouse()
  6951. local codeFrame = obj.GuiElems.LinesFrame
  6952. local lines = obj.Lines
  6953.  
  6954. codeFrame.InputBegan:Connect(function(input)
  6955. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  6956. local fontSizeX,fontSizeY = math.ceil(obj.FontSize/2),obj.FontSize
  6957.  
  6958. local relX = mouse.X - codeFrame.AbsolutePosition.X
  6959. local relY = mouse.Y - codeFrame.AbsolutePosition.Y
  6960. local selX = math.round(relX / fontSizeX) + obj.ViewX
  6961. local selY = math.floor(relY / fontSizeY) + obj.ViewY
  6962. local releaseEvent,mouseEvent,scrollEvent
  6963. local scrollPowerV,scrollPowerH = 0,0
  6964. selY = math.min(#lines-1,selY)
  6965. local relativeLine = lines[selY+1] or ""
  6966. selX = math.min(#relativeLine, selX + obj:TabAdjust(selX,selY))
  6967.  
  6968. obj.SelectionRange = {{-1,-1},{-1,-1}}
  6969. obj:MoveCursor(selX,selY)
  6970. obj.FloatCursorX = selX
  6971.  
  6972. local function updateSelection()
  6973. local relX = mouse.X - codeFrame.AbsolutePosition.X
  6974. local relY = mouse.Y - codeFrame.AbsolutePosition.Y
  6975. local sel2X = math.max(0,math.round(relX / fontSizeX) + obj.ViewX)
  6976. local sel2Y = math.max(0,math.floor(relY / fontSizeY) + obj.ViewY)
  6977.  
  6978. sel2Y = math.min(#lines-1,sel2Y)
  6979. local relativeLine = lines[sel2Y+1] or ""
  6980. sel2X = math.min(#relativeLine, sel2X + obj:TabAdjust(sel2X,sel2Y))
  6981.  
  6982. if sel2Y < selY or (sel2Y == selY and sel2X < selX) then
  6983. obj.SelectionRange = {{sel2X,sel2Y},{selX,selY}}
  6984. else
  6985. obj.SelectionRange = {{selX,selY},{sel2X,sel2Y}}
  6986. end
  6987.  
  6988. obj:MoveCursor(sel2X,sel2Y)
  6989. obj.FloatCursorX = sel2X
  6990. obj:Refresh()
  6991. end
  6992.  
  6993. releaseEvent = service.UserInputService.InputEnded:Connect(function(input)
  6994. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  6995. releaseEvent:Disconnect()
  6996. mouseEvent:Disconnect()
  6997. scrollEvent:Disconnect()
  6998. obj:SetCopyableSelection()
  6999. --updateSelection()
  7000. end
  7001. end)
  7002.  
  7003. mouseEvent = service.UserInputService.InputChanged:Connect(function(input)
  7004. if input.UserInputType == Enum.UserInputType.MouseMovement then
  7005. local upDelta = mouse.Y - codeFrame.AbsolutePosition.Y
  7006. local downDelta = mouse.Y - codeFrame.AbsolutePosition.Y - codeFrame.AbsoluteSize.Y
  7007. local leftDelta = mouse.X - codeFrame.AbsolutePosition.X
  7008. local rightDelta = mouse.X - codeFrame.AbsolutePosition.X - codeFrame.AbsoluteSize.X
  7009. scrollPowerV = 0
  7010. scrollPowerH = 0
  7011. if downDelta > 0 then
  7012. scrollPowerV = math.floor(downDelta*0.05) + 1
  7013. elseif upDelta < 0 then
  7014. scrollPowerV = math.ceil(upDelta*0.05) - 1
  7015. end
  7016. if rightDelta > 0 then
  7017. scrollPowerH = math.floor(rightDelta*0.05) + 1
  7018. elseif leftDelta < 0 then
  7019. scrollPowerH = math.ceil(leftDelta*0.05) - 1
  7020. end
  7021. updateSelection()
  7022. end
  7023. end)
  7024.  
  7025. scrollEvent = clonerefs(game:GetService("RunService")).RenderStepped:Connect(function()
  7026. if scrollPowerV ~= 0 or scrollPowerH ~= 0 then
  7027. obj:ScrollDelta(scrollPowerH,scrollPowerV)
  7028. updateSelection()
  7029. end
  7030. end)
  7031.  
  7032. obj:Refresh()
  7033. end
  7034. end)
  7035. end
  7036.  
  7037. local function makeFrame(obj)
  7038. local frame = create({
  7039. {1,"Frame",{BackgroundColor3=Color3.new(0.15686275064945,0.15686275064945,0.15686275064945),BorderSizePixel = 0,Position=UDim2.new(0.5,-300,0.5,-200),Size=UDim2.new(0,600,0,400),}},
  7040. })
  7041. local elems = {}
  7042.  
  7043. local linesFrame = Instance.new("Frame")
  7044. linesFrame.Name = "Lines"
  7045. linesFrame.BackgroundTransparency = 1
  7046. linesFrame.Size = UDim2.new(1,0,1,0)
  7047. linesFrame.ClipsDescendants = true
  7048. linesFrame.Parent = frame
  7049.  
  7050. local lineNumbersLabel = Instance.new("TextLabel")
  7051. lineNumbersLabel.Name = "LineNumbers"
  7052. lineNumbersLabel.BackgroundTransparency = 1
  7053. lineNumbersLabel.Font = Enum.Font.Code
  7054. lineNumbersLabel.TextXAlignment = Enum.TextXAlignment.Right
  7055. lineNumbersLabel.TextYAlignment = Enum.TextYAlignment.Top
  7056. lineNumbersLabel.ClipsDescendants = true
  7057. lineNumbersLabel.RichText = true
  7058. lineNumbersLabel.Parent = frame
  7059.  
  7060. local cursor = Instance.new("Frame")
  7061. cursor.Name = "Cursor"
  7062. cursor.BackgroundColor3 = Color3.fromRGB(220,220,220)
  7063. cursor.BorderSizePixel = 0
  7064. cursor.Parent = frame
  7065.  
  7066. local editBox = Instance.new("TextBox")
  7067. editBox.Name = "EditBox"
  7068. editBox.MultiLine = true
  7069. editBox.Visible = false
  7070. editBox.Parent = frame
  7071.  
  7072. lineTweens.Invis = tweenService:Create(cursor,TweenInfo.new(0.4,Enum.EasingStyle.Quart,Enum.EasingDirection.Out),{BackgroundTransparency = 1})
  7073. lineTweens.Vis = tweenService:Create(cursor,TweenInfo.new(0.2,Enum.EasingStyle.Quart,Enum.EasingDirection.Out),{BackgroundTransparency = 0})
  7074.  
  7075. elems.LinesFrame = linesFrame
  7076. elems.LineNumbersLabel = lineNumbersLabel
  7077. elems.Cursor = cursor
  7078. elems.EditBox = editBox
  7079. elems.ScrollCorner = create({{1,"Frame",{BackgroundColor3=Color3.new(0.15686275064945,0.15686275064945,0.15686275064945),BorderSizePixel=0,Name="ScrollCorner",Position=UDim2.new(1,-16,1,-16),Size=UDim2.new(0,16,0,16),Visible=false,}}})
  7080.  
  7081. elems.ScrollCorner.Parent = frame
  7082. linesFrame.InputBegan:Connect(function(input)
  7083. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  7084. obj:SetEditing(true,input)
  7085. end
  7086. end)
  7087.  
  7088. obj.Frame = frame
  7089. obj.Gui = frame
  7090. obj.GuiElems = elems
  7091. setupEditBox(obj)
  7092. setupMouseSelection(obj)
  7093.  
  7094. return frame
  7095. end
  7096.  
  7097. funcs.GetSelectionText = function(self)
  7098. if not self:IsValidRange() then return "" end
  7099.  
  7100. local selectionRange = self.SelectionRange
  7101. local selX,selY = selectionRange[1][1], selectionRange[1][2]
  7102. local sel2X,sel2Y = selectionRange[2][1], selectionRange[2][2]
  7103. local deltaLines = sel2Y-selY
  7104. local lines = self.Lines
  7105.  
  7106. if not lines[selY+1] or not lines[sel2Y+1] then return "" end
  7107.  
  7108. if deltaLines == 0 then
  7109. return self:ConvertText(lines[selY+1]:sub(selX+1,sel2X), false)
  7110. end
  7111.  
  7112. local leftSub = lines[selY+1]:sub(selX+1)
  7113. local rightSub = lines[sel2Y+1]:sub(1,sel2X)
  7114.  
  7115. local result = leftSub.."\n"
  7116. for i = selY+1,sel2Y-1 do
  7117. result = result..lines[i+1].."\n"
  7118. end
  7119. result = result..rightSub
  7120.  
  7121. return self:ConvertText(result,false)
  7122. end
  7123.  
  7124. funcs.SetCopyableSelection = function(self)
  7125. local text = self:GetSelectionText()
  7126. local editBox = self.GuiElems.EditBox
  7127.  
  7128. self.EditBoxCopying = true
  7129. editBox.Text = text
  7130. editBox.SelectionStart = 1
  7131. editBox.CursorPosition = #editBox.Text + 1
  7132. self.EditBoxCopying = false
  7133. end
  7134.  
  7135. funcs.ConnectEditBoxEvent = function(self)
  7136. if self.EditBoxEvent then
  7137. self.EditBoxEvent:Disconnect()
  7138. end
  7139.  
  7140. self.EditBoxEvent = service.UserInputService.InputBegan:Connect(function(input)
  7141. if input.UserInputType ~= Enum.UserInputType.Keyboard then return end
  7142.  
  7143. local keycodes = Enum.KeyCode
  7144. local keycode = input.KeyCode
  7145.  
  7146. local function setupMove(key,func)
  7147. local endCon,finished
  7148. endCon = service.UserInputService.InputEnded:Connect(function(input)
  7149. if input.KeyCode ~= key then return end
  7150. endCon:Disconnect()
  7151. finished = true
  7152. end)
  7153. func()
  7154. Lib.FastWait(0.5)
  7155. while not finished do func() Lib.FastWait(0.03) end
  7156. end
  7157.  
  7158. if keycode == keycodes.Down then
  7159. setupMove(keycodes.Down,function()
  7160. self.CursorX = self.FloatCursorX
  7161. self.CursorY = self.CursorY + 1
  7162. self:UpdateCursor()
  7163. self:JumpToCursor()
  7164. end)
  7165. elseif keycode == keycodes.Up then
  7166. setupMove(keycodes.Up,function()
  7167. self.CursorX = self.FloatCursorX
  7168. self.CursorY = self.CursorY - 1
  7169. self:UpdateCursor()
  7170. self:JumpToCursor()
  7171. end)
  7172. elseif keycode == keycodes.Left then
  7173. setupMove(keycodes.Left,function()
  7174. local line = self.Lines[self.CursorY+1] or ""
  7175. self.CursorX = self.CursorX - 1 - (line:sub(self.CursorX-3,self.CursorX) == tabReplacement and 3 or 0)
  7176. if self.CursorX < 0 then
  7177. self.CursorY = self.CursorY - 1
  7178. local line2 = self.Lines[self.CursorY+1] or ""
  7179. self.CursorX = #line2
  7180. end
  7181. self.FloatCursorX = self.CursorX
  7182. self:UpdateCursor()
  7183. self:JumpToCursor()
  7184. end)
  7185. elseif keycode == keycodes.Right then
  7186. setupMove(keycodes.Right,function()
  7187. local line = self.Lines[self.CursorY+1] or ""
  7188. self.CursorX = self.CursorX + 1 + (line:sub(self.CursorX+1,self.CursorX+4) == tabReplacement and 3 or 0)
  7189. if self.CursorX > #line then
  7190. self.CursorY = self.CursorY + 1
  7191. self.CursorX = 0
  7192. end
  7193. self.FloatCursorX = self.CursorX
  7194. self:UpdateCursor()
  7195. self:JumpToCursor()
  7196. end)
  7197. elseif keycode == keycodes.Backspace then
  7198. setupMove(keycodes.Backspace,function()
  7199. local startRange,endRange
  7200. if self:IsValidRange() then
  7201. startRange = self.SelectionRange[1]
  7202. endRange = self.SelectionRange[2]
  7203. else
  7204. endRange = {self.CursorX,self.CursorY}
  7205. end
  7206.  
  7207. if not startRange then
  7208. local line = self.Lines[self.CursorY+1] or ""
  7209. self.CursorX = self.CursorX - 1 - (line:sub(self.CursorX-3,self.CursorX) == tabReplacement and 3 or 0)
  7210. if self.CursorX < 0 then
  7211. self.CursorY = self.CursorY - 1
  7212. local line2 = self.Lines[self.CursorY+1] or ""
  7213. self.CursorX = #line2
  7214. end
  7215. self.FloatCursorX = self.CursorX
  7216. self:UpdateCursor()
  7217.  
  7218. startRange = startRange or {self.CursorX,self.CursorY}
  7219. end
  7220.  
  7221. self:DeleteRange({startRange,endRange},false,true)
  7222. self:ResetSelection(true)
  7223. self:JumpToCursor()
  7224. end)
  7225. elseif keycode == keycodes.Delete then
  7226. setupMove(keycodes.Delete,function()
  7227. local startRange,endRange
  7228. if self:IsValidRange() then
  7229. startRange = self.SelectionRange[1]
  7230. endRange = self.SelectionRange[2]
  7231. else
  7232. startRange = {self.CursorX,self.CursorY}
  7233. end
  7234.  
  7235. if not endRange then
  7236. local line = self.Lines[self.CursorY+1] or ""
  7237. local endCursorX = self.CursorX + 1 + (line:sub(self.CursorX+1,self.CursorX+4) == tabReplacement and 3 or 0)
  7238. local endCursorY = self.CursorY
  7239. if endCursorX > #line then
  7240. endCursorY = endCursorY + 1
  7241. endCursorX = 0
  7242. end
  7243. self:UpdateCursor()
  7244.  
  7245. endRange = endRange or {endCursorX,endCursorY}
  7246. end
  7247.  
  7248. self:DeleteRange({startRange,endRange},false,true)
  7249. self:ResetSelection(true)
  7250. self:JumpToCursor()
  7251. end)
  7252. elseif service.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then
  7253. if keycode == keycodes.A then
  7254. self.SelectionRange = {{0,0},{#self.Lines[#self.Lines],#self.Lines-1}}
  7255. self:SetCopyableSelection()
  7256. self:Refresh()
  7257. end
  7258. end
  7259. end)
  7260. end
  7261.  
  7262. funcs.DisconnectEditBoxEvent = function(self)
  7263. if self.EditBoxEvent then
  7264. self.EditBoxEvent:Disconnect()
  7265. end
  7266. end
  7267.  
  7268. funcs.ResetSelection = function(self,norefresh)
  7269. self.SelectionRange = {{-1,-1},{-1,-1}}
  7270. if not norefresh then self:Refresh() end
  7271. end
  7272.  
  7273. funcs.IsValidRange = function(self,range)
  7274. local selectionRange = range or self.SelectionRange
  7275. local selX,selY = selectionRange[1][1], selectionRange[1][2]
  7276. local sel2X,sel2Y = selectionRange[2][1], selectionRange[2][2]
  7277.  
  7278. if selX == -1 or (selX == sel2X and selY == sel2Y) then return false end
  7279.  
  7280. return true
  7281. end
  7282.  
  7283. funcs.DeleteRange = function(self,range,noprocess,updatemouse)
  7284. range = range or self.SelectionRange
  7285. if not self:IsValidRange(range) then return end
  7286.  
  7287. local lines = self.Lines
  7288. local selX,selY = range[1][1], range[1][2]
  7289. local sel2X,sel2Y = range[2][1], range[2][2]
  7290. local deltaLines = sel2Y-selY
  7291.  
  7292. if not lines[selY+1] or not lines[sel2Y+1] then return end
  7293.  
  7294. local leftSub = lines[selY+1]:sub(1,selX)
  7295. local rightSub = lines[sel2Y+1]:sub(sel2X+1)
  7296. lines[selY+1] = leftSub..rightSub
  7297.  
  7298. local remove = table.remove
  7299. for i = 1,deltaLines do
  7300. remove(lines,selY+2)
  7301. end
  7302.  
  7303. if range == self.SelectionRange then self.SelectionRange = {{-1,-1},{-1,-1}} end
  7304. if updatemouse then
  7305. self.CursorX = selX
  7306. self.CursorY = selY
  7307. self:UpdateCursor()
  7308. end
  7309.  
  7310. if not noprocess then
  7311. self:ProcessTextChange()
  7312. end
  7313. end
  7314.  
  7315. funcs.AppendText = function(self,text)
  7316. self:DeleteRange(nil,true,true)
  7317. local lines,cursorX,cursorY = self.Lines,self.CursorX,self.CursorY
  7318. local line = lines[cursorY+1]
  7319. local before = line:sub(1,cursorX)
  7320. local after = line:sub(cursorX+1)
  7321.  
  7322. text = text:gsub("\r\n","\n")
  7323. text = self:ConvertText(text,true) -- Tab Convert
  7324.  
  7325. local textLines = text:split("\n")
  7326. local insert = table.insert
  7327.  
  7328. for i = 1,#textLines do
  7329. local linePos = cursorY+i
  7330. if i > 1 then insert(lines,linePos,"") end
  7331.  
  7332. local textLine = textLines[i]
  7333. local newBefore = (i == 1 and before or "")
  7334. local newAfter = (i == #textLines and after or "")
  7335.  
  7336. lines[linePos] = newBefore..textLine..newAfter
  7337. end
  7338.  
  7339. if #textLines > 1 then cursorX = 0 end
  7340.  
  7341. self:ProcessTextChange()
  7342. self.CursorX = cursorX + #textLines[#textLines]
  7343. self.CursorY = cursorY + #textLines-1
  7344. self:UpdateCursor()
  7345. end
  7346.  
  7347. funcs.ScrollDelta = function(self,x,y)
  7348. self.ScrollV:ScrollTo(self.ScrollV.Index + y)
  7349. self.ScrollH:ScrollTo(self.ScrollH.Index + x)
  7350. end
  7351.  
  7352. -- x and y starts at 0
  7353. funcs.TabAdjust = function(self,x,y)
  7354. local lines = self.Lines
  7355. local line = lines[y+1]
  7356. x=x+1
  7357.  
  7358. if line then
  7359. local left = line:sub(x-1,x-1)
  7360. local middle = line:sub(x,x)
  7361. local right = line:sub(x+1,x+1)
  7362. local selRange = (#left > 0 and left or " ") .. (#middle > 0 and middle or " ") .. (#right > 0 and right or " ")
  7363.  
  7364. for i,v in pairs(tabJumps) do
  7365. if selRange:find(i) then
  7366. return v
  7367. end
  7368. end
  7369. end
  7370. return 0
  7371. end
  7372.  
  7373. funcs.SetEditing = function(self,on,input)
  7374. self:UpdateCursor(input)
  7375.  
  7376. if on then
  7377. if self.Editable then
  7378. self.GuiElems.EditBox.Text = ""
  7379. self.GuiElems.EditBox:CaptureFocus()
  7380. end
  7381. else
  7382. self.GuiElems.EditBox:ReleaseFocus()
  7383. end
  7384. end
  7385.  
  7386. funcs.CursorAnim = function(self,on)
  7387. local cursor = self.GuiElems.Cursor
  7388. local animTime = tick()
  7389. self.LastAnimTime = animTime
  7390.  
  7391. if not on then return end
  7392.  
  7393. lineTweens.Invis:Cancel()
  7394. lineTweens.Vis:Cancel()
  7395. cursor.BackgroundTransparency = 0
  7396.  
  7397. coroutine.wrap(function()
  7398. while self.Editable do
  7399. Lib.FastWait(0.5)
  7400. if self.LastAnimTime ~= animTime then return end
  7401. lineTweens.Invis:Play()
  7402. Lib.FastWait(0.4)
  7403. if self.LastAnimTime ~= animTime then return end
  7404. lineTweens.Vis:Play()
  7405. Lib.FastWait(0.2)
  7406. end
  7407. end)()
  7408. end
  7409.  
  7410. funcs.MoveCursor = function(self,x,y)
  7411. self.CursorX = x
  7412. self.CursorY = y
  7413. self:UpdateCursor()
  7414. self:JumpToCursor()
  7415. end
  7416.  
  7417. funcs.JumpToCursor = function(self)
  7418. self:Refresh()
  7419. end
  7420.  
  7421. funcs.UpdateCursor = function(self,input)
  7422. local linesFrame = self.GuiElems.LinesFrame
  7423. local cursor = self.GuiElems.Cursor
  7424. local hSize = math.max(0,linesFrame.AbsoluteSize.X)
  7425. local vSize = math.max(0,linesFrame.AbsoluteSize.Y)
  7426. local maxLines = math.ceil(vSize / self.FontSize)
  7427. local maxCols = math.ceil(hSize / math.ceil(self.FontSize/2))
  7428. local viewX,viewY = self.ViewX,self.ViewY
  7429. local totalLinesStr = tostring(#self.Lines)
  7430. local fontWidth = math.ceil(self.FontSize / 2)
  7431. local linesOffset = #totalLinesStr*fontWidth + 4*fontWidth
  7432.  
  7433. if input then
  7434. local linesFrame = self.GuiElems.LinesFrame
  7435. local frameX,frameY = linesFrame.AbsolutePosition.X,linesFrame.AbsolutePosition.Y
  7436. local mouseX,mouseY = input.Position.X,input.Position.Y
  7437. local fontSizeX,fontSizeY = math.ceil(self.FontSize/2),self.FontSize
  7438.  
  7439. self.CursorX = self.ViewX + math.round((mouseX - frameX) / fontSizeX)
  7440. self.CursorY = self.ViewY + math.floor((mouseY - frameY) / fontSizeY)
  7441. end
  7442.  
  7443. local cursorX,cursorY = self.CursorX,self.CursorY
  7444.  
  7445. local line = self.Lines[cursorY+1] or ""
  7446. if cursorX > #line then cursorX = #line
  7447. elseif cursorX < 0 then cursorX = 0 end
  7448.  
  7449. if cursorY >= #self.Lines then
  7450. cursorY = math.max(0,#self.Lines-1)
  7451. elseif cursorY < 0 then
  7452. cursorY = 0
  7453. end
  7454.  
  7455. cursorX = cursorX + self:TabAdjust(cursorX,cursorY)
  7456.  
  7457. -- Update modified
  7458. self.CursorX = cursorX
  7459. self.CursorY = cursorY
  7460.  
  7461. local cursorVisible = (cursorX >= viewX) and (cursorY >= viewY) and (cursorX <= viewX + maxCols) and (cursorY <= viewY + maxLines)
  7462. if cursorVisible then
  7463. local offX = (cursorX - viewX)
  7464. local offY = (cursorY - viewY)
  7465. cursor.Position = UDim2.new(0,linesOffset + offX*math.ceil(self.FontSize/2) - 1,0,offY*self.FontSize)
  7466. cursor.Size = UDim2.new(0,1,0,self.FontSize+2)
  7467. cursor.Visible = true
  7468. self:CursorAnim(true)
  7469. else
  7470. cursor.Visible = false
  7471. end
  7472. end
  7473.  
  7474. funcs.MapNewLines = function(self)
  7475. local newLines = {}
  7476. local count = 1
  7477. local text = self.Text
  7478. local find = string.find
  7479. local init = 1
  7480.  
  7481. local pos = find(text,"\n",init,true)
  7482. while pos do
  7483. newLines[count] = pos
  7484. count = count + 1
  7485. init = pos + 1
  7486. pos = find(text,"\n",init,true)
  7487. end
  7488.  
  7489. self.NewLines = newLines
  7490. end
  7491.  
  7492. funcs.PreHighlight = function(self)
  7493. local start = tick()
  7494. local text = self.Text:gsub("\\\\"," ")
  7495. --print("BACKSLASH SUB",tick()-start)
  7496. local textLen = #text
  7497. local found = {}
  7498. local foundMap = {}
  7499. local extras = {}
  7500. local find = string.find
  7501. local sub = string.sub
  7502. self.ColoredLines = {}
  7503.  
  7504. local function findAll(str,pattern,typ,raw)
  7505. local count = #found+1
  7506. local init = 1
  7507. local x,y,extra = find(str,pattern,init,raw)
  7508. while x do
  7509. found[count] = x
  7510. foundMap[x] = typ
  7511. if extra then
  7512. extras[x] = extra
  7513. end
  7514.  
  7515. count = count+1
  7516. init = y+1
  7517. x,y,extra = find(str,pattern,init,raw)
  7518. end
  7519. end
  7520. local start = tick()
  7521. findAll(text,'"',1,true)
  7522. findAll(text,"'",2,true)
  7523. findAll(text,"%[(=*)%[",3)
  7524. findAll(text,"--",4,true)
  7525. table.sort(found)
  7526.  
  7527. local newLines = self.NewLines
  7528. local curLine = 0
  7529. local lineTableCount = 1
  7530. local lineStart = 0
  7531. local lineEnd = 0
  7532. local lastEnding = 0
  7533. local foundHighlights = {}
  7534.  
  7535. for i = 1,#found do
  7536. local pos = found[i]
  7537. if pos <= lastEnding then continue end
  7538.  
  7539. local ending = pos
  7540. local typ = foundMap[pos]
  7541. if typ == 1 then
  7542. ending = find(text,'"',pos+1,true)
  7543. while ending and sub(text,ending-1,ending-1) == "\\" do
  7544. ending = find(text,'"',ending+1,true)
  7545. end
  7546. if not ending then ending = textLen end
  7547. elseif typ == 2 then
  7548. ending = find(text,"'",pos+1,true)
  7549. while ending and sub(text,ending-1,ending-1) == "\\" do
  7550. ending = find(text,"'",ending+1,true)
  7551. end
  7552. if not ending then ending = textLen end
  7553. elseif typ == 3 then
  7554. _,ending = find(text,"]"..extras[pos].."]",pos+1,true)
  7555. if not ending then ending = textLen end
  7556. elseif typ == 4 then
  7557. local ahead = foundMap[pos+2]
  7558.  
  7559. if ahead == 3 then
  7560. _,ending = find(text,"]"..extras[pos+2].."]",pos+1,true)
  7561. if not ending then ending = textLen end
  7562. else
  7563. ending = find(text,"\n",pos+1,true) or textLen
  7564. end
  7565. end
  7566.  
  7567. while pos > lineEnd do
  7568. curLine = curLine + 1
  7569. --lineTableCount = 1
  7570. lineEnd = newLines[curLine] or textLen+1
  7571. end
  7572. while true do
  7573. local lineTable = foundHighlights[curLine]
  7574. if not lineTable then lineTable = {} foundHighlights[curLine] = lineTable end
  7575. lineTable[pos] = {typ,ending}
  7576. --lineTableCount = lineTableCount + 1
  7577.  
  7578. if ending > lineEnd then
  7579. curLine = curLine + 1
  7580. lineEnd = newLines[curLine] or textLen+1
  7581. else
  7582. break
  7583. end
  7584. end
  7585.  
  7586. lastEnding = ending
  7587. --if i < 200 then print(curLine) end
  7588. end
  7589. self.PreHighlights = foundHighlights
  7590. --print(tick()-start)
  7591. --print(#found,curLine)
  7592. end
  7593.  
  7594. funcs.HighlightLine = function(self,line)
  7595. local cached = self.ColoredLines[line]
  7596. if cached then return cached end
  7597.  
  7598. local sub = string.sub
  7599. local find = string.find
  7600. local match = string.match
  7601. local highlights = {}
  7602. local preHighlights = self.PreHighlights[line] or {}
  7603. local lineText = self.Lines[line] or ""
  7604. local lineLen = #lineText
  7605. local lastEnding = 0
  7606. local currentType = 0
  7607. local lastWord = nil
  7608. local wordBeginsDotted = false
  7609. local funcStatus = 0
  7610. local lineStart = self.NewLines[line-1] or 0
  7611.  
  7612. local preHighlightMap = {}
  7613. for pos,data in next,preHighlights do
  7614. local relativePos = pos-lineStart
  7615. if relativePos < 1 then
  7616. currentType = data[1]
  7617. lastEnding = data[2] - lineStart
  7618. --warn(pos,data[2])
  7619. else
  7620. preHighlightMap[relativePos] = {data[1],data[2]-lineStart}
  7621. end
  7622. end
  7623.  
  7624. for col = 1,#lineText do
  7625. if col <= lastEnding then highlights[col] = currentType continue end
  7626.  
  7627. local pre = preHighlightMap[col]
  7628. if pre then
  7629. currentType = pre[1]
  7630. lastEnding = pre[2]
  7631. highlights[col] = currentType
  7632. wordBeginsDotted = false
  7633. lastWord = nil
  7634. funcStatus = 0
  7635. else
  7636. local char = sub(lineText,col,col)
  7637. if find(char,"[%a_]") then
  7638. local word = match(lineText,"[%a%d_]+",col)
  7639. local wordType = (keywords[word] and 7) or (builtIns[word] and 8)
  7640.  
  7641. lastEnding = col+#word-1
  7642.  
  7643. if wordType ~= 7 then
  7644. if wordBeginsDotted then
  7645. local prevBuiltIn = lastWord and builtIns[lastWord]
  7646. wordType = (prevBuiltIn and type(prevBuiltIn) == "table" and prevBuiltIn[word] and 8) or 10
  7647. end
  7648.  
  7649. if wordType ~= 8 then
  7650. local x,y,br = find(lineText,"^%s*([%({\"'])",lastEnding+1)
  7651. if x then
  7652. wordType = (funcStatus > 0 and br == "(" and 16) or 9
  7653. funcStatus = 0
  7654. end
  7655. end
  7656. else
  7657. wordType = specialKeywordsTypes[word] or wordType
  7658. funcStatus = (word == "function" and 1 or 0)
  7659. end
  7660.  
  7661. lastWord = word
  7662. wordBeginsDotted = false
  7663. if funcStatus > 0 then funcStatus = 1 end
  7664.  
  7665. if wordType then
  7666. currentType = wordType
  7667. highlights[col] = currentType
  7668. else
  7669. currentType = nil
  7670. end
  7671. elseif find(char,"%p") then
  7672. local isDot = (char == ".")
  7673. local isNum = isDot and find(sub(lineText,col+1,col+1),"%d")
  7674. highlights[col] = (isNum and 6 or 5)
  7675.  
  7676. if not isNum then
  7677. local dotStr = isDot and match(lineText,"%.%.?%.?",col)
  7678. if dotStr and #dotStr > 1 then
  7679. currentType = 5
  7680. lastEnding = col+#dotStr-1
  7681. wordBeginsDotted = false
  7682. lastWord = nil
  7683. funcStatus = 0
  7684. else
  7685. if isDot then
  7686. if wordBeginsDotted then
  7687. lastWord = nil
  7688. else
  7689. wordBeginsDotted = true
  7690. end
  7691. else
  7692. wordBeginsDotted = false
  7693. lastWord = nil
  7694. end
  7695.  
  7696. funcStatus = ((isDot or char == ":") and funcStatus == 1 and 2) or 0
  7697. end
  7698. end
  7699. elseif find(char,"%d") then
  7700. local _,endPos = find(lineText,"%x+",col)
  7701. local endPart = sub(lineText,endPos,endPos+1)
  7702. if (endPart == "e+" or endPart == "e-") and find(sub(lineText,endPos+2,endPos+2),"%d") then
  7703. endPos = endPos + 1
  7704. end
  7705. currentType = 6
  7706. lastEnding = endPos
  7707. highlights[col] = 6
  7708. wordBeginsDotted = false
  7709. lastWord = nil
  7710. funcStatus = 0
  7711. else
  7712. highlights[col] = currentType
  7713. local _,endPos = find(lineText,"%s+",col)
  7714. if endPos then
  7715. lastEnding = endPos
  7716. end
  7717. end
  7718. end
  7719. end
  7720.  
  7721. self.ColoredLines[line] = highlights
  7722. return highlights
  7723. end
  7724.  
  7725. funcs.Refresh = function(self)
  7726. local start = tick()
  7727.  
  7728. local linesFrame = self.Frame.Lines
  7729. local hSize = math.max(0,linesFrame.AbsoluteSize.X)
  7730. local vSize = math.max(0,linesFrame.AbsoluteSize.Y)
  7731. local maxLines = math.ceil(vSize / self.FontSize)
  7732. local maxCols = math.ceil(hSize / math.ceil(self.FontSize/2))
  7733. local gsub = string.gsub
  7734. local sub = string.sub
  7735.  
  7736. local viewX,viewY = self.ViewX,self.ViewY
  7737.  
  7738. local lineNumberStr = ""
  7739.  
  7740. for row = 1,maxLines do
  7741. local lineFrame = self.LineFrames[row]
  7742. if not lineFrame then
  7743. lineFrame = Instance.new("Frame")
  7744. lineFrame.Name = "Line"
  7745. lineFrame.Position = UDim2.new(0,0,0,(row-1)*self.FontSize)
  7746. lineFrame.Size = UDim2.new(1,0,0,self.FontSize)
  7747. lineFrame.BorderSizePixel = 0
  7748. lineFrame.BackgroundTransparency = 1
  7749.  
  7750. local selectionHighlight = Instance.new("Frame")
  7751. selectionHighlight.Name = "SelectionHighlight"
  7752. selectionHighlight.BorderSizePixel = 0
  7753. selectionHighlight.BackgroundColor3 = Settings.Theme.Syntax.SelectionBack
  7754. selectionHighlight.Parent = lineFrame
  7755.  
  7756. local label = Instance.new("TextLabel")
  7757. label.Name = "Label"
  7758. label.BackgroundTransparency = 1
  7759. label.Font = Enum.Font.Code
  7760. label.TextSize = self.FontSize
  7761. label.Size = UDim2.new(1,0,0,self.FontSize)
  7762. label.RichText = true
  7763. label.TextXAlignment = Enum.TextXAlignment.Left
  7764. label.TextColor3 = self.Colors.Text
  7765. label.ZIndex = 2
  7766. label.Parent = lineFrame
  7767.  
  7768. lineFrame.Parent = linesFrame
  7769. self.LineFrames[row] = lineFrame
  7770. end
  7771.  
  7772. local relaY = viewY + row
  7773. local lineText = self.Lines[relaY] or ""
  7774. local resText = ""
  7775. local highlights = self:HighlightLine(relaY)
  7776. local colStart = viewX + 1
  7777.  
  7778. local richTemplates = self.RichTemplates
  7779. local textTemplate = richTemplates.Text
  7780. local selectionTemplate = richTemplates.Selection
  7781. local curType = highlights[colStart]
  7782. local curTemplate = richTemplates[typeMap[curType]] or textTemplate
  7783.  
  7784. -- Selection Highlight
  7785. local selectionRange = self.SelectionRange
  7786. local selPos1 = selectionRange[1]
  7787. local selPos2 = selectionRange[2]
  7788. local selRow,selColumn = selPos1[2],selPos1[1]
  7789. local sel2Row,sel2Column = selPos2[2],selPos2[1]
  7790. local selRelaX,selRelaY = viewX,relaY-1
  7791.  
  7792. if selRelaY >= selPos1[2] and selRelaY <= selPos2[2] then
  7793. local fontSizeX = math.ceil(self.FontSize/2)
  7794. local posX = (selRelaY == selPos1[2] and selPos1[1] or 0) - viewX
  7795. local sizeX = (selRelaY == selPos2[2] and selPos2[1]-posX-viewX or maxCols+viewX)
  7796.  
  7797. lineFrame.SelectionHighlight.Position = UDim2.new(0,posX*fontSizeX,0,0)
  7798. lineFrame.SelectionHighlight.Size = UDim2.new(0,sizeX*fontSizeX,1,0)
  7799. lineFrame.SelectionHighlight.Visible = true
  7800. else
  7801. lineFrame.SelectionHighlight.Visible = false
  7802. end
  7803.  
  7804. -- Selection Text Color for first char
  7805. local inSelection = selRelaY >= selRow and selRelaY <= sel2Row and (selRelaY == selRow and viewX >= selColumn or selRelaY ~= selRow) and (selRelaY == sel2Row and viewX < sel2Column or selRelaY ~= sel2Row)
  7806. if inSelection then
  7807. curType = -999
  7808. curTemplate = selectionTemplate
  7809. end
  7810.  
  7811. for col = 2,maxCols do
  7812. local relaX = viewX + col
  7813. local selRelaX = relaX-1
  7814. local posType = highlights[relaX]
  7815.  
  7816. -- Selection Text Color
  7817. local inSelection = selRelaY >= selRow and selRelaY <= sel2Row and (selRelaY == selRow and selRelaX >= selColumn or selRelaY ~= selRow) and (selRelaY == sel2Row and selRelaX < sel2Column or selRelaY ~= sel2Row)
  7818. if inSelection then
  7819. posType = -999
  7820. end
  7821.  
  7822. if posType ~= curType then
  7823. local template = (inSelection and selectionTemplate) or richTemplates[typeMap[posType]] or textTemplate
  7824.  
  7825. if template ~= curTemplate then
  7826. local nextText = gsub(sub(lineText,colStart,relaX-1),"['\"<>&]",richReplace)
  7827. resText = resText .. (curTemplate ~= textTemplate and (curTemplate .. nextText .. "</font>") or nextText)
  7828. colStart = relaX
  7829. curTemplate = template
  7830. end
  7831. curType = posType
  7832. end
  7833. end
  7834.  
  7835. local lastText = gsub(sub(lineText,colStart,viewX+maxCols),"['\"<>&]",richReplace)
  7836. --warn("SUB",colStart,viewX+maxCols-1)
  7837. if #lastText > 0 then
  7838. resText = resText .. (curTemplate ~= textTemplate and (curTemplate .. lastText .. "</font>") or lastText)
  7839. end
  7840.  
  7841. if self.Lines[relaY] then
  7842. lineNumberStr = lineNumberStr .. (relaY == self.CursorY and ("<b>"..relaY.."</b>\n") or relaY .. "\n")
  7843. end
  7844.  
  7845. lineFrame.Label.Text = resText
  7846. end
  7847.  
  7848. for i = maxLines+1,#self.LineFrames do
  7849. self.LineFrames[i]:Destroy()
  7850. self.LineFrames[i] = nil
  7851. end
  7852.  
  7853. self.Frame.LineNumbers.Text = lineNumberStr
  7854. self:UpdateCursor()
  7855.  
  7856. --print("REFRESH TIME",tick()-start)
  7857. end
  7858.  
  7859. funcs.UpdateView = function(self)
  7860. local totalLinesStr = tostring(#self.Lines)
  7861. local fontWidth = math.ceil(self.FontSize / 2)
  7862. local linesOffset = #totalLinesStr*fontWidth + 4*fontWidth
  7863.  
  7864. local linesFrame = self.Frame.Lines
  7865. local hSize = linesFrame.AbsoluteSize.X
  7866. local vSize = linesFrame.AbsoluteSize.Y
  7867. local maxLines = math.ceil(vSize / self.FontSize)
  7868. local totalWidth = self.MaxTextCols*fontWidth
  7869. local scrollV = self.ScrollV
  7870. local scrollH = self.ScrollH
  7871.  
  7872. scrollV.VisibleSpace = maxLines
  7873. scrollV.TotalSpace = #self.Lines + 1
  7874. scrollH.VisibleSpace = math.ceil(hSize/fontWidth)
  7875. scrollH.TotalSpace = self.MaxTextCols + 1
  7876.  
  7877. scrollV.Gui.Visible = #self.Lines + 1 > maxLines
  7878. scrollH.Gui.Visible = totalWidth > hSize
  7879.  
  7880. local oldOffsets = self.FrameOffsets
  7881. self.FrameOffsets = Vector2.new(scrollV.Gui.Visible and -16 or 0, scrollH.Gui.Visible and -16 or 0)
  7882. if oldOffsets ~= self.FrameOffsets then
  7883. self:UpdateView()
  7884. else
  7885. scrollV:ScrollTo(self.ViewY,true)
  7886. scrollH:ScrollTo(self.ViewX,true)
  7887.  
  7888. if scrollV.Gui.Visible and scrollH.Gui.Visible then
  7889. scrollV.Gui.Size = UDim2.new(0,16,1,-16)
  7890. scrollH.Gui.Size = UDim2.new(1,-16,0,16)
  7891. self.GuiElems.ScrollCorner.Visible = true
  7892. else
  7893. scrollV.Gui.Size = UDim2.new(0,16,1,0)
  7894. scrollH.Gui.Size = UDim2.new(1,0,0,16)
  7895. self.GuiElems.ScrollCorner.Visible = false
  7896. end
  7897.  
  7898. self.ViewY = scrollV.Index
  7899. self.ViewX = scrollH.Index
  7900. self.Frame.Lines.Position = UDim2.new(0,linesOffset,0,0)
  7901. self.Frame.Lines.Size = UDim2.new(1,-linesOffset+oldOffsets.X,1,oldOffsets.Y)
  7902. self.Frame.LineNumbers.Position = UDim2.new(0,fontWidth,0,0)
  7903. self.Frame.LineNumbers.Size = UDim2.new(0,#totalLinesStr*fontWidth,1,oldOffsets.Y)
  7904. self.Frame.LineNumbers.TextSize = self.FontSize
  7905. end
  7906. end
  7907.  
  7908. funcs.ProcessTextChange = function(self)
  7909. local maxCols = 0
  7910. local lines = self.Lines
  7911.  
  7912. for i = 1,#lines do
  7913. local lineLen = #lines[i]
  7914. if lineLen > maxCols then
  7915. maxCols = lineLen
  7916. end
  7917. end
  7918.  
  7919. self.MaxTextCols = maxCols
  7920. self:UpdateView()
  7921. self.Text = table.concat(self.Lines,"\n")
  7922. self:MapNewLines()
  7923. self:PreHighlight()
  7924. self:Refresh()
  7925. --self.TextChanged:Fire()
  7926. end
  7927.  
  7928. funcs.ConvertText = function(self,text,toEditor)
  7929. if toEditor then
  7930. return text:gsub("\t",(" %s%s "):format(tabSub,tabSub))
  7931. else
  7932. return text:gsub((" %s%s "):format(tabSub,tabSub),"\t")
  7933. end
  7934. end
  7935.  
  7936. funcs.GetText = function(self) -- TODO: better (use new tab format)
  7937. local source = table.concat(self.Lines,"\n")
  7938. return self:ConvertText(source,false) -- Tab Convert
  7939. end
  7940.  
  7941. funcs.SetText = function(self,txt)
  7942. txt = self:ConvertText(txt,true) -- Tab Convert
  7943. local lines = self.Lines
  7944. table.clear(lines)
  7945. local count = 1
  7946.  
  7947. for line in txt:gmatch("([^\n\r]*)[\n\r]?") do
  7948. local len = #line
  7949. lines[count] = line
  7950. count = count + 1
  7951. end
  7952.  
  7953. self:ProcessTextChange()
  7954. end
  7955.  
  7956. funcs.MakeRichTemplates = function(self)
  7957. local floor = math.floor
  7958. local templates = {}
  7959.  
  7960. for name,color in pairs(self.Colors) do
  7961. templates[name] = ('<font color="rgb(%s,%s,%s)">'):format(floor(color.r*255),floor(color.g*255),floor(color.b*255))
  7962. end
  7963.  
  7964. self.RichTemplates = templates
  7965. end
  7966.  
  7967. funcs.ApplyTheme = function(self)
  7968. local colors = Settings.Theme.Syntax
  7969. self.Colors = colors
  7970. self.Frame.LineNumbers.TextColor3 = colors.Text
  7971. self.Frame.BackgroundColor3 = colors.Background
  7972. end
  7973.  
  7974. local mt = {__index = funcs}
  7975.  
  7976. local function new()
  7977. if not builtInInited then initBuiltIn() end
  7978.  
  7979. local scrollV = Lib.ScrollBar.new()
  7980. local scrollH = Lib.ScrollBar.new(true)
  7981. scrollH.Gui.Position = UDim2.new(0,0,1,-16)
  7982. local obj = setmetatable({
  7983. FontSize = 15,
  7984. ViewX = 0,
  7985. ViewY = 0,
  7986. Colors = Settings.Theme.Syntax,
  7987. ColoredLines = {},
  7988. Lines = {""},
  7989. LineFrames = {},
  7990. Editable = true,
  7991. Editing = false,
  7992. CursorX = 0,
  7993. CursorY = 0,
  7994. FloatCursorX = 0,
  7995. Text = "",
  7996. PreHighlights = {},
  7997. SelectionRange = {{-1,-1},{-1,-1}},
  7998. NewLines = {},
  7999. FrameOffsets = Vector2.new(0,0),
  8000. MaxTextCols = 0,
  8001. ScrollV = scrollV,
  8002. ScrollH = scrollH
  8003. },mt)
  8004.  
  8005. scrollV.WheelIncrement = 3
  8006. scrollH.Increment = 2
  8007. scrollH.WheelIncrement = 7
  8008.  
  8009. scrollV.Scrolled:Connect(function()
  8010. obj.ViewY = scrollV.Index
  8011. obj:Refresh()
  8012. end)
  8013.  
  8014. scrollH.Scrolled:Connect(function()
  8015. obj.ViewX = scrollH.Index
  8016. obj:Refresh()
  8017. end)
  8018.  
  8019. makeFrame(obj)
  8020. obj:MakeRichTemplates()
  8021. obj:ApplyTheme()
  8022. scrollV:SetScrollFrame(obj.Frame.Lines)
  8023. scrollV.Gui.Parent = obj.Frame
  8024. scrollH.Gui.Parent = obj.Frame
  8025.  
  8026. obj:UpdateView()
  8027. obj.Frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
  8028. obj:UpdateView()
  8029. obj:Refresh()
  8030. end)
  8031.  
  8032. return obj
  8033. end
  8034.  
  8035. return {new = new}
  8036. end)()
  8037.  
  8038. Lib.Checkbox = (function()
  8039. local funcs = {}
  8040. local c3 = Color3.fromRGB
  8041. local v2 = Vector2.new
  8042. local ud2s = UDim2.fromScale
  8043. local ud2o = UDim2.fromOffset
  8044. local ud = UDim.new
  8045. local max = math.max
  8046. local new = Instance.new
  8047. local TweenSize = new("Frame").TweenSize
  8048. local ti = TweenInfo.new
  8049. local delay = delay
  8050.  
  8051. local function ripple(object, color)
  8052. local circle = new('Frame')
  8053. circle.BackgroundColor3 = color
  8054. circle.BackgroundTransparency = 0.75
  8055. circle.BorderSizePixel = 0
  8056. circle.AnchorPoint = v2(0.5, 0.5)
  8057. circle.Size = ud2o()
  8058. circle.Position = ud2s(0.5, 0.5)
  8059. circle.Parent = object
  8060. local rounding = new('UICorner')
  8061. rounding.CornerRadius = ud(1)
  8062. rounding.Parent = circle
  8063.  
  8064. local abssz = object.AbsoluteSize
  8065. local size = max(abssz.X, abssz.Y) * 5/3
  8066.  
  8067. TweenSize(circle, ud2o(size, size), "Out", "Quart", 0.4)
  8068. service.TweenService:Create(circle, ti(0.4, Enum.EasingStyle.Quart, Enum.EasingDirection.In), {BackgroundTransparency = 1}):Play()
  8069.  
  8070. service.Debris:AddItem(circle, 0.4)
  8071. end
  8072.  
  8073. local function initGui(self,frame)
  8074. local checkbox = frame or create({
  8075. {1,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="Checkbox",Position=UDim2.new(0,3,0,3),Size=UDim2.new(0,16,0,16),}},
  8076. {2,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ripples",Parent={1},Size=UDim2.new(1,0,1,0),}},
  8077. {3,"Frame",{BackgroundColor3=Color3.new(0.10196078568697,0.10196078568697,0.10196078568697),BorderSizePixel=0,Name="outline",Parent={1},Size=UDim2.new(0,16,0,16),}},
  8078. {4,"Frame",{BackgroundColor3=Color3.new(0.14117647707462,0.14117647707462,0.14117647707462),BorderSizePixel=0,Name="filler",Parent={3},Position=UDim2.new(0,1,0,1),Size=UDim2.new(0,14,0,14),}},
  8079. {5,"Frame",{BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="top",Parent={4},Size=UDim2.new(0,16,0,0),}},
  8080. {6,"Frame",{AnchorPoint=Vector2.new(0,1),BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="bottom",Parent={4},Position=UDim2.new(0,0,0,14),Size=UDim2.new(0,16,0,0),}},
  8081. {7,"Frame",{BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="left",Parent={4},Size=UDim2.new(0,0,0,16),}},
  8082. {8,"Frame",{AnchorPoint=Vector2.new(1,0),BackgroundColor3=Color3.new(0.90196084976196,0.90196084976196,0.90196084976196),BorderSizePixel=0,Name="right",Parent={4},Position=UDim2.new(0,14,0,0),Size=UDim2.new(0,0,0,16),}},
  8083. {9,"Frame",{AnchorPoint=Vector2.new(0.5,0.5),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,ClipsDescendants=true,Name="checkmark",Parent={4},Position=UDim2.new(0.5,0,0.5,0),Size=UDim2.new(0,0,0,20),}},
  8084. {10,"ImageLabel",{AnchorPoint=Vector2.new(0.5,0.5),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Image="rbxassetid://6234266378",Parent={9},Position=UDim2.new(0.5,0,0.5,0),ScaleType=3,Size=UDim2.new(0,15,0,11),}},
  8085. {11,"ImageLabel",{AnchorPoint=Vector2.new(0.5,0.5),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6401617475",ImageColor3=Color3.new(0.20784313976765,0.69803923368454,0.98431372642517),Name="checkmark2",Parent={4},Position=UDim2.new(0.5,0,0.5,0),Size=UDim2.new(0,12,0,12),Visible=false,}},
  8086. {12,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6425281788",ImageTransparency=0.20000000298023,Name="middle",Parent={4},ScaleType=2,Size=UDim2.new(1,0,1,0),TileSize=UDim2.new(0,2,0,2),Visible=false,}},
  8087. {13,"UICorner",{CornerRadius=UDim.new(0,2),Parent={3},}},
  8088. })
  8089. local outline = checkbox.outline
  8090. local filler = outline.filler
  8091. local checkmark = filler.checkmark
  8092. local ripples_container = checkbox.ripples
  8093.  
  8094. -- walls
  8095. local top, bottom, left, right = filler.top, filler.bottom, filler.left, filler.right
  8096.  
  8097. self.Gui = checkbox
  8098. self.GuiElems = {
  8099. Top = top,
  8100. Bottom = bottom,
  8101. Left = left,
  8102. Right = right,
  8103. Outline = outline,
  8104. Filler = filler,
  8105. Checkmark = checkmark,
  8106. Checkmark2 = filler.checkmark2,
  8107. Middle = filler.middle
  8108. }
  8109.  
  8110. checkbox.InputBegan:Connect(function(i)
  8111. if i.UserInputType == Enum.UserInputType.MouseButton1 then
  8112. local release
  8113. release = service.UserInputService.InputEnded:Connect(function(input)
  8114. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  8115. release:Disconnect()
  8116.  
  8117. if Lib.CheckMouseInGui(checkbox) then
  8118. if self.Style == 0 then
  8119. ripple(ripples_container, self.Disabled and self.Colors.Disabled or self.Colors.Primary)
  8120. end
  8121.  
  8122. if not self.Disabled then
  8123. self:SetState(not self.Toggled,true)
  8124. else
  8125. self:Paint()
  8126. end
  8127.  
  8128. self.OnInput:Fire()
  8129. end
  8130. end
  8131. end)
  8132. end
  8133. end)
  8134.  
  8135. self:Paint()
  8136. end
  8137.  
  8138. funcs.Collapse = function(self,anim)
  8139. local guiElems = self.GuiElems
  8140. if anim then
  8141. TweenSize(guiElems.Top, ud2o(14, 14), "In", "Quart", 4/15, true)
  8142. TweenSize(guiElems.Bottom, ud2o(14, 14), "In", "Quart", 4/15, true)
  8143. TweenSize(guiElems.Left, ud2o(14, 14), "In", "Quart", 4/15, true)
  8144. TweenSize(guiElems.Right, ud2o(14, 14), "In", "Quart", 4/15, true)
  8145. else
  8146. guiElems.Top.Size = ud2o(14, 14)
  8147. guiElems.Bottom.Size = ud2o(14, 14)
  8148. guiElems.Left.Size = ud2o(14, 14)
  8149. guiElems.Right.Size = ud2o(14, 14)
  8150. end
  8151. end
  8152.  
  8153. funcs.Expand = function(self,anim)
  8154. local guiElems = self.GuiElems
  8155. if anim then
  8156. TweenSize(guiElems.Top, ud2o(14, 0), "InOut", "Quart", 4/15, true)
  8157. TweenSize(guiElems.Bottom, ud2o(14, 0), "InOut", "Quart", 4/15, true)
  8158. TweenSize(guiElems.Left, ud2o(0, 14), "InOut", "Quart", 4/15, true)
  8159. TweenSize(guiElems.Right, ud2o(0, 14), "InOut", "Quart", 4/15, true)
  8160. else
  8161. guiElems.Top.Size = ud2o(14, 0)
  8162. guiElems.Bottom.Size = ud2o(14, 0)
  8163. guiElems.Left.Size = ud2o(0, 14)
  8164. guiElems.Right.Size = ud2o(0, 14)
  8165. end
  8166. end
  8167.  
  8168. funcs.Paint = function(self)
  8169. local guiElems = self.GuiElems
  8170.  
  8171. if self.Style == 0 then
  8172. local color_base = self.Disabled and self.Colors.Disabled
  8173. guiElems.Outline.BackgroundColor3 = color_base or (self.Toggled and self.Colors.Primary) or self.Colors.Secondary
  8174. local walls_color = color_base or self.Colors.Primary
  8175. guiElems.Top.BackgroundColor3 = walls_color
  8176. guiElems.Bottom.BackgroundColor3 = walls_color
  8177. guiElems.Left.BackgroundColor3 = walls_color
  8178. guiElems.Right.BackgroundColor3 = walls_color
  8179. else
  8180. guiElems.Outline.BackgroundColor3 = self.Disabled and self.Colors.Disabled or self.Colors.Secondary
  8181. guiElems.Filler.BackgroundColor3 = self.Disabled and self.Colors.DisabledBackground or self.Colors.Background
  8182. guiElems.Checkmark2.ImageColor3 = self.Disabled and self.Colors.DisabledCheck or self.Colors.Primary
  8183. end
  8184. end
  8185.  
  8186. funcs.SetState = function(self,val,anim)
  8187. self.Toggled = val
  8188.  
  8189. if self.OutlineColorTween then self.OutlineColorTween:Cancel() end
  8190. local setStateTime = tick()
  8191. self.LastSetStateTime = setStateTime
  8192.  
  8193. if self.Toggled then
  8194. if self.Style == 0 then
  8195. if anim then
  8196. self.OutlineColorTween = service.TweenService:Create(self.GuiElems.Outline, ti(4/15, Enum.EasingStyle.Circular, Enum.EasingDirection.Out), {BackgroundColor3 = self.Colors.Primary})
  8197. self.OutlineColorTween:Play()
  8198. delay(0.15, function()
  8199. if setStateTime ~= self.LastSetStateTime then return end
  8200. self:Paint()
  8201. TweenSize(self.GuiElems.Checkmark, ud2o(14, 20), "Out", "Bounce", 2/15, true)
  8202. end)
  8203. else
  8204. self.GuiElems.Outline.BackgroundColor3 = self.Colors.Primary
  8205. self:Paint()
  8206. self.GuiElems.Checkmark.Size = ud2o(14, 20)
  8207. end
  8208. self:Collapse(anim)
  8209. else
  8210. self:Paint()
  8211. self.GuiElems.Checkmark2.Visible = true
  8212. self.GuiElems.Middle.Visible = false
  8213. end
  8214. else
  8215. if self.Style == 0 then
  8216. if anim then
  8217. self.OutlineColorTween = service.TweenService:Create(self.GuiElems.Outline, ti(4/15, Enum.EasingStyle.Circular, Enum.EasingDirection.In), {BackgroundColor3 = self.Colors.Secondary})
  8218. self.OutlineColorTween:Play()
  8219. delay(0.15, function()
  8220. if setStateTime ~= self.LastSetStateTime then return end
  8221. self:Paint()
  8222. TweenSize(self.GuiElems.Checkmark, ud2o(0, 20), "Out", "Quad", 1/15, true)
  8223. end)
  8224. else
  8225. self.GuiElems.Outline.BackgroundColor3 = self.Colors.Secondary
  8226. self:Paint()
  8227. self.GuiElems.Checkmark.Size = ud2o(0, 20)
  8228. end
  8229. self:Expand(anim)
  8230. else
  8231. self:Paint()
  8232. self.GuiElems.Checkmark2.Visible = false
  8233. self.GuiElems.Middle.Visible = self.Toggled == nil
  8234. end
  8235. end
  8236. end
  8237.  
  8238. local mt = {__index = funcs}
  8239.  
  8240. local function new(style)
  8241. local obj = setmetatable({
  8242. Toggled = false,
  8243. Disabled = false,
  8244. OnInput = Lib.Signal.new(),
  8245. Style = style or 0,
  8246. Colors = {
  8247. Background = c3(36,36,36),
  8248. Primary = c3(49,176,230),
  8249. Secondary = c3(25,25,25),
  8250. Disabled = c3(64,64,64),
  8251. DisabledBackground = c3(52,52,52),
  8252. DisabledCheck = c3(80,80,80)
  8253. }
  8254. },mt)
  8255. initGui(obj)
  8256. return obj
  8257. end
  8258.  
  8259. local function fromFrame(frame)
  8260. local obj = setmetatable({
  8261. Toggled = false,
  8262. Disabled = false,
  8263. Colors = {
  8264. Background = c3(36,36,36),
  8265. Primary = c3(49,176,230),
  8266. Secondary = c3(25,25,25),
  8267. Disabled = c3(64,64,64),
  8268. DisabledBackground = c3(52,52,52)
  8269. }
  8270. },mt)
  8271. initGui(obj,frame)
  8272. return obj
  8273. end
  8274.  
  8275. return {new = new, fromFrame}
  8276. end)()
  8277.  
  8278. Lib.BrickColorPicker = (function()
  8279. local funcs = {}
  8280. local paletteCount = 0
  8281. local mouse = service.Players.LocalPlayer:GetMouse()
  8282. local hexStartX = 4
  8283. local hexSizeX = 27
  8284. local hexTriangleStart = 1
  8285. local hexTriangleSize = 8
  8286.  
  8287. local bottomColors = {
  8288. Color3.fromRGB(17,17,17),
  8289. Color3.fromRGB(99,95,98),
  8290. Color3.fromRGB(163,162,165),
  8291. Color3.fromRGB(205,205,205),
  8292. Color3.fromRGB(223,223,222),
  8293. Color3.fromRGB(237,234,234),
  8294. Color3.fromRGB(27,42,53),
  8295. Color3.fromRGB(91,93,105),
  8296. Color3.fromRGB(159,161,172),
  8297. Color3.fromRGB(202,203,209),
  8298. Color3.fromRGB(231,231,236),
  8299. Color3.fromRGB(248,248,248)
  8300. }
  8301.  
  8302. local function isMouseInHexagon(hex)
  8303. local relativeX = mouse.X - hex.AbsolutePosition.X
  8304. local relativeY = mouse.Y - hex.AbsolutePosition.Y
  8305. if relativeX >= hexStartX and relativeX < hexStartX + hexSizeX then
  8306. relativeX = relativeX - 4
  8307. local relativeWidth = (13-math.min(relativeX,26 - relativeX))/13
  8308. if relativeY >= hexTriangleStart + hexTriangleSize*relativeWidth and relativeY < hex.AbsoluteSize.Y - hexTriangleStart - hexTriangleSize*relativeWidth then
  8309. return true
  8310. end
  8311. end
  8312.  
  8313. return false
  8314. end
  8315.  
  8316. local function hexInput(self,hex,color)
  8317. hex.InputBegan:Connect(function(input)
  8318. if input.UserInputType == Enum.UserInputType.MouseButton1 and isMouseInHexagon(hex) then
  8319. self.OnSelect:Fire(color)
  8320. self:Close()
  8321. end
  8322. end)
  8323.  
  8324. hex.InputChanged:Connect(function(input)
  8325. if input.UserInputType == Enum.UserInputType.MouseMovement and isMouseInHexagon(hex) then
  8326. self.OnPreview:Fire(color)
  8327. end
  8328. end)
  8329. end
  8330.  
  8331. local function createGui(self)
  8332. local gui = create({
  8333. {1,"ScreenGui",{Name="BrickColor",}},
  8334. {2,"Frame",{Active=true,BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),Parent={1},Position=UDim2.new(0.40000000596046,0,0.40000000596046,0),Size=UDim2.new(0,337,0,380),}},
  8335. {3,"TextButton",{BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,Font=3,Name="MoreColors",Parent={2},Position=UDim2.new(0,5,1,-30),Size=UDim2.new(1,-10,0,25),Text="More Colors",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  8336. {4,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Image="rbxassetid://1281023007",ImageColor3=Color3.new(0.33333334326744,0.33333334326744,0.49803924560547),Name="Hex",Parent={2},Size=UDim2.new(0,35,0,35),Visible=false,}},
  8337. })
  8338. local colorFrame = gui.Frame
  8339. local hex = colorFrame.Hex
  8340.  
  8341. for row = 1,13 do
  8342. local columns = math.min(row,14-row)+6
  8343. for column = 1,columns do
  8344. local nextColor = BrickColor.palette(paletteCount).Color
  8345. local newHex = hex:Clone()
  8346. newHex.Position = UDim2.new(0, (column-1)*25-(columns-7)*13+3*26 + 1, 0, (row-1)*23 + 4)
  8347. newHex.ImageColor3 = nextColor
  8348. newHex.Visible = true
  8349. hexInput(self,newHex,nextColor)
  8350. newHex.Parent = colorFrame
  8351. paletteCount = paletteCount + 1
  8352. end
  8353. end
  8354.  
  8355. for column = 1,12 do
  8356. local nextColor = bottomColors[column]
  8357. local newHex = hex:Clone()
  8358. newHex.Position = UDim2.new(0, (column-1)*25-(12-7)*13+3*26 + 3, 0, 308)
  8359. newHex.ImageColor3 = nextColor
  8360. newHex.Visible = true
  8361. hexInput(self,newHex,nextColor)
  8362. newHex.Parent = colorFrame
  8363. paletteCount = paletteCount + 1
  8364. end
  8365.  
  8366. colorFrame.MoreColors.MouseButton1Click:Connect(function()
  8367. self.OnMoreColors:Fire()
  8368. self:Close()
  8369. end)
  8370.  
  8371. self.Gui = gui
  8372. end
  8373.  
  8374. funcs.SetMoreColorsVisible = function(self,vis)
  8375. local colorFrame = self.Gui.Frame
  8376. colorFrame.Size = UDim2.new(0,337,0,380 - (not vis and 33 or 0))
  8377. colorFrame.MoreColors.Visible = vis
  8378. end
  8379.  
  8380. funcs.Show = function(self,x,y,prevColor)
  8381. self.PrevColor = prevColor or self.PrevColor
  8382.  
  8383. local reverseY = false
  8384.  
  8385. local x,y = x or mouse.X, y or mouse.Y
  8386. local maxX,maxY = mouse.ViewSizeX,mouse.ViewSizeY
  8387. Lib.ShowGui(self.Gui)
  8388. local sizeX,sizeY = self.Gui.Frame.AbsoluteSize.X,self.Gui.Frame.AbsoluteSize.Y
  8389.  
  8390. if x + sizeX > maxX then x = self.ReverseX and x - sizeX or maxX - sizeX end
  8391. if y + sizeY > maxY then reverseY = true end
  8392.  
  8393. local closable = false
  8394. if self.CloseEvent then self.CloseEvent:Disconnect() end
  8395. self.CloseEvent = service.UserInputService.InputBegan:Connect(function(input)
  8396. if not closable or input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  8397.  
  8398. if not Lib.CheckMouseInGui(self.Gui.Frame) then
  8399. self.CloseEvent:Disconnect()
  8400. self:Close()
  8401. end
  8402. end)
  8403.  
  8404. if reverseY then
  8405. local newY = y - sizeY - (self.ReverseYOffset or 0)
  8406. y = newY >= 0 and newY or 0
  8407. end
  8408.  
  8409. self.Gui.Frame.Position = UDim2.new(0,x,0,y)
  8410.  
  8411. Lib.FastWait()
  8412. closable = true
  8413. end
  8414.  
  8415. funcs.Close = function(self)
  8416. self.Gui.Parent = nil
  8417. self.OnCancel:Fire()
  8418. end
  8419.  
  8420. local mt = {__index = funcs}
  8421.  
  8422. local function new()
  8423. local obj = setmetatable({
  8424. OnPreview = Lib.Signal.new(),
  8425. OnSelect = Lib.Signal.new(),
  8426. OnCancel = Lib.Signal.new(),
  8427. OnMoreColors = Lib.Signal.new(),
  8428. PrevColor = Color3.new(0,0,0)
  8429. },mt)
  8430. createGui(obj)
  8431. return obj
  8432. end
  8433.  
  8434. return {new = new}
  8435. end)()
  8436.  
  8437. Lib.ColorPicker = (function() -- TODO: Convert to newer class model
  8438. local funcs = {}
  8439.  
  8440. local function new()
  8441. local newMt = setmetatable({},{})
  8442.  
  8443. newMt.OnSelect = Lib.Signal.new()
  8444. newMt.OnCancel = Lib.Signal.new()
  8445. newMt.OnPreview = Lib.Signal.new()
  8446.  
  8447. local guiContents = create({
  8448. {1,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,ClipsDescendants=true,Name="Content",Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,1,-20),}},
  8449. {2,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="BasicColors",Parent={1},Position=UDim2.new(0,5,0,5),Size=UDim2.new(0,180,0,200),}},
  8450. {3,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={2},Position=UDim2.new(0,0,0,-5),Size=UDim2.new(1,0,0,26),Text="Basic Colors",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8451. {4,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Blue",Parent={1},Position=UDim2.new(1,-63,0,255),Size=UDim2.new(0,52,0,16),}},
  8452. {5,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={4},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8453. {6,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={5},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  8454. {7,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={6},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8455. {8,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={7},Size=UDim2.new(0,16,0,8),}},
  8456. {9,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={8},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  8457. {10,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={8},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8458. {11,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={8},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  8459. {12,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={6},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8460. {13,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={12},Size=UDim2.new(0,16,0,8),}},
  8461. {14,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={13},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  8462. {15,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={13},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8463. {16,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={13},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  8464. {17,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={4},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Blue:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  8465. {18,"Frame",{BackgroundColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,ClipsDescendants=true,Name="ColorSpaceFrame",Parent={1},Position=UDim2.new(1,-261,0,4),Size=UDim2.new(0,222,0,202),}},
  8466. {19,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),BorderSizePixel=0,Image="rbxassetid://1072518406",Name="ColorSpace",Parent={18},Position=UDim2.new(0,1,0,1),Size=UDim2.new(0,220,0,200),}},
  8467. {20,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="Scope",Parent={19},Position=UDim2.new(0,210,0,190),Size=UDim2.new(0,20,0,20),}},
  8468. {21,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Name="Line",Parent={20},Position=UDim2.new(0,9,0,0),Size=UDim2.new(0,2,0,20),}},
  8469. {22,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Name="Line",Parent={20},Position=UDim2.new(0,0,0,9),Size=UDim2.new(0,20,0,2),}},
  8470. {23,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="CustomColors",Parent={1},Position=UDim2.new(0,5,0,210),Size=UDim2.new(0,180,0,90),}},
  8471. {24,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={23},Size=UDim2.new(1,0,0,20),Text="Custom Colors (RC = Set)",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8472. {25,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Green",Parent={1},Position=UDim2.new(1,-63,0,233),Size=UDim2.new(0,52,0,16),}},
  8473. {26,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={25},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8474. {27,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={26},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  8475. {28,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={27},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8476. {29,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={28},Size=UDim2.new(0,16,0,8),}},
  8477. {30,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={29},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  8478. {31,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={29},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8479. {32,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={29},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  8480. {33,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={27},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8481. {34,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={33},Size=UDim2.new(0,16,0,8),}},
  8482. {35,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={34},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  8483. {36,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={34},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8484. {37,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={34},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  8485. {38,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={25},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Green:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  8486. {39,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Hue",Parent={1},Position=UDim2.new(1,-180,0,211),Size=UDim2.new(0,52,0,16),}},
  8487. {40,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={39},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8488. {41,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={40},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  8489. {42,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={41},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8490. {43,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={42},Size=UDim2.new(0,16,0,8),}},
  8491. {44,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={43},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  8492. {45,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={43},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8493. {46,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={43},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  8494. {47,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={41},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8495. {48,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={47},Size=UDim2.new(0,16,0,8),}},
  8496. {49,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={48},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  8497. {50,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={48},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8498. {51,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={48},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  8499. {52,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={39},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Hue:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  8500. {53,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Name="Preview",Parent={1},Position=UDim2.new(1,-260,0,211),Size=UDim2.new(0,35,1,-245),}},
  8501. {54,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Red",Parent={1},Position=UDim2.new(1,-63,0,211),Size=UDim2.new(0,52,0,16),}},
  8502. {55,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={54},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8503. {56,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={55},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  8504. {57,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={56},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8505. {58,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={57},Size=UDim2.new(0,16,0,8),}},
  8506. {59,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={58},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  8507. {60,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={58},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8508. {61,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={58},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  8509. {62,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={56},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8510. {63,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={62},Size=UDim2.new(0,16,0,8),}},
  8511. {64,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={63},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  8512. {65,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={63},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8513. {66,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={63},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  8514. {67,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={54},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Red:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  8515. {68,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Sat",Parent={1},Position=UDim2.new(1,-180,0,233),Size=UDim2.new(0,52,0,16),}},
  8516. {69,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={68},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8517. {70,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={69},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  8518. {71,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={70},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8519. {72,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={71},Size=UDim2.new(0,16,0,8),}},
  8520. {73,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={72},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  8521. {74,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={72},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8522. {75,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={72},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  8523. {76,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={70},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8524. {77,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={76},Size=UDim2.new(0,16,0,8),}},
  8525. {78,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={77},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  8526. {79,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={77},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8527. {80,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={77},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  8528. {81,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={68},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Sat:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  8529. {82,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Val",Parent={1},Position=UDim2.new(1,-180,0,255),Size=UDim2.new(0,52,0,16),}},
  8530. {83,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Font=3,Name="Input",Parent={82},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,50,0,16),Text="255",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8531. {84,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={83},Position=UDim2.new(1,-16,0,0),Size=UDim2.new(0,16,1,0),}},
  8532. {85,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Up",Parent={84},Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8533. {86,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={85},Size=UDim2.new(0,16,0,8),}},
  8534. {87,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={86},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,1),}},
  8535. {88,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={86},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8536. {89,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={86},Position=UDim2.new(0,6,0,5),Size=UDim2.new(0,5,0,1),}},
  8537. {90,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="Down",Parent={84},Position=UDim2.new(0,0,0,8),Size=UDim2.new(1,0,0,8),Text="",TextSize=14,}},
  8538. {91,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={90},Size=UDim2.new(0,16,0,8),}},
  8539. {92,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={91},Position=UDim2.new(0,8,0,5),Size=UDim2.new(0,1,0,1),}},
  8540. {93,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={91},Position=UDim2.new(0,7,0,4),Size=UDim2.new(0,3,0,1),}},
  8541. {94,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={91},Position=UDim2.new(0,6,0,3),Size=UDim2.new(0,5,0,1),}},
  8542. {95,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={82},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Val:",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  8543. {96,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Cancel",Parent={1},Position=UDim2.new(1,-105,1,-28),Size=UDim2.new(0,100,0,25),Text="Cancel",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  8544. {97,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Ok",Parent={1},Position=UDim2.new(1,-210,1,-28),Size=UDim2.new(0,100,0,25),Text="OK",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  8545. {98,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Image="rbxassetid://1072518502",Name="ColorStrip",Parent={1},Position=UDim2.new(1,-30,0,5),Size=UDim2.new(0,13,0,200),}},
  8546. {99,"Frame",{BackgroundColor3=Color3.new(0.3137255012989,0.3137255012989,0.3137255012989),BackgroundTransparency=1,BorderSizePixel=0,Name="ArrowFrame",Parent={1},Position=UDim2.new(1,-16,0,1),Size=UDim2.new(0,5,0,208),}},
  8547. {100,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={99},Position=UDim2.new(0,-2,0,-4),Size=UDim2.new(0,8,0,16),}},
  8548. {101,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,2,0,8),Size=UDim2.new(0,1,0,1),}},
  8549. {102,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,3,0,7),Size=UDim2.new(0,1,0,3),}},
  8550. {103,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,4,0,6),Size=UDim2.new(0,1,0,5),}},
  8551. {104,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,5,0,5),Size=UDim2.new(0,1,0,7),}},
  8552. {105,"Frame",{BackgroundColor3=Color3.new(0,0,0),BorderSizePixel=0,Parent={100},Position=UDim2.new(0,6,0,4),Size=UDim2.new(0,1,0,9),}},
  8553. })
  8554. local window = Lib.Window.new()
  8555. window.Resizable = false
  8556. window.Alignable = false
  8557. window:SetTitle("Color Picker")
  8558. window:Resize(450,330)
  8559. for i,v in pairs(guiContents:GetChildren()) do
  8560. v.Parent = window.GuiElems.Content
  8561. end
  8562. newMt.Window = window
  8563. newMt.Gui = window.Gui
  8564. local pickerGui = window.Gui.Main
  8565. local pickerTopBar = pickerGui.TopBar
  8566. local pickerFrame = pickerGui.Content
  8567. local colorSpace = pickerFrame.ColorSpaceFrame.ColorSpace
  8568. local colorStrip = pickerFrame.ColorStrip
  8569. local previewFrame = pickerFrame.Preview
  8570. local basicColorsFrame = pickerFrame.BasicColors
  8571. local customColorsFrame = pickerFrame.CustomColors
  8572. local okButton = pickerFrame.Ok
  8573. local cancelButton = pickerFrame.Cancel
  8574. local closeButton = pickerTopBar.Close
  8575.  
  8576. local colorScope = colorSpace.Scope
  8577. local colorArrow = pickerFrame.ArrowFrame.Arrow
  8578.  
  8579. local hueInput = pickerFrame.Hue.Input
  8580. local satInput = pickerFrame.Sat.Input
  8581. local valInput = pickerFrame.Val.Input
  8582.  
  8583. local redInput = pickerFrame.Red.Input
  8584. local greenInput = pickerFrame.Green.Input
  8585. local blueInput = pickerFrame.Blue.Input
  8586.  
  8587. local user = clonerefs(game:GetService("UserInputService"))
  8588. local mouse = clonerefs(game:GetService("Players")).LocalPlayer:GetMouse()
  8589.  
  8590. local hue,sat,val = 0,0,1
  8591. local red,green,blue = 1,1,1
  8592. local chosenColor = Color3.new(0,0,0)
  8593.  
  8594. local basicColors = {Color3.new(0,0,0),Color3.new(0.66666668653488,0,0),Color3.new(0,0.33333334326744,0),Color3.new(0.66666668653488,0.33333334326744,0),Color3.new(0,0.66666668653488,0),Color3.new(0.66666668653488,0.66666668653488,0),Color3.new(0,1,0),Color3.new(0.66666668653488,1,0),Color3.new(0,0,0.49803924560547),Color3.new(0.66666668653488,0,0.49803924560547),Color3.new(0,0.33333334326744,0.49803924560547),Color3.new(0.66666668653488,0.33333334326744,0.49803924560547),Color3.new(0,0.66666668653488,0.49803924560547),Color3.new(0.66666668653488,0.66666668653488,0.49803924560547),Color3.new(0,1,0.49803924560547),Color3.new(0.66666668653488,1,0.49803924560547),Color3.new(0,0,1),Color3.new(0.66666668653488,0,1),Color3.new(0,0.33333334326744,1),Color3.new(0.66666668653488,0.33333334326744,1),Color3.new(0,0.66666668653488,1),Color3.new(0.66666668653488,0.66666668653488,1),Color3.new(0,1,1),Color3.new(0.66666668653488,1,1),Color3.new(0.33333334326744,0,0),Color3.new(1,0,0),Color3.new(0.33333334326744,0.33333334326744,0),Color3.new(1,0.33333334326744,0),Color3.new(0.33333334326744,0.66666668653488,0),Color3.new(1,0.66666668653488,0),Color3.new(0.33333334326744,1,0),Color3.new(1,1,0),Color3.new(0.33333334326744,0,0.49803924560547),Color3.new(1,0,0.49803924560547),Color3.new(0.33333334326744,0.33333334326744,0.49803924560547),Color3.new(1,0.33333334326744,0.49803924560547),Color3.new(0.33333334326744,0.66666668653488,0.49803924560547),Color3.new(1,0.66666668653488,0.49803924560547),Color3.new(0.33333334326744,1,0.49803924560547),Color3.new(1,1,0.49803924560547),Color3.new(0.33333334326744,0,1),Color3.new(1,0,1),Color3.new(0.33333334326744,0.33333334326744,1),Color3.new(1,0.33333334326744,1),Color3.new(0.33333334326744,0.66666668653488,1),Color3.new(1,0.66666668653488,1),Color3.new(0.33333334326744,1,1),Color3.new(1,1,1)}
  8595. local customColors = {}
  8596.  
  8597. local function updateColor(noupdate)
  8598. local relativeX,relativeY,relativeStripY = 219 - hue*219, 199 - sat*199, 199 - val*199
  8599. local hsvColor = Color3.fromHSV(hue,sat,val)
  8600.  
  8601. if noupdate == 2 or not noupdate then
  8602. hueInput.Text = tostring(math.ceil(359*hue))
  8603. satInput.Text = tostring(math.ceil(255*sat))
  8604. valInput.Text = tostring(math.floor(255*val))
  8605. end
  8606. if noupdate == 1 or not noupdate then
  8607. redInput.Text = tostring(math.floor(255*red))
  8608. greenInput.Text = tostring(math.floor(255*green))
  8609. blueInput.Text = tostring(math.floor(255*blue))
  8610. end
  8611.  
  8612. chosenColor = Color3.new(red,green,blue)
  8613.  
  8614. colorScope.Position = UDim2.new(0,relativeX-9,0,relativeY-9)
  8615. colorStrip.ImageColor3 = Color3.fromHSV(hue,sat,1)
  8616. colorArrow.Position = UDim2.new(0,-2,0,relativeStripY-4)
  8617. previewFrame.BackgroundColor3 = chosenColor
  8618.  
  8619. newMt.Color = chosenColor
  8620. newMt.OnPreview:Fire(chosenColor)
  8621. end
  8622.  
  8623. local function colorSpaceInput()
  8624. local relativeX = mouse.X - colorSpace.AbsolutePosition.X
  8625. local relativeY = mouse.Y - colorSpace.AbsolutePosition.Y
  8626.  
  8627. if relativeX < 0 then relativeX = 0 elseif relativeX > 219 then relativeX = 219 end
  8628. if relativeY < 0 then relativeY = 0 elseif relativeY > 199 then relativeY = 199 end
  8629.  
  8630. hue = (219 - relativeX)/219
  8631. sat = (199 - relativeY)/199
  8632.  
  8633. local hsvColor = Color3.fromHSV(hue,sat,val)
  8634. red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  8635.  
  8636. updateColor()
  8637. end
  8638.  
  8639. local function colorStripInput()
  8640. local relativeY = mouse.Y - colorStrip.AbsolutePosition.Y
  8641.  
  8642. if relativeY < 0 then relativeY = 0 elseif relativeY > 199 then relativeY = 199 end
  8643.  
  8644. val = (199 - relativeY)/199
  8645.  
  8646. local hsvColor = Color3.fromHSV(hue,sat,val)
  8647. red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  8648.  
  8649. updateColor()
  8650. end
  8651.  
  8652. local function hookButtons(frame,func)
  8653. frame.ArrowFrame.Up.InputBegan:Connect(function(input)
  8654. if input.UserInputType == Enum.UserInputType.MouseMovement then
  8655. frame.ArrowFrame.Up.BackgroundTransparency = 0.5
  8656. elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  8657. local releaseEvent,runEvent
  8658.  
  8659. local startTime = tick()
  8660. local pressing = true
  8661. local startNum = tonumber(frame.Text)
  8662.  
  8663. if not startNum then return end
  8664.  
  8665. releaseEvent = user.InputEnded:Connect(function(input)
  8666. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  8667. releaseEvent:Disconnect()
  8668. pressing = false
  8669. end)
  8670.  
  8671. startNum = startNum + 1
  8672. func(startNum)
  8673. while pressing do
  8674. if tick()-startTime > 0.3 then
  8675. startNum = startNum + 1
  8676. func(startNum)
  8677. end
  8678. wait(0.1)
  8679. end
  8680. end
  8681. end)
  8682.  
  8683. frame.ArrowFrame.Up.InputEnded:Connect(function(input)
  8684. if input.UserInputType == Enum.UserInputType.MouseMovement then
  8685. frame.ArrowFrame.Up.BackgroundTransparency = 1
  8686. end
  8687. end)
  8688.  
  8689. frame.ArrowFrame.Down.InputBegan:Connect(function(input)
  8690. if input.UserInputType == Enum.UserInputType.MouseMovement then
  8691. frame.ArrowFrame.Down.BackgroundTransparency = 0.5
  8692. elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
  8693. local releaseEvent,runEvent
  8694.  
  8695. local startTime = tick()
  8696. local pressing = true
  8697. local startNum = tonumber(frame.Text)
  8698.  
  8699. if not startNum then return end
  8700.  
  8701. releaseEvent = user.InputEnded:Connect(function(input)
  8702. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  8703. releaseEvent:Disconnect()
  8704. pressing = false
  8705. end)
  8706.  
  8707. startNum = startNum - 1
  8708. func(startNum)
  8709. while pressing do
  8710. if tick()-startTime > 0.3 then
  8711. startNum = startNum - 1
  8712. func(startNum)
  8713. end
  8714. wait(0.1)
  8715. end
  8716. end
  8717. end)
  8718.  
  8719. frame.ArrowFrame.Down.InputEnded:Connect(function(input)
  8720. if input.UserInputType == Enum.UserInputType.MouseMovement then
  8721. frame.ArrowFrame.Down.BackgroundTransparency = 1
  8722. end
  8723. end)
  8724. end
  8725.  
  8726. colorSpace.InputBegan:Connect(function(input)
  8727. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  8728. local releaseEvent,mouseEvent
  8729.  
  8730. releaseEvent = user.InputEnded:Connect(function(input)
  8731. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  8732. releaseEvent:Disconnect()
  8733. mouseEvent:Disconnect()
  8734. end)
  8735.  
  8736. mouseEvent = user.InputChanged:Connect(function(input)
  8737. if input.UserInputType == Enum.UserInputType.MouseMovement then
  8738. colorSpaceInput()
  8739. end
  8740. end)
  8741.  
  8742. colorSpaceInput()
  8743. end
  8744. end)
  8745.  
  8746. colorStrip.InputBegan:Connect(function(input)
  8747. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  8748. local releaseEvent,mouseEvent
  8749.  
  8750. releaseEvent = user.InputEnded:Connect(function(input)
  8751. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  8752. releaseEvent:Disconnect()
  8753. mouseEvent:Disconnect()
  8754. end)
  8755.  
  8756. mouseEvent = user.InputChanged:Connect(function(input)
  8757. if input.UserInputType == Enum.UserInputType.MouseMovement then
  8758. colorStripInput()
  8759. end
  8760. end)
  8761.  
  8762. colorStripInput()
  8763. end
  8764. end)
  8765.  
  8766. local function updateHue(str)
  8767. local num = tonumber(str)
  8768. if num then
  8769. hue = math.clamp(math.floor(num),0,359)/359
  8770. local hsvColor = Color3.fromHSV(hue,sat,val)
  8771. red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  8772. hueInput.Text = tostring(hue*359)
  8773. updateColor(1)
  8774. end
  8775. end
  8776. hueInput.FocusLost:Connect(function() updateHue(hueInput.Text) end) hookButtons(hueInput,updateHue)
  8777.  
  8778. local function updateSat(str)
  8779. local num = tonumber(str)
  8780. if num then
  8781. sat = math.clamp(math.floor(num),0,255)/255
  8782. local hsvColor = Color3.fromHSV(hue,sat,val)
  8783. red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  8784. satInput.Text = tostring(sat*255)
  8785. updateColor(1)
  8786. end
  8787. end
  8788. satInput.FocusLost:Connect(function() updateSat(satInput.Text) end) hookButtons(satInput,updateSat)
  8789.  
  8790. local function updateVal(str)
  8791. local num = tonumber(str)
  8792. if num then
  8793. val = math.clamp(math.floor(num),0,255)/255
  8794. local hsvColor = Color3.fromHSV(hue,sat,val)
  8795. red,green,blue = hsvColor.r,hsvColor.g,hsvColor.b
  8796. valInput.Text = tostring(val*255)
  8797. updateColor(1)
  8798. end
  8799. end
  8800. valInput.FocusLost:Connect(function() updateVal(valInput.Text) end) hookButtons(valInput,updateVal)
  8801.  
  8802. local function updateRed(str)
  8803. local num = tonumber(str)
  8804. if num then
  8805. red = math.clamp(math.floor(num),0,255)/255
  8806. local newColor = Color3.new(red,green,blue)
  8807. hue,sat,val = Color3.toHSV(newColor)
  8808. redInput.Text = tostring(red*255)
  8809. updateColor(2)
  8810. end
  8811. end
  8812. redInput.FocusLost:Connect(function() updateRed(redInput.Text) end) hookButtons(redInput,updateRed)
  8813.  
  8814. local function updateGreen(str)
  8815. local num = tonumber(str)
  8816. if num then
  8817. green = math.clamp(math.floor(num),0,255)/255
  8818. local newColor = Color3.new(red,green,blue)
  8819. hue,sat,val = Color3.toHSV(newColor)
  8820. greenInput.Text = tostring(green*255)
  8821. updateColor(2)
  8822. end
  8823. end
  8824. greenInput.FocusLost:Connect(function() updateGreen(greenInput.Text) end) hookButtons(greenInput,updateGreen)
  8825.  
  8826. local function updateBlue(str)
  8827. local num = tonumber(str)
  8828. if num then
  8829. blue = math.clamp(math.floor(num),0,255)/255
  8830. local newColor = Color3.new(red,green,blue)
  8831. hue,sat,val = Color3.toHSV(newColor)
  8832. blueInput.Text = tostring(blue*255)
  8833. updateColor(2)
  8834. end
  8835. end
  8836. blueInput.FocusLost:Connect(function() updateBlue(blueInput.Text) end) hookButtons(blueInput,updateBlue)
  8837.  
  8838. local colorChoice = Instance.new("TextButton")
  8839. colorChoice.Name = "Choice"
  8840. colorChoice.Size = UDim2.new(0,25,0,18)
  8841. colorChoice.BorderColor3 = Color3.fromRGB(55,55,55)
  8842. colorChoice.Text = ""
  8843. colorChoice.AutoButtonColor = false
  8844.  
  8845. local row = 0
  8846. local column = 0
  8847. for i,v in pairs(basicColors) do
  8848. local newColor = colorChoice:Clone()
  8849. newColor.BackgroundColor3 = v
  8850. newColor.Position = UDim2.new(0,1 + 30*column,0,21 + 23*row)
  8851.  
  8852. newColor.MouseButton1Click:Connect(function()
  8853. red,green,blue = v.r,v.g,v.b
  8854. local newColor = Color3.new(red,green,blue)
  8855. hue,sat,val = Color3.toHSV(newColor)
  8856. updateColor()
  8857. end)
  8858.  
  8859. newColor.Parent = basicColorsFrame
  8860. column = column + 1
  8861. if column == 6 then row = row + 1 column = 0 end
  8862. end
  8863.  
  8864. row = 0
  8865. column = 0
  8866. for i = 1,12 do
  8867. local color = customColors[i] or Color3.new(0,0,0)
  8868. local newColor = colorChoice:Clone()
  8869. newColor.BackgroundColor3 = color
  8870. newColor.Position = UDim2.new(0,1 + 30*column,0,20 + 23*row)
  8871.  
  8872. newColor.MouseButton1Click:Connect(function()
  8873. local curColor = customColors[i] or Color3.new(0,0,0)
  8874. red,green,blue = curColor.r,curColor.g,curColor.b
  8875. hue,sat,val = Color3.toHSV(curColor)
  8876. updateColor()
  8877. end)
  8878.  
  8879. newColor.MouseButton2Click:Connect(function()
  8880. customColors[i] = chosenColor
  8881. newColor.BackgroundColor3 = chosenColor
  8882. end)
  8883.  
  8884. newColor.Parent = customColorsFrame
  8885. column = column + 1
  8886. if column == 6 then row = row + 1 column = 0 end
  8887. end
  8888.  
  8889. okButton.MouseButton1Click:Connect(function() newMt.OnSelect:Fire(chosenColor) window:Close() end)
  8890. okButton.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then okButton.BackgroundTransparency = 0.4 end end)
  8891. okButton.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then okButton.BackgroundTransparency = 0 end end)
  8892.  
  8893. cancelButton.MouseButton1Click:Connect(function() newMt.OnCancel:Fire() window:Close() end)
  8894. cancelButton.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then cancelButton.BackgroundTransparency = 0.4 end end)
  8895. cancelButton.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then cancelButton.BackgroundTransparency = 0 end end)
  8896.  
  8897. updateColor()
  8898.  
  8899. newMt.SetColor = function(self,color)
  8900. red,green,blue = color.r,color.g,color.b
  8901. hue,sat,val = Color3.toHSV(color)
  8902. updateColor()
  8903. end
  8904.  
  8905. newMt.Show = function(self)
  8906. self.Window:Show()
  8907. end
  8908.  
  8909. return newMt
  8910. end
  8911.  
  8912. return {new = new}
  8913. end)()
  8914.  
  8915. Lib.NumberSequenceEditor = (function()
  8916. local function new() -- TODO: Convert to newer class model
  8917. local newMt = setmetatable({},{})
  8918. newMt.OnSelect = Lib.Signal.new()
  8919. newMt.OnCancel = Lib.Signal.new()
  8920. newMt.OnPreview = Lib.Signal.new()
  8921.  
  8922. local guiContents = create({
  8923. {1,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,ClipsDescendants=true,Name="Content",Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,1,-20),}},
  8924. {2,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Time",Parent={1},Position=UDim2.new(0,40,0,210),Size=UDim2.new(0,60,0,20),}},
  8925. {3,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),ClipsDescendants=true,Font=3,Name="Input",Parent={2},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,58,0,20),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8926. {4,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={2},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Time",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  8927. {5,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Close",Parent={1},Position=UDim2.new(1,-90,0,210),Size=UDim2.new(0,80,0,20),Text="Close",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  8928. {6,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Reset",Parent={1},Position=UDim2.new(1,-180,0,210),Size=UDim2.new(0,80,0,20),Text="Reset",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  8929. {7,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Font=3,Name="Delete",Parent={1},Position=UDim2.new(0,380,0,210),Size=UDim2.new(0,80,0,20),Text="Delete",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  8930. {8,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Name="NumberLineOutlines",Parent={1},Position=UDim2.new(0,10,0,20),Size=UDim2.new(1,-20,0,170),}},
  8931. {9,"Frame",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),Name="NumberLine",Parent={1},Position=UDim2.new(0,10,0,20),Size=UDim2.new(1,-20,0,170),}},
  8932. {10,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Value",Parent={1},Position=UDim2.new(0,170,0,210),Size=UDim2.new(0,60,0,20),}},
  8933. {11,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={10},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Value",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  8934. {12,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),ClipsDescendants=true,Font=3,Name="Input",Parent={10},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,58,0,20),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8935. {13,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Envelope",Parent={1},Position=UDim2.new(0,300,0,210),Size=UDim2.new(0,60,0,20),}},
  8936. {14,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),ClipsDescendants=true,Font=3,Name="Input",Parent={13},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,58,0,20),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  8937. {15,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={13},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Envelope",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  8938. })
  8939. local window = Lib.Window.new()
  8940. window.Resizable = false
  8941. window:Resize(680,265)
  8942. window:SetTitle("NumberSequence Editor")
  8943. newMt.Window = window
  8944. newMt.Gui = window.Gui
  8945. for i,v in pairs(guiContents:GetChildren()) do
  8946. v.Parent = window.GuiElems.Content
  8947. end
  8948. local gui = window.Gui
  8949. local pickerGui = gui.Main
  8950. local pickerTopBar = pickerGui.TopBar
  8951. local pickerFrame = pickerGui.Content
  8952. local numberLine = pickerFrame.NumberLine
  8953. local numberLineOutlines = pickerFrame.NumberLineOutlines
  8954. local timeBox = pickerFrame.Time.Input
  8955. local valueBox = pickerFrame.Value.Input
  8956. local envelopeBox = pickerFrame.Envelope.Input
  8957. local deleteButton = pickerFrame.Delete
  8958. local resetButton = pickerFrame.Reset
  8959. local closeButton = pickerFrame.Close
  8960. local topClose = pickerTopBar.Close
  8961.  
  8962. local points = {{1,0,3},{8,0.05,1},{5,0.6,2},{4,0.7,4},{6,1,4}}
  8963. local lines = {}
  8964. local eLines = {}
  8965. local beginPoint = points[1]
  8966. local endPoint = points[#points]
  8967. local currentlySelected = nil
  8968. local currentPoint = nil
  8969. local resetSequence = nil
  8970.  
  8971. local user = clonerefs(game:GetService("UserInputService"))
  8972. local mouse = clonerefs(game:GetService("Players")).LocalPlayer:GetMouse()
  8973.  
  8974. for i = 2,10 do
  8975. local newLine = Instance.new("Frame")
  8976. newLine.BackgroundTransparency = 0.5
  8977. newLine.BackgroundColor3 = Color3.new(96/255,96/255,96/255)
  8978. newLine.BorderSizePixel = 0
  8979. newLine.Size = UDim2.new(0,1,1,0)
  8980. newLine.Position = UDim2.new((i-1)/(11-1),0,0,0)
  8981. newLine.Parent = numberLineOutlines
  8982. end
  8983.  
  8984. for i = 2,4 do
  8985. local newLine = Instance.new("Frame")
  8986. newLine.BackgroundTransparency = 0.5
  8987. newLine.BackgroundColor3 = Color3.new(96/255,96/255,96/255)
  8988. newLine.BorderSizePixel = 0
  8989. newLine.Size = UDim2.new(1,0,0,1)
  8990. newLine.Position = UDim2.new(0,0,(i-1)/(5-1),0)
  8991. newLine.Parent = numberLineOutlines
  8992. end
  8993.  
  8994. local lineTemp = Instance.new("Frame")
  8995. lineTemp.BackgroundColor3 = Color3.new(0,0,0)
  8996. lineTemp.BorderSizePixel = 0
  8997. lineTemp.Size = UDim2.new(0,1,0,1)
  8998.  
  8999. local sequenceLine = Instance.new("Frame")
  9000. sequenceLine.BackgroundColor3 = Color3.new(0,0,0)
  9001. sequenceLine.BorderSizePixel = 0
  9002. sequenceLine.Size = UDim2.new(0,1,0,0)
  9003.  
  9004. for i = 1,numberLine.AbsoluteSize.X do
  9005. local line = sequenceLine:Clone()
  9006. eLines[i] = line
  9007. line.Name = "E"..tostring(i)
  9008. line.BackgroundTransparency = 0.5
  9009. line.BackgroundColor3 = Color3.new(199/255,44/255,28/255)
  9010. line.Position = UDim2.new(0,i-1,0,0)
  9011. line.Parent = numberLine
  9012. end
  9013.  
  9014. for i = 1,numberLine.AbsoluteSize.X do
  9015. local line = sequenceLine:Clone()
  9016. lines[i] = line
  9017. line.Name = tostring(i)
  9018. line.Position = UDim2.new(0,i-1,0,0)
  9019. line.Parent = numberLine
  9020. end
  9021.  
  9022. local envelopeDrag = Instance.new("Frame")
  9023. envelopeDrag.BackgroundTransparency = 1
  9024. envelopeDrag.BackgroundColor3 = Color3.new(0,0,0)
  9025. envelopeDrag.BorderSizePixel = 0
  9026. envelopeDrag.Size = UDim2.new(0,7,0,20)
  9027. envelopeDrag.Visible = false
  9028. envelopeDrag.ZIndex = 2
  9029. local envelopeDragLine = Instance.new("Frame",envelopeDrag)
  9030. envelopeDragLine.Name = "Line"
  9031. envelopeDragLine.BackgroundColor3 = Color3.new(0,0,0)
  9032. envelopeDragLine.BorderSizePixel = 0
  9033. envelopeDragLine.Position = UDim2.new(0,3,0,0)
  9034. envelopeDragLine.Size = UDim2.new(0,1,0,20)
  9035. envelopeDragLine.ZIndex = 2
  9036.  
  9037. local envelopeDragTop,envelopeDragBottom = envelopeDrag:Clone(),envelopeDrag:Clone()
  9038. envelopeDragTop.Parent = numberLine
  9039. envelopeDragBottom.Parent = numberLine
  9040.  
  9041. local function buildSequence()
  9042. local newPoints = {}
  9043. for i,v in pairs(points) do
  9044. table.insert(newPoints,NumberSequenceKeypoint.new(v[2],v[1],v[3]))
  9045. end
  9046. newMt.Sequence = NumberSequence.new(newPoints)
  9047. newMt.OnSelect:Fire(newMt.Sequence)
  9048. end
  9049.  
  9050. local function round(num,places)
  9051. local multi = 10^places
  9052. return math.floor(num*multi + 0.5)/multi
  9053. end
  9054.  
  9055. local function updateInputs(point)
  9056. if point then
  9057. currentPoint = point
  9058. local rawT,rawV,rawE = point[2],point[1],point[3]
  9059. timeBox.Text = round(rawT,(rawT < 0.01 and 5) or (rawT < 0.1 and 4) or 3)
  9060. valueBox.Text = round(rawV,(rawV < 0.01 and 5) or (rawV < 0.1 and 4) or (rawV < 1 and 3) or 2)
  9061. envelopeBox.Text = round(rawE,(rawE < 0.01 and 5) or (rawE < 0.1 and 4) or (rawV < 1 and 3) or 2)
  9062.  
  9063. local envelopeDistance = numberLine.AbsoluteSize.Y*(point[3]/10)
  9064. envelopeDragTop.Position = UDim2.new(0,point[4].Position.X.Offset-1,0,point[4].Position.Y.Offset-envelopeDistance-17)
  9065. envelopeDragTop.Visible = true
  9066. envelopeDragBottom.Position = UDim2.new(0,point[4].Position.X.Offset-1,0,point[4].Position.Y.Offset+envelopeDistance+2)
  9067. envelopeDragBottom.Visible = true
  9068. end
  9069. end
  9070.  
  9071. envelopeDragTop.InputBegan:Connect(function(input)
  9072. if input.UserInputType ~= Enum.UserInputType.MouseButton1 or not currentPoint or Lib.CheckMouseInGui(currentPoint[4].Select) then return end
  9073. local mouseEvent,releaseEvent
  9074. local maxSize = numberLine.AbsoluteSize.Y
  9075.  
  9076. local mouseDelta = math.abs(envelopeDragTop.AbsolutePosition.Y - mouse.Y)
  9077.  
  9078. envelopeDragTop.Line.Position = UDim2.new(0,2,0,0)
  9079. envelopeDragTop.Line.Size = UDim2.new(0,3,0,20)
  9080.  
  9081. releaseEvent = user.InputEnded:Connect(function(input)
  9082. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  9083. mouseEvent:Disconnect()
  9084. releaseEvent:Disconnect()
  9085. envelopeDragTop.Line.Position = UDim2.new(0,3,0,0)
  9086. envelopeDragTop.Line.Size = UDim2.new(0,1,0,20)
  9087. end)
  9088.  
  9089. mouseEvent = user.InputChanged:Connect(function(input)
  9090. if input.UserInputType == Enum.UserInputType.MouseMovement then
  9091. local topDiff = (currentPoint[4].AbsolutePosition.Y+2)-(mouse.Y-mouseDelta)-19
  9092. local newEnvelope = 10*(math.max(topDiff,0)/maxSize)
  9093. local maxEnvelope = math.min(currentPoint[1],10-currentPoint[1])
  9094. currentPoint[3] = math.min(newEnvelope,maxEnvelope)
  9095. newMt:Redraw()
  9096. buildSequence()
  9097. updateInputs(currentPoint)
  9098. end
  9099. end)
  9100. end)
  9101.  
  9102. envelopeDragBottom.InputBegan:Connect(function(input)
  9103. if input.UserInputType ~= Enum.UserInputType.MouseButton1 or not currentPoint or Lib.CheckMouseInGui(currentPoint[4].Select) then return end
  9104. local mouseEvent,releaseEvent
  9105. local maxSize = numberLine.AbsoluteSize.Y
  9106.  
  9107. local mouseDelta = math.abs(envelopeDragBottom.AbsolutePosition.Y - mouse.Y)
  9108.  
  9109. envelopeDragBottom.Line.Position = UDim2.new(0,2,0,0)
  9110. envelopeDragBottom.Line.Size = UDim2.new(0,3,0,20)
  9111.  
  9112. releaseEvent = user.InputEnded:Connect(function(input)
  9113. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  9114. mouseEvent:Disconnect()
  9115. releaseEvent:Disconnect()
  9116. envelopeDragBottom.Line.Position = UDim2.new(0,3,0,0)
  9117. envelopeDragBottom.Line.Size = UDim2.new(0,1,0,20)
  9118. end)
  9119.  
  9120. mouseEvent = user.InputChanged:Connect(function(input)
  9121. if input.UserInputType == Enum.UserInputType.MouseMovement then
  9122. local bottomDiff = (mouse.Y+(20-mouseDelta))-(currentPoint[4].AbsolutePosition.Y+2)-19
  9123. local newEnvelope = 10*(math.max(bottomDiff,0)/maxSize)
  9124. local maxEnvelope = math.min(currentPoint[1],10-currentPoint[1])
  9125. currentPoint[3] = math.min(newEnvelope,maxEnvelope)
  9126. newMt:Redraw()
  9127. buildSequence()
  9128. updateInputs(currentPoint)
  9129. end
  9130. end)
  9131. end)
  9132.  
  9133. local function placePoint(point)
  9134. local newPoint = Instance.new("Frame")
  9135. newPoint.Name = "Point"
  9136. newPoint.BorderSizePixel = 0
  9137. newPoint.Size = UDim2.new(0,5,0,5)
  9138. newPoint.Position = UDim2.new(0,math.floor((numberLine.AbsoluteSize.X-1) * point[2])-2,0,numberLine.AbsoluteSize.Y*(10-point[1])/10-2)
  9139. newPoint.BackgroundColor3 = Color3.new(0,0,0)
  9140.  
  9141. local newSelect = Instance.new("Frame")
  9142. newSelect.Name = "Select"
  9143. newSelect.BackgroundTransparency = 1
  9144. newSelect.BackgroundColor3 = Color3.new(199/255,44/255,28/255)
  9145. newSelect.Position = UDim2.new(0,-2,0,-2)
  9146. newSelect.Size = UDim2.new(0,9,0,9)
  9147. newSelect.Parent = newPoint
  9148.  
  9149. newPoint.Parent = numberLine
  9150.  
  9151. newSelect.InputBegan:Connect(function(input)
  9152. if input.UserInputType == Enum.UserInputType.MouseMovement then
  9153. for i,v in pairs(points) do v[4].Select.BackgroundTransparency = 1 end
  9154. newSelect.BackgroundTransparency = 0
  9155. updateInputs(point)
  9156. end
  9157. if input.UserInputType == Enum.UserInputType.MouseButton1 and not currentlySelected then
  9158. currentPoint = point
  9159. local mouseEvent,releaseEvent
  9160. currentlySelected = true
  9161. newSelect.BackgroundColor3 = Color3.new(249/255,191/255,59/255)
  9162.  
  9163. local oldEnvelope = point[3]
  9164.  
  9165. releaseEvent = user.InputEnded:Connect(function(input)
  9166. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  9167. mouseEvent:Disconnect()
  9168. releaseEvent:Disconnect()
  9169. currentlySelected = nil
  9170. newSelect.BackgroundColor3 = Color3.new(199/255,44/255,28/255)
  9171. end)
  9172.  
  9173. mouseEvent = user.InputChanged:Connect(function(input)
  9174. if input.UserInputType == Enum.UserInputType.MouseMovement then
  9175. local maxX = numberLine.AbsoluteSize.X-1
  9176. local relativeX = mouse.X - numberLine.AbsolutePosition.X
  9177. if relativeX < 0 then relativeX = 0 end
  9178. if relativeX > maxX then relativeX = maxX end
  9179. local maxY = numberLine.AbsoluteSize.Y-1
  9180. local relativeY = mouse.Y - numberLine.AbsolutePosition.Y
  9181. if relativeY < 0 then relativeY = 0 end
  9182. if relativeY > maxY then relativeY = maxY end
  9183. if point ~= beginPoint and point ~= endPoint then
  9184. point[2] = relativeX/maxX
  9185. end
  9186. point[1] = 10-(relativeY/maxY)*10
  9187. local maxEnvelope = math.min(point[1],10-point[1])
  9188. point[3] = math.min(oldEnvelope,maxEnvelope)
  9189. newMt:Redraw()
  9190. updateInputs(point)
  9191. for i,v in pairs(points) do v[4].Select.BackgroundTransparency = 1 end
  9192. newSelect.BackgroundTransparency = 0
  9193. buildSequence()
  9194. end
  9195. end)
  9196. end
  9197. end)
  9198.  
  9199. return newPoint
  9200. end
  9201.  
  9202. local function placePoints()
  9203. for i,v in pairs(points) do
  9204. v[4] = placePoint(v)
  9205. end
  9206. end
  9207.  
  9208. local function redraw(self)
  9209. local numberLineSize = numberLine.AbsoluteSize
  9210. table.sort(points,function(a,b) return a[2] < b[2] end)
  9211. for i,v in pairs(points) do
  9212. v[4].Position = UDim2.new(0,math.floor((numberLineSize.X-1) * v[2])-2,0,(numberLineSize.Y-1)*(10-v[1])/10-2)
  9213. end
  9214. lines[1].Size = UDim2.new(0,1,0,0)
  9215. for i = 1,#points-1 do
  9216. local fromPoint = points[i]
  9217. local toPoint = points[i+1]
  9218. local deltaY = toPoint[4].Position.Y.Offset-fromPoint[4].Position.Y.Offset
  9219. local deltaX = toPoint[4].Position.X.Offset-fromPoint[4].Position.X.Offset
  9220. local slope = deltaY/deltaX
  9221.  
  9222. local fromEnvelope = fromPoint[3]
  9223. local nextEnvelope = toPoint[3]
  9224.  
  9225. local currentRise = math.abs(slope)
  9226. local totalRise = 0
  9227. local maxRise = math.abs(toPoint[4].Position.Y.Offset-fromPoint[4].Position.Y.Offset)
  9228.  
  9229. for lineCount = math.min(fromPoint[4].Position.X.Offset+1,toPoint[4].Position.X.Offset),toPoint[4].Position.X.Offset do
  9230. if deltaX == 0 and deltaY == 0 then return end
  9231. local riseNow = math.floor(currentRise)
  9232. local line = lines[lineCount+3]
  9233. if line then
  9234. if totalRise+riseNow > maxRise then riseNow = maxRise-totalRise end
  9235. if math.sign(slope) == -1 then
  9236. line.Position = UDim2.new(0,lineCount+2,0,fromPoint[4].Position.Y.Offset + -(totalRise+riseNow)+2)
  9237. else
  9238. line.Position = UDim2.new(0,lineCount+2,0,fromPoint[4].Position.Y.Offset + totalRise+2)
  9239. end
  9240. line.Size = UDim2.new(0,1,0,math.max(riseNow,1))
  9241. end
  9242. totalRise = totalRise + riseNow
  9243. currentRise = currentRise - riseNow + math.abs(slope)
  9244.  
  9245. local envPercent = (lineCount-fromPoint[4].Position.X.Offset)/(toPoint[4].Position.X.Offset-fromPoint[4].Position.X.Offset)
  9246. local envLerp = fromEnvelope+(nextEnvelope-fromEnvelope)*envPercent
  9247. local relativeSize = (envLerp/10)*numberLineSize.Y
  9248.  
  9249. local line = eLines[lineCount + 3]
  9250. if line then
  9251. line.Position = UDim2.new(0,lineCount+2,0,lines[lineCount+3].Position.Y.Offset-math.floor(relativeSize))
  9252. line.Size = UDim2.new(0,1,0,math.floor(relativeSize*2))
  9253. end
  9254. end
  9255. end
  9256. end
  9257. newMt.Redraw = redraw
  9258.  
  9259. local function loadSequence(self,seq)
  9260. resetSequence = seq
  9261. for i,v in pairs(points) do if v[4] then v[4]:Destroy() end end
  9262. points = {}
  9263. for i,v in pairs(seq.Keypoints) do
  9264. local maxEnvelope = math.min(v.Value,10-v.Value)
  9265. local newPoint = {v.Value,v.Time,math.min(v.Envelope,maxEnvelope)}
  9266. newPoint[4] = placePoint(newPoint)
  9267. table.insert(points,newPoint)
  9268. end
  9269. beginPoint = points[1]
  9270. endPoint = points[#points]
  9271. currentlySelected = nil
  9272. redraw()
  9273. envelopeDragTop.Visible = false
  9274. envelopeDragBottom.Visible = false
  9275. end
  9276. newMt.SetSequence = loadSequence
  9277.  
  9278. timeBox.FocusLost:Connect(function()
  9279. local point = currentPoint
  9280. local num = tonumber(timeBox.Text)
  9281. if point and num and point ~= beginPoint and point ~= endPoint then
  9282. num = math.clamp(num,0,1)
  9283. point[2] = num
  9284. redraw()
  9285. buildSequence()
  9286. updateInputs(point)
  9287. end
  9288. end)
  9289.  
  9290. valueBox.FocusLost:Connect(function()
  9291. local point = currentPoint
  9292. local num = tonumber(valueBox.Text)
  9293. if point and num then
  9294. local oldEnvelope = point[3]
  9295. num = math.clamp(num,0,10)
  9296. point[1] = num
  9297. local maxEnvelope = math.min(point[1],10-point[1])
  9298. point[3] = math.min(oldEnvelope,maxEnvelope)
  9299. redraw()
  9300. buildSequence()
  9301. updateInputs(point)
  9302. end
  9303. end)
  9304.  
  9305. envelopeBox.FocusLost:Connect(function()
  9306. local point = currentPoint
  9307. local num = tonumber(envelopeBox.Text)
  9308. if point and num then
  9309. num = math.clamp(num,0,5)
  9310. local maxEnvelope = math.min(point[1],10-point[1])
  9311. point[3] = math.min(num,maxEnvelope)
  9312. redraw()
  9313. buildSequence()
  9314. updateInputs(point)
  9315. end
  9316. end)
  9317.  
  9318. local function buttonAnimations(button,inverse)
  9319. button.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then button.BackgroundTransparency = (inverse and 0.5 or 0.4) end end)
  9320. button.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then button.BackgroundTransparency = (inverse and 1 or 0) end end)
  9321. end
  9322.  
  9323. numberLine.InputBegan:Connect(function(input)
  9324. if input.UserInputType == Enum.UserInputType.MouseButton1 and #points < 20 then
  9325. if Lib.CheckMouseInGui(envelopeDragTop) or Lib.CheckMouseInGui(envelopeDragBottom) then return end
  9326. for i,v in pairs(points) do
  9327. if Lib.CheckMouseInGui(v[4].Select) then return end
  9328. end
  9329. local maxX = numberLine.AbsoluteSize.X-1
  9330. local relativeX = mouse.X - numberLine.AbsolutePosition.X
  9331. if relativeX < 0 then relativeX = 0 end
  9332. if relativeX > maxX then relativeX = maxX end
  9333. local maxY = numberLine.AbsoluteSize.Y-1
  9334. local relativeY = mouse.Y - numberLine.AbsolutePosition.Y
  9335. if relativeY < 0 then relativeY = 0 end
  9336. if relativeY > maxY then relativeY = maxY end
  9337.  
  9338. local raw = relativeX/maxX
  9339. local newPoint = {10-(relativeY/maxY)*10,raw,0}
  9340. newPoint[4] = placePoint(newPoint)
  9341. table.insert(points,newPoint)
  9342. redraw()
  9343. buildSequence()
  9344. end
  9345. end)
  9346.  
  9347. deleteButton.MouseButton1Click:Connect(function()
  9348. if currentPoint and currentPoint ~= beginPoint and currentPoint ~= endPoint then
  9349. for i,v in pairs(points) do
  9350. if v == currentPoint then
  9351. v[4]:Destroy()
  9352. table.remove(points,i)
  9353. break
  9354. end
  9355. end
  9356. currentlySelected = nil
  9357. redraw()
  9358. buildSequence()
  9359. updateInputs(points[1])
  9360. end
  9361. end)
  9362.  
  9363. resetButton.MouseButton1Click:Connect(function()
  9364. if resetSequence then
  9365. newMt:SetSequence(resetSequence)
  9366. buildSequence()
  9367. end
  9368. end)
  9369.  
  9370. closeButton.MouseButton1Click:Connect(function()
  9371. window:Close()
  9372. end)
  9373.  
  9374. buttonAnimations(deleteButton)
  9375. buttonAnimations(resetButton)
  9376. buttonAnimations(closeButton)
  9377.  
  9378. placePoints()
  9379. redraw()
  9380.  
  9381. newMt.Show = function(self)
  9382. window:Show()
  9383. end
  9384.  
  9385. return newMt
  9386. end
  9387.  
  9388. return {new = new}
  9389. end)()
  9390.  
  9391. Lib.ColorSequenceEditor = (function() -- TODO: Convert to newer class model
  9392. local function new()
  9393. local newMt = setmetatable({},{})
  9394. newMt.OnSelect = Lib.Signal.new()
  9395. newMt.OnCancel = Lib.Signal.new()
  9396. newMt.OnPreview = Lib.Signal.new()
  9397. newMt.OnPickColor = Lib.Signal.new()
  9398.  
  9399. local guiContents = create({
  9400. {1,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,ClipsDescendants=true,Name="Content",Position=UDim2.new(0,0,0,20),Size=UDim2.new(1,0,1,-20),}},
  9401. {2,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Name="ColorLine",Parent={1},Position=UDim2.new(0,10,0,5),Size=UDim2.new(1,-20,0,70),}},
  9402. {3,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderSizePixel=0,Name="Gradient",Parent={2},Size=UDim2.new(1,0,1,0),}},
  9403. {4,"UIGradient",{Parent={3},}},
  9404. {5,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Name="Arrows",Parent={1},Position=UDim2.new(0,1,0,73),Size=UDim2.new(1,-2,0,16),}},
  9405. {6,"Frame",{BackgroundColor3=Color3.new(0,0,0),BackgroundTransparency=0.5,BorderSizePixel=0,Name="Cursor",Parent={1},Position=UDim2.new(0,10,0,0),Size=UDim2.new(0,1,0,80),}},
  9406. {7,"Frame",{BackgroundColor3=Color3.new(0.14901961386204,0.14901961386204,0.14901961386204),BorderColor3=Color3.new(0.12549020349979,0.12549020349979,0.12549020349979),Name="Time",Parent={1},Position=UDim2.new(0,40,0,95),Size=UDim2.new(0,100,0,20),}},
  9407. {8,"TextBox",{BackgroundColor3=Color3.new(0.25098040699959,0.25098040699959,0.25098040699959),BackgroundTransparency=1,BorderColor3=Color3.new(0.37647062540054,0.37647062540054,0.37647062540054),ClipsDescendants=true,Font=3,Name="Input",Parent={7},Position=UDim2.new(0,2,0,0),Size=UDim2.new(0,98,0,20),Text="0",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=0,}},
  9408. {9,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={7},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Time",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  9409. {10,"Frame",{BackgroundColor3=Color3.new(1,1,1),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),Name="ColorBox",Parent={1},Position=UDim2.new(0,220,0,95),Size=UDim2.new(0,20,0,20),}},
  9410. {11,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Title",Parent={10},Position=UDim2.new(0,-40,0,0),Size=UDim2.new(0,34,1,0),Text="Color",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,TextXAlignment=1,}},
  9411. {12,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,Font=3,Name="Close",Parent={1},Position=UDim2.new(1,-90,0,95),Size=UDim2.new(0,80,0,20),Text="Close",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  9412. {13,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,Font=3,Name="Reset",Parent={1},Position=UDim2.new(1,-180,0,95),Size=UDim2.new(0,80,0,20),Text="Reset",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  9413. {14,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderColor3=Color3.new(0.21568627655506,0.21568627655506,0.21568627655506),BorderSizePixel=0,Font=3,Name="Delete",Parent={1},Position=UDim2.new(0,280,0,95),Size=UDim2.new(0,80,0,20),Text="Delete",TextColor3=Color3.new(0.86274516582489,0.86274516582489,0.86274516582489),TextSize=14,}},
  9414. {15,"Frame",{BackgroundTransparency=1,Name="Arrow",Parent={1},Size=UDim2.new(0,16,0,16),Visible=false,}},
  9415. {16,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,8,0,3),Size=UDim2.new(0,1,0,2),}},
  9416. {17,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,7,0,5),Size=UDim2.new(0,3,0,2),}},
  9417. {18,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,6,0,7),Size=UDim2.new(0,5,0,2),}},
  9418. {19,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,5,0,9),Size=UDim2.new(0,7,0,2),}},
  9419. {20,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={15},Position=UDim2.new(0,4,0,11),Size=UDim2.new(0,9,0,2),}},
  9420. })
  9421. local window = Lib.Window.new()
  9422. window.Resizable = false
  9423. window:Resize(650,150)
  9424. window:SetTitle("ColorSequence Editor")
  9425. newMt.Window = window
  9426. newMt.Gui = window.Gui
  9427. for i,v in pairs(guiContents:GetChildren()) do
  9428. v.Parent = window.GuiElems.Content
  9429. end
  9430. local gui = window.Gui
  9431. local pickerGui = gui.Main
  9432. local pickerTopBar = pickerGui.TopBar
  9433. local pickerFrame = pickerGui.Content
  9434. local colorLine = pickerFrame.ColorLine
  9435. local gradient = colorLine.Gradient.UIGradient
  9436. local arrowFrame = pickerFrame.Arrows
  9437. local arrow = pickerFrame.Arrow
  9438. local cursor = pickerFrame.Cursor
  9439. local timeBox = pickerFrame.Time.Input
  9440. local colorBox = pickerFrame.ColorBox
  9441. local deleteButton = pickerFrame.Delete
  9442. local resetButton = pickerFrame.Reset
  9443. local closeButton = pickerFrame.Close
  9444. local topClose = pickerTopBar.Close
  9445.  
  9446. local user = clonerefs(game:GetService("UserInputService"))
  9447. local mouse = clonerefs(game:GetService("Players")).LocalPlayer:GetMouse()
  9448.  
  9449. local colors = {{Color3.new(1,0,1),0},{Color3.new(0.2,0.9,0.2),0.2},{Color3.new(0.4,0.5,0.9),0.7},{Color3.new(0.6,1,1),1}}
  9450. local resetSequence = nil
  9451.  
  9452. local beginPoint = colors[1]
  9453. local endPoint = colors[#colors]
  9454.  
  9455. local currentlySelected = nil
  9456. local currentPoint = nil
  9457.  
  9458. local sequenceLine = Instance.new("Frame")
  9459. sequenceLine.BorderSizePixel = 0
  9460. sequenceLine.Size = UDim2.new(0,1,1,0)
  9461.  
  9462. newMt.Sequence = ColorSequence.new(Color3.new(1,1,1))
  9463. local function buildSequence(noupdate)
  9464. local newPoints = {}
  9465. table.sort(colors,function(a,b) return a[2] < b[2] end)
  9466. for i,v in pairs(colors) do
  9467. table.insert(newPoints,ColorSequenceKeypoint.new(v[2],v[1]))
  9468. end
  9469. newMt.Sequence = ColorSequence.new(newPoints)
  9470. if not noupdate then newMt.OnSelect:Fire(newMt.Sequence) end
  9471. end
  9472.  
  9473. local function round(num,places)
  9474. local multi = 10^places
  9475. return math.floor(num*multi + 0.5)/multi
  9476. end
  9477.  
  9478. local function updateInputs(point)
  9479. if point then
  9480. currentPoint = point
  9481. local raw = point[2]
  9482. timeBox.Text = round(raw,(raw < 0.01 and 5) or (raw < 0.1 and 4) or 3)
  9483. colorBox.BackgroundColor3 = point[1]
  9484. end
  9485. end
  9486.  
  9487. local function placeArrow(ind,point)
  9488. local newArrow = arrow:Clone()
  9489. newArrow.Position = UDim2.new(0,ind-1,0,0)
  9490. newArrow.Visible = true
  9491. newArrow.Parent = arrowFrame
  9492.  
  9493. newArrow.InputBegan:Connect(function(input)
  9494. if input.UserInputType == Enum.UserInputType.MouseMovement then
  9495. cursor.Visible = true
  9496. cursor.Position = UDim2.new(0,9 + newArrow.Position.X.Offset,0,0)
  9497. end
  9498. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  9499. updateInputs(point)
  9500. if point == beginPoint or point == endPoint or currentlySelected then return end
  9501.  
  9502. local mouseEvent,releaseEvent
  9503. currentlySelected = true
  9504.  
  9505. releaseEvent = user.InputEnded:Connect(function(input)
  9506. if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  9507. mouseEvent:Disconnect()
  9508. releaseEvent:Disconnect()
  9509. currentlySelected = nil
  9510. cursor.Visible = false
  9511. end)
  9512.  
  9513. mouseEvent = user.InputChanged:Connect(function(input)
  9514. if input.UserInputType == Enum.UserInputType.MouseMovement then
  9515. local maxSize = colorLine.AbsoluteSize.X-1
  9516. local relativeX = mouse.X - colorLine.AbsolutePosition.X
  9517. if relativeX < 0 then relativeX = 0 end
  9518. if relativeX > maxSize then relativeX = maxSize end
  9519. local raw = relativeX/maxSize
  9520. point[2] = relativeX/maxSize
  9521. updateInputs(point)
  9522. cursor.Visible = true
  9523. cursor.Position = UDim2.new(0,9 + newArrow.Position.X.Offset,0,0)
  9524. buildSequence()
  9525. newMt:Redraw()
  9526. end
  9527. end)
  9528. end
  9529. end)
  9530.  
  9531. newArrow.InputEnded:Connect(function(input)
  9532. if input.UserInputType == Enum.UserInputType.MouseMovement then
  9533. cursor.Visible = false
  9534. end
  9535. end)
  9536.  
  9537. return newArrow
  9538. end
  9539.  
  9540. local function placeArrows()
  9541. for i,v in pairs(colors) do
  9542. v[3] = placeArrow(math.floor((colorLine.AbsoluteSize.X-1) * v[2]) + 1,v)
  9543. end
  9544. end
  9545.  
  9546. local function redraw(self)
  9547. gradient.Color = newMt.Sequence or ColorSequence.new(Color3.new(1,1,1))
  9548.  
  9549. for i = 2,#colors do
  9550. local nextColor = colors[i]
  9551. local endPos = math.floor((colorLine.AbsoluteSize.X-1) * nextColor[2]) + 1
  9552. nextColor[3].Position = UDim2.new(0,endPos,0,0)
  9553. end
  9554. end
  9555. newMt.Redraw = redraw
  9556.  
  9557. local function loadSequence(self,seq)
  9558. resetSequence = seq
  9559. for i,v in pairs(colors) do if v[3] then v[3]:Destroy() end end
  9560. colors = {}
  9561. currentlySelected = nil
  9562. for i,v in pairs(seq.Keypoints) do
  9563. local newPoint = {v.Value,v.Time}
  9564. newPoint[3] = placeArrow(v.Time,newPoint)
  9565. table.insert(colors,newPoint)
  9566. end
  9567. beginPoint = colors[1]
  9568. endPoint = colors[#colors]
  9569. currentlySelected = nil
  9570. updateInputs(colors[1])
  9571. buildSequence(true)
  9572. redraw()
  9573. end
  9574. newMt.SetSequence = loadSequence
  9575.  
  9576. local function buttonAnimations(button,inverse)
  9577. button.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then button.BackgroundTransparency = (inverse and 0.5 or 0.4) end end)
  9578. button.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement then button.BackgroundTransparency = (inverse and 1 or 0) end end)
  9579. end
  9580.  
  9581. colorLine.InputBegan:Connect(function(input)
  9582. if input.UserInputType == Enum.UserInputType.MouseButton1 and #colors < 20 then
  9583. local maxSize = colorLine.AbsoluteSize.X-1
  9584. local relativeX = mouse.X - colorLine.AbsolutePosition.X
  9585. if relativeX < 0 then relativeX = 0 end
  9586. if relativeX > maxSize then relativeX = maxSize end
  9587.  
  9588. local raw = relativeX/maxSize
  9589. local fromColor = nil
  9590. local toColor = nil
  9591. for i,col in pairs(colors) do
  9592. if col[2] >= raw then
  9593. fromColor = colors[math.max(i-1,1)]
  9594. toColor = colors[i]
  9595. break
  9596. end
  9597. end
  9598. local lerpColor = fromColor[1]:lerp(toColor[1],(raw-fromColor[2])/(toColor[2]-fromColor[2]))
  9599. local newPoint = {lerpColor,raw}
  9600. newPoint[3] = placeArrow(newPoint[2],newPoint)
  9601. table.insert(colors,newPoint)
  9602. updateInputs(newPoint)
  9603. buildSequence()
  9604. redraw()
  9605. end
  9606. end)
  9607.  
  9608. colorLine.InputChanged:Connect(function(input)
  9609. if input.UserInputType == Enum.UserInputType.MouseMovement then
  9610. local maxSize = colorLine.AbsoluteSize.X-1
  9611. local relativeX = mouse.X - colorLine.AbsolutePosition.X
  9612. if relativeX < 0 then relativeX = 0 end
  9613. if relativeX > maxSize then relativeX = maxSize end
  9614. cursor.Visible = true
  9615. cursor.Position = UDim2.new(0,10 + relativeX,0,0)
  9616. end
  9617. end)
  9618.  
  9619. colorLine.InputEnded:Connect(function(input)
  9620. if input.UserInputType == Enum.UserInputType.MouseMovement then
  9621. local inArrow = false
  9622. for i,v in pairs(colors) do
  9623. if Lib.CheckMouseInGui(v[3]) then
  9624. inArrow = v[3]
  9625. end
  9626. end
  9627. cursor.Visible = inArrow and true or false
  9628. if inArrow then cursor.Position = UDim2.new(0,9 + inArrow.Position.X.Offset,0,0) end
  9629. end
  9630. end)
  9631.  
  9632. timeBox:GetPropertyChangedSignal("Text"):Connect(function()
  9633. local point = currentPoint
  9634. local num = tonumber(timeBox.Text)
  9635. if point and num and point ~= beginPoint and point ~= endPoint then
  9636. num = math.clamp(num,0,1)
  9637. point[2] = num
  9638. buildSequence()
  9639. redraw()
  9640. end
  9641. end)
  9642.  
  9643. colorBox.InputBegan:Connect(function(input)
  9644. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  9645. local editor = newMt.ColorPicker
  9646. if not editor then
  9647. editor = Lib.ColorPicker.new()
  9648. editor.Window:SetTitle("ColorSequence Color Picker")
  9649.  
  9650. editor.OnSelect:Connect(function(col)
  9651. if currentPoint then
  9652. currentPoint[1] = col
  9653. end
  9654. buildSequence()
  9655. redraw()
  9656. end)
  9657.  
  9658. newMt.ColorPicker = editor
  9659. end
  9660.  
  9661. editor.Window:ShowAndFocus()
  9662. end
  9663. end)
  9664.  
  9665. deleteButton.MouseButton1Click:Connect(function()
  9666. if currentPoint and currentPoint ~= beginPoint and currentPoint ~= endPoint then
  9667. for i,v in pairs(colors) do
  9668. if v == currentPoint then
  9669. v[3]:Destroy()
  9670. table.remove(colors,i)
  9671. break
  9672. end
  9673. end
  9674. currentlySelected = nil
  9675. updateInputs(colors[1])
  9676. buildSequence()
  9677. redraw()
  9678. end
  9679. end)
  9680.  
  9681. resetButton.MouseButton1Click:Connect(function()
  9682. if resetSequence then
  9683. newMt:SetSequence(resetSequence)
  9684. end
  9685. end)
  9686.  
  9687. closeButton.MouseButton1Click:Connect(function()
  9688. window:Close()
  9689. end)
  9690.  
  9691. topClose.MouseButton1Click:Connect(function()
  9692. window:Close()
  9693. end)
  9694.  
  9695. buttonAnimations(deleteButton)
  9696. buttonAnimations(resetButton)
  9697. buttonAnimations(closeButton)
  9698.  
  9699. placeArrows()
  9700. redraw()
  9701.  
  9702. newMt.Show = function(self)
  9703. window:Show()
  9704. end
  9705.  
  9706. return newMt
  9707. end
  9708.  
  9709. return {new = new}
  9710. end)()
  9711.  
  9712. Lib.ViewportTextBox = (function()
  9713. local textService = clonerefs(game:GetService("TextService"))
  9714.  
  9715. local props = {
  9716. OffsetX = 0,
  9717. TextBox = PH,
  9718. CursorPos = -1,
  9719. Gui = PH,
  9720. View = PH
  9721. }
  9722. local funcs = {}
  9723. funcs.Update = function(self)
  9724. local cursorPos = self.CursorPos or -1
  9725. local text = self.TextBox.Text
  9726. if text == "" then self.TextBox.Position = UDim2.new(0,0,0,0) return end
  9727. if cursorPos == -1 then return end
  9728.  
  9729. local cursorText = text:sub(1,cursorPos-1)
  9730. local pos = nil
  9731. local leftEnd = -self.TextBox.Position.X.Offset
  9732. local rightEnd = leftEnd + self.View.AbsoluteSize.X
  9733.  
  9734. local totalTextSize = textService:GetTextSize(text,self.TextBox.TextSize,self.TextBox.Font,Vector2.new(999999999,100)).X
  9735. local cursorTextSize = textService:GetTextSize(cursorText,self.TextBox.TextSize,self.TextBox.Font,Vector2.new(999999999,100)).X
  9736.  
  9737. if cursorTextSize > rightEnd then
  9738. pos = math.max(-1,cursorTextSize - self.View.AbsoluteSize.X + 2)
  9739. elseif cursorTextSize < leftEnd then
  9740. pos = math.max(-1,cursorTextSize-2)
  9741. elseif totalTextSize < rightEnd then
  9742. pos = math.max(-1,totalTextSize - self.View.AbsoluteSize.X + 2)
  9743. end
  9744.  
  9745. if pos then
  9746. self.TextBox.Position = UDim2.new(0,-pos,0,0)
  9747. self.TextBox.Size = UDim2.new(1,pos,1,0)
  9748. end
  9749. end
  9750.  
  9751. funcs.GetText = function(self)
  9752. return self.TextBox.Text
  9753. end
  9754.  
  9755. funcs.SetText = function(self,text)
  9756. self.TextBox.Text = text
  9757. end
  9758.  
  9759. local mt = getGuiMT(props,funcs)
  9760.  
  9761. local function convert(textbox)
  9762. local obj = initObj(props,mt)
  9763.  
  9764. local view = Instance.new("Frame")
  9765. view.BackgroundTransparency = textbox.BackgroundTransparency
  9766. view.BackgroundColor3 = textbox.BackgroundColor3
  9767. view.BorderSizePixel = textbox.BorderSizePixel
  9768. view.BorderColor3 = textbox.BorderColor3
  9769. view.Position = textbox.Position
  9770. view.Size = textbox.Size
  9771. view.ClipsDescendants = true
  9772. view.Name = textbox.Name
  9773. textbox.BackgroundTransparency = 1
  9774. textbox.Position = UDim2.new(0,0,0,0)
  9775. textbox.Size = UDim2.new(1,0,1,0)
  9776. textbox.TextXAlignment = Enum.TextXAlignment.Left
  9777. textbox.Name = "Input"
  9778.  
  9779. obj.TextBox = textbox
  9780. obj.View = view
  9781. obj.Gui = view
  9782.  
  9783. textbox.Changed:Connect(function(prop)
  9784. if prop == "Text" or prop == "CursorPosition" or prop == "AbsoluteSize" then
  9785. local cursorPos = obj.TextBox.CursorPosition
  9786. if cursorPos ~= -1 then obj.CursorPos = cursorPos end
  9787. obj:Update()
  9788. end
  9789. end)
  9790.  
  9791. obj:Update()
  9792.  
  9793. view.Parent = textbox.Parent
  9794. textbox.Parent = view
  9795.  
  9796. return obj
  9797. end
  9798.  
  9799. local function new()
  9800. local textBox = Instance.new("TextBox")
  9801. textBox.Size = UDim2.new(0,100,0,20)
  9802. textBox.BackgroundColor3 = Settings.Theme.TextBox
  9803. textBox.BorderColor3 = Settings.Theme.Outline3
  9804. textBox.ClearTextOnFocus = false
  9805. textBox.TextColor3 = Settings.Theme.Text
  9806. textBox.Font = Enum.Font.SourceSans
  9807. textBox.TextSize = 14
  9808. textBox.Text = ""
  9809. return convert(textBox)
  9810. end
  9811.  
  9812. return {new = new, convert = convert}
  9813. end)()
  9814.  
  9815. Lib.Label = (function()
  9816. local props,funcs = {},{}
  9817.  
  9818. local mt = getGuiMT(props,funcs)
  9819.  
  9820. local function new()
  9821. local label = Instance.new("TextLabel")
  9822. label.BackgroundTransparency = 1
  9823. label.TextXAlignment = Enum.TextXAlignment.Left
  9824. label.TextColor3 = Settings.Theme.Text
  9825. label.TextTransparency = 0.1
  9826. label.Size = UDim2.new(0,100,0,20)
  9827. label.Font = Enum.Font.SourceSans
  9828. label.TextSize = 14
  9829.  
  9830. local obj = setmetatable({
  9831. Gui = label
  9832. },mt)
  9833. return obj
  9834. end
  9835.  
  9836. return {new = new}
  9837. end)()
  9838.  
  9839. Lib.Frame = (function()
  9840. local props,funcs = {},{}
  9841.  
  9842. local mt = getGuiMT(props,funcs)
  9843.  
  9844. local function new()
  9845. local fr = Instance.new("Frame")
  9846. fr.BackgroundColor3 = Settings.Theme.Main1
  9847. fr.BorderColor3 = Settings.Theme.Outline1
  9848. fr.Size = UDim2.new(0,50,0,50)
  9849.  
  9850. local obj = setmetatable({
  9851. Gui = fr
  9852. },mt)
  9853. return obj
  9854. end
  9855.  
  9856. return {new = new}
  9857. end)()
  9858.  
  9859. Lib.Button = (function()
  9860. local props = {
  9861. Gui = PH,
  9862. Anim = PH,
  9863. Disabled = false,
  9864. OnClick = SIGNAL,
  9865. OnDown = SIGNAL,
  9866. OnUp = SIGNAL,
  9867. AllowedButtons = {1}
  9868. }
  9869. local funcs = {}
  9870. local tableFind = table.find
  9871.  
  9872. funcs.Trigger = function(self,event,button)
  9873. if not self.Disabled and tableFind(self.AllowedButtons,button) then
  9874. self["On"..event]:Fire(button)
  9875. end
  9876. end
  9877.  
  9878. funcs.SetDisabled = function(self,dis)
  9879. self.Disabled = dis
  9880.  
  9881. if dis then
  9882. self.Anim:Disable()
  9883. self.Gui.TextTransparency = 0.5
  9884. else
  9885. self.Anim.Enable()
  9886. self.Gui.TextTransparency = 0
  9887. end
  9888. end
  9889.  
  9890. local mt = getGuiMT(props,funcs)
  9891.  
  9892. local function new()
  9893. local b = Instance.new("TextButton")
  9894. b.AutoButtonColor = false
  9895. b.TextColor3 = Settings.Theme.Text
  9896. b.TextTransparency = 0.1
  9897. b.Size = UDim2.new(0,100,0,20)
  9898. b.Font = Enum.Font.SourceSans
  9899. b.TextSize = 14
  9900. b.BackgroundColor3 = Settings.Theme.Button
  9901. b.BorderColor3 = Settings.Theme.Outline2
  9902.  
  9903. local obj = initObj(props,mt)
  9904. obj.Gui = b
  9905. obj.Anim = Lib.ButtonAnim(b,{Mode = 2, StartColor = Settings.Theme.Button, HoverColor = Settings.Theme.ButtonHover, PressColor = Settings.Theme.ButtonPress, OutlineColor = Settings.Theme.Outline2})
  9906.  
  9907. b.MouseButton1Click:Connect(function() obj:Trigger("Click",1) end)
  9908. b.MouseButton1Down:Connect(function() obj:Trigger("Down",1) end)
  9909. b.MouseButton1Up:Connect(function() obj:Trigger("Up",1) end)
  9910.  
  9911. b.MouseButton2Click:Connect(function() obj:Trigger("Click",2) end)
  9912. b.MouseButton2Down:Connect(function() obj:Trigger("Down",2) end)
  9913. b.MouseButton2Up:Connect(function() obj:Trigger("Up",2) end)
  9914.  
  9915. return obj
  9916. end
  9917.  
  9918. return {new = new}
  9919. end)()
  9920.  
  9921. Lib.DropDown = (function()
  9922. local props = {
  9923. Gui = PH,
  9924. Anim = PH,
  9925. Context = PH,
  9926. Selected = PH,
  9927. Disabled = false,
  9928. CanBeEmpty = true,
  9929. Options = {},
  9930. GuiElems = {},
  9931. OnSelect = SIGNAL
  9932. }
  9933. local funcs = {}
  9934.  
  9935. funcs.Update = function(self)
  9936. local options = self.Options
  9937.  
  9938. if #options > 0 then
  9939. if not self.Selected then
  9940. if not self.CanBeEmpty then
  9941. self.Selected = options[1]
  9942. self.GuiElems.Label.Text = options[1]
  9943. else
  9944. self.GuiElems.Label.Text = "- Select -"
  9945. end
  9946. else
  9947. self.GuiElems.Label.Text = self.Selected
  9948. end
  9949. else
  9950. self.GuiElems.Label.Text = "- Select -"
  9951. end
  9952. end
  9953.  
  9954. funcs.ShowOptions = function(self)
  9955. local context = self.Context
  9956.  
  9957. context.Width = self.Gui.AbsoluteSize.X
  9958. context.ReverseYOffset = self.Gui.AbsoluteSize.Y
  9959. context:Show(self.Gui.AbsolutePosition.X, self.Gui.AbsolutePosition.Y + context.ReverseYOffset)
  9960. end
  9961.  
  9962. funcs.SetOptions = function(self,opts)
  9963. self.Options = opts
  9964.  
  9965. local context = self.Context
  9966. local options = self.Options
  9967. context:Clear()
  9968.  
  9969. local onClick = function(option) self.Selected = option self.OnSelect:Fire(option) self:Update() end
  9970.  
  9971. if self.CanBeEmpty then
  9972. context:Add({Name = "- Select -", OnClick = function() self.Selected = nil self.OnSelect:Fire(nil) self:Update() end})
  9973. end
  9974.  
  9975. for i = 1,#options do
  9976. context:Add({Name = options[i], OnClick = onClick})
  9977. end
  9978.  
  9979. self:Update()
  9980. end
  9981.  
  9982. funcs.SetSelected = function(self,opt)
  9983. self.Selected = type(opt) == "number" and self.Options[opt] or opt
  9984. self:Update()
  9985. end
  9986.  
  9987. local mt = getGuiMT(props,funcs)
  9988.  
  9989. local function new()
  9990. local f = Instance.new("TextButton")
  9991. f.AutoButtonColor = false
  9992. f.Text = ""
  9993. f.Size = UDim2.new(0,100,0,20)
  9994. f.BackgroundColor3 = Settings.Theme.TextBox
  9995. f.BorderColor3 = Settings.Theme.Outline3
  9996.  
  9997. local label = Lib.Label.new()
  9998. label.Position = UDim2.new(0,2,0,0)
  9999. label.Size = UDim2.new(1,-22,1,0)
  10000. label.TextTruncate = Enum.TextTruncate.AtEnd
  10001. label.Parent = f
  10002. local arrow = create({
  10003. {1,"Frame",{BackgroundTransparency=1,Name="EnumArrow",Position=UDim2.new(1,-16,0,2),Size=UDim2.new(0,16,0,16),}},
  10004. {2,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,8,0,9),Size=UDim2.new(0,1,0,1),}},
  10005. {3,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,7,0,8),Size=UDim2.new(0,3,0,1),}},
  10006. {4,"Frame",{BackgroundColor3=Color3.new(0.86274510622025,0.86274510622025,0.86274510622025),BorderSizePixel=0,Parent={1},Position=UDim2.new(0,6,0,7),Size=UDim2.new(0,5,0,1),}},
  10007. })
  10008. arrow.Parent = f
  10009.  
  10010. local obj = initObj(props,mt)
  10011. obj.Gui = f
  10012. obj.Anim = Lib.ButtonAnim(f,{Mode = 2, StartColor = Settings.Theme.TextBox, LerpTo = Settings.Theme.Button, LerpDelta = 0.15})
  10013. obj.Context = Lib.ContextMenu.new()
  10014. obj.Context.Iconless = true
  10015. obj.Context.MaxHeight = 200
  10016. obj.Selected = nil
  10017. obj.GuiElems = {Label = label}
  10018. f.MouseButton1Down:Connect(function() obj:ShowOptions() end)
  10019. obj:Update()
  10020. return obj
  10021. end
  10022.  
  10023. return {new = new}
  10024. end)()
  10025.  
  10026. Lib.ClickSystem = (function()
  10027. local props = {
  10028. LastItem = PH,
  10029. OnDown = SIGNAL,
  10030. OnRelease = SIGNAL,
  10031. AllowedButtons = {1},
  10032. Combo = 0,
  10033. MaxCombo = 2,
  10034. ComboTime = 0.5,
  10035. Items = {},
  10036. ItemCons = {},
  10037. ClickId = -1,
  10038. LastButton = ""
  10039. }
  10040. local funcs = {}
  10041. local tostring = tostring
  10042.  
  10043. local disconnect = function(con)
  10044. local pos = table.find(con.Signal.Connections,con)
  10045. if pos then table.remove(con.Signal.Connections,pos) end
  10046. end
  10047.  
  10048. funcs.Trigger = function(self,item,button)
  10049. if table.find(self.AllowedButtons,button) then
  10050. if self.LastButton ~= button or self.LastItem ~= item or self.Combo == self.MaxCombo or tick() - self.ClickId > self.ComboTime then
  10051. self.Combo = 0
  10052. self.LastButton = button
  10053. self.LastItem = item
  10054. end
  10055. self.Combo = self.Combo + 1
  10056. self.ClickId = tick()
  10057.  
  10058. local release
  10059. release = service.UserInputService.InputEnded:Connect(function(input)
  10060. if input.UserInputType == Enum.UserInputType["MouseButton"..button] then
  10061. release:Disconnect()
  10062. if Lib.CheckMouseInGui(item) and self.LastButton == button and self.LastItem == item then
  10063. self["OnRelease"]:Fire(item,self.Combo,button)
  10064. end
  10065. end
  10066. end)
  10067.  
  10068. self["OnDown"]:Fire(item,self.Combo,button)
  10069. end
  10070. end
  10071.  
  10072. funcs.Add = function(self,item)
  10073. if table.find(self.Items,item) then return end
  10074.  
  10075. local cons = {}
  10076. cons[1] = item.MouseButton1Down:Connect(function() self:Trigger(item,1) end)
  10077. cons[2] = item.MouseButton2Down:Connect(function() self:Trigger(item,2) end)
  10078.  
  10079. self.ItemCons[item] = cons
  10080. self.Items[#self.Items+1] = item
  10081. end
  10082.  
  10083. funcs.Remove = function(self,item)
  10084. local ind = table.find(self.Items,item)
  10085. if not ind then return end
  10086.  
  10087. for i,v in pairs(self.ItemCons[item]) do
  10088. v:Disconnect()
  10089. end
  10090. self.ItemCons[item] = nil
  10091. table.remove(self.Items,ind)
  10092. end
  10093.  
  10094. local mt = {__index = funcs}
  10095.  
  10096. local function new()
  10097. local obj = initObj(props,mt)
  10098.  
  10099. return obj
  10100. end
  10101.  
  10102. return {new = new}
  10103. end)()
  10104.  
  10105. return Lib
  10106. end
  10107.  
  10108. return {InitDeps = initDeps, InitAfterMain = initAfterMain, Main = main}
  10109. end
  10110. }
  10111.  
  10112. -- Main vars
  10113. local Main, Explorer, Properties, ScriptViewer, DefaultSettings, Notebook, Serializer, Lib
  10114. local API, RMD
  10115.  
  10116. -- Default Settings
  10117. DefaultSettings = (function()
  10118. local rgb = Color3.fromRGB
  10119. return {
  10120. Explorer = {
  10121. _Recurse = true,
  10122. Sorting = true,
  10123. TeleportToOffset = Vector3.new(0,0,0),
  10124. ClickToRename = true,
  10125. AutoUpdateSearch = true,
  10126. AutoUpdateMode = 0, -- 0 Default, 1 no tree update, 2 no descendant events, 3 frozen
  10127. PartSelectionBox = true,
  10128. GuiSelectionBox = true,
  10129. CopyPathUseGetChildren = true
  10130. },
  10131. Properties = {
  10132. _Recurse = true,
  10133. MaxConflictCheck = 50,
  10134. ShowDeprecated = false,
  10135. ShowHidden = false,
  10136. ClearOnFocus = false,
  10137. LoadstringInput = true,
  10138. NumberRounding = 3,
  10139. ShowAttributes = false,
  10140. MaxAttributes = 50,
  10141. ScaleType = 1 -- 0 Full Name Shown, 1 Equal Halves
  10142. },
  10143. Theme = {
  10144. _Recurse = true,
  10145. Main1 = rgb(52,52,52),
  10146. Main2 = rgb(45,45,45),
  10147. Outline1 = rgb(33,33,33), -- Mainly frames
  10148. Outline2 = rgb(55,55,55), -- Mainly button
  10149. Outline3 = rgb(30,30,30), -- Mainly textbox
  10150. TextBox = rgb(38,38,38),
  10151. Menu = rgb(32,32,32),
  10152. ListSelection = rgb(11,90,175),
  10153. Button = rgb(60,60,60),
  10154. ButtonHover = rgb(68,68,68),
  10155. ButtonPress = rgb(40,40,40),
  10156. Highlight = rgb(75,75,75),
  10157. Text = rgb(255,255,255),
  10158. PlaceholderText = rgb(100,100,100),
  10159. Important = rgb(255,0,0),
  10160. ExplorerIconMap = "",
  10161. MiscIconMap = "",
  10162. Syntax = {
  10163. Text = rgb(204,204,204),
  10164. Background = rgb(36,36,36),
  10165. Selection = rgb(255,255,255),
  10166. SelectionBack = rgb(11,90,175),
  10167. Operator = rgb(204,204,204),
  10168. Number = rgb(255,198,0),
  10169. String = rgb(173,241,149),
  10170. Comment = rgb(102,102,102),
  10171. Keyword = rgb(248,109,124),
  10172. Error = rgb(255,0,0),
  10173. FindBackground = rgb(141,118,0),
  10174. MatchingWord = rgb(85,85,85),
  10175. BuiltIn = rgb(132,214,247),
  10176. CurrentLine = rgb(45,50,65),
  10177. LocalMethod = rgb(253,251,172),
  10178. LocalProperty = rgb(97,161,241),
  10179. Nil = rgb(255,198,0),
  10180. Bool = rgb(255,198,0),
  10181. Function = rgb(248,109,124),
  10182. Local = rgb(248,109,124),
  10183. Self = rgb(248,109,124),
  10184. FunctionName = rgb(253,251,172),
  10185. Bracket = rgb(204,204,204)
  10186. },
  10187. }
  10188. }
  10189. end)()
  10190.  
  10191. -- Vars
  10192. local Settings = {}
  10193. local Apps = {}
  10194. local env = {}
  10195. local service = setmetatable({},{__index = function(self,name)
  10196. local serv = clonerefs(game:GetService(name))
  10197. self[name] = serv
  10198. return serv
  10199. end})
  10200. local plr = service.Players.LocalPlayer or service.Players.PlayerAdded:wait()
  10201.  
  10202. local create = function(data)
  10203. local insts = {}
  10204. for i,v in pairs(data) do insts[v[1]] = Instance.new(v[2]) end
  10205.  
  10206. for _,v in pairs(data) do
  10207. for prop,val in pairs(v[3]) do
  10208. if type(val) == "table" then
  10209. insts[v[1]][prop] = insts[val[1]]
  10210. else
  10211. insts[v[1]][prop] = val
  10212. end
  10213. end
  10214. end
  10215.  
  10216. return insts[1]
  10217. end
  10218.  
  10219. local createSimple = function(class,props)
  10220. local inst = Instance.new(class)
  10221. for i,v in next,props do
  10222. inst[i] = v
  10223. end
  10224. return inst
  10225. end
  10226.  
  10227. Main = (function()
  10228. local Main = {}
  10229.  
  10230. Main.ModuleList = {"Explorer","Properties","ScriptViewer"}
  10231. Main.Elevated = false
  10232. Main.MissingEnv = {}
  10233. Main.Version = "" -- Beta 1.0.0
  10234. Main.Mouse = plr:GetMouse()
  10235. Main.AppControls = {}
  10236. Main.Apps = Apps
  10237. Main.MenuApps = {}
  10238.  
  10239. Main.DisplayOrders = {
  10240. SideWindow = 8,
  10241. Window = 10,
  10242. Menu = 100000,
  10243. Core = 101000
  10244. }
  10245.  
  10246. Main.GetInitDeps = function()
  10247. return {
  10248. Main = Main,
  10249. Lib = Lib,
  10250. Apps = Apps,
  10251. Settings = Settings,
  10252.  
  10253. API = API,
  10254. RMD = RMD,
  10255. env = env,
  10256. service = service,
  10257. plr = plr,
  10258. create = create,
  10259. createSimple = createSimple
  10260. }
  10261. end
  10262.  
  10263. Main.Error = function(str)
  10264. if rconsoleprint then
  10265. rconsoleprint("DEX ERROR: "..tostring(str).."\n")
  10266. wait(9e9)
  10267. else
  10268. error(str)
  10269. end
  10270. end
  10271.  
  10272. Main.LoadModule = function(name)
  10273. if Main.Elevated then -- If you don't have filesystem api then ur outta luck tbh
  10274. local control
  10275.  
  10276. if EmbeddedModules then -- Offline Modules
  10277. control = EmbeddedModules[name]()
  10278.  
  10279. if not control then Main.Error("Missing Embedded Module: "..name) end
  10280. end
  10281.  
  10282. Main.AppControls[name] = control
  10283. control.InitDeps(Main.GetInitDeps())
  10284.  
  10285. local moduleData = control.Main()
  10286. Apps[name] = moduleData
  10287. return moduleData
  10288. else
  10289. local module = script:WaitForChild("Modules"):WaitForChild(name,2)
  10290. if not module then Main.Error("CANNOT FIND MODULE "..name) end
  10291.  
  10292. local control = require(module)
  10293. Main.AppControls[name] = control
  10294. control.InitDeps(Main.GetInitDeps())
  10295.  
  10296. local moduleData = control.Main()
  10297. Apps[name] = moduleData
  10298. return moduleData
  10299. end
  10300. end
  10301.  
  10302. Main.LoadModules = function()
  10303. for i,v in pairs(Main.ModuleList) do
  10304. local s,e = pcall(Main.LoadModule,v)
  10305. if not s then
  10306. Main.Error("FAILED LOADING " + v + " CAUSE " + e)
  10307. end
  10308. end
  10309.  
  10310. -- Init Major Apps and define them in modules
  10311. Explorer = Apps.Explorer
  10312. Properties = Apps.Properties
  10313. ScriptViewer = Apps.ScriptViewer
  10314. Notebook = Apps.Notebook
  10315. local appTable = {
  10316. Explorer = Explorer,
  10317. Properties = Properties,
  10318. ScriptViewer = ScriptViewer,
  10319. Notebook = Notebook
  10320. }
  10321.  
  10322. Main.AppControls.Lib.InitAfterMain(appTable)
  10323. for i,v in pairs(Main.ModuleList) do
  10324. local control = Main.AppControls[v]
  10325. if control then
  10326. control.InitAfterMain(appTable)
  10327. end
  10328. end
  10329. end
  10330.  
  10331. Main.InitEnv = function()
  10332. setmetatable(env, {__newindex = function(self, name, func)
  10333. if not func then Main.MissingEnv[#Main.MissingEnv + 1] = name return end
  10334. rawset(self, name, func)
  10335. end})
  10336.  
  10337. -- file
  10338. env.readfile = readfile
  10339. env.writefile = writefile
  10340. env.appendfile = appendfile
  10341. env.makefolder = makefolder
  10342. env.listfiles = listfiles
  10343. env.loadfile = loadfile
  10344. env.saveinstance = saveinstance
  10345.  
  10346. -- debug
  10347. env.getupvalues = debug.getupvalues or getupvals
  10348. env.getconstants = debug.getconstants or getconsts
  10349. env.islclosure = islclosure or is_l_closure
  10350. env.checkcaller = checkcaller
  10351. env.getreg = getreg
  10352. env.getgc = getgc
  10353.  
  10354. -- other
  10355. env.setfflag = setfflag
  10356. env.decompile = decompile
  10357. env.protectgui = protect_gui or (syn and syn.protect_gui)
  10358. env.gethui = gethui
  10359. env.setclipboard = setclipboard
  10360. env.getnilinstances = getnilinstances or get_nil_instances
  10361. env.getloadedmodules = getloadedmodules
  10362.  
  10363. if identifyexecutor then Main.Executor = identifyexecutor() end
  10364.  
  10365. Main.GuiHolder = Main.Elevated and service.CoreGui or plr:FindFirstChildOfClass("PlayerGui")
  10366.  
  10367. setmetatable(env, nil)
  10368. end
  10369.  
  10370. Main.LoadSettings = function()
  10371. local s,data = pcall(env.readfile or error,"DexSettings.json")
  10372. if s and data and data ~= "" then
  10373. local s,decoded = service.HttpService:JSONDecode(data)
  10374. if s and decoded then
  10375. for i,v in next,decoded do
  10376.  
  10377. end
  10378. else
  10379. -- TODO: Notification
  10380. end
  10381. else
  10382. Main.ResetSettings()
  10383. end
  10384. end
  10385.  
  10386. Main.ResetSettings = function()
  10387. local function recur(t,res)
  10388. for set,val in pairs(t) do
  10389. if type(val) == "table" and val._Recurse then
  10390. if type(res[set]) ~= "table" then
  10391. res[set] = {}
  10392. end
  10393. recur(val,res[set])
  10394. else
  10395. res[set] = val
  10396. end
  10397. end
  10398. return res
  10399. end
  10400. recur(DefaultSettings,Settings)
  10401. end
  10402.  
  10403. Main.FetchAPI = function()
  10404. local api,rawAPI
  10405. if Main.Elevated then
  10406. if Main.LocalDepsUpToDate() then
  10407. local localAPI = Lib.ReadFile("dex/rbx_api.dat")
  10408. if localAPI then
  10409. rawAPI = localAPI
  10410. else
  10411. Main.DepsVersionData[1] = ""
  10412. end
  10413. end
  10414. rawAPI = rawAPI or game:HttpGet("http://setup.roblox.com/"..Main.RobloxVersion.."-API-Dump.json")
  10415. else
  10416. if script:FindFirstChild("API") then
  10417. rawAPI = require(script.API)
  10418. else
  10419. error("NO API EXISTS")
  10420. end
  10421. end
  10422. Main.RawAPI = rawAPI
  10423. api = service.HttpService:JSONDecode(rawAPI)
  10424.  
  10425. local classes,enums = {},{}
  10426. local categoryOrder,seenCategories = {},{}
  10427.  
  10428. local function insertAbove(t,item,aboveItem)
  10429. local findPos = table.find(t,item)
  10430. if not findPos then return end
  10431. table.remove(t,findPos)
  10432.  
  10433. local pos = table.find(t,aboveItem)
  10434. if not pos then return end
  10435. table.insert(t,pos,item)
  10436. end
  10437.  
  10438. for _,class in pairs(api.Classes) do
  10439. local newClass = {}
  10440. newClass.Name = class.Name
  10441. newClass.Superclass = class.Superclass
  10442. newClass.Properties = {}
  10443. newClass.Functions = {}
  10444. newClass.Events = {}
  10445. newClass.Callbacks = {}
  10446. newClass.Tags = {}
  10447.  
  10448. if class.Tags then for c,tag in pairs(class.Tags) do newClass.Tags[tag] = true end end
  10449. for __,member in pairs(class.Members) do
  10450. local newMember = {}
  10451. newMember.Name = member.Name
  10452. newMember.Class = class.Name
  10453. newMember.Security = member.Security
  10454. newMember.Tags ={}
  10455. if member.Tags then for c,tag in pairs(member.Tags) do newMember.Tags[tag] = true end end
  10456.  
  10457. local mType = member.MemberType
  10458. if mType == "Property" then
  10459. local propCategory = member.Category or "Other"
  10460. propCategory = propCategory:match("^%s*(.-)%s*$")
  10461. if not seenCategories[propCategory] then
  10462. categoryOrder[#categoryOrder+1] = propCategory
  10463. seenCategories[propCategory] = true
  10464. end
  10465. newMember.ValueType = member.ValueType
  10466. newMember.Category = propCategory
  10467. newMember.Serialization = member.Serialization
  10468. table.insert(newClass.Properties,newMember)
  10469. elseif mType == "Function" then
  10470. newMember.Parameters = {}
  10471. newMember.ReturnType = member.ReturnType.Name
  10472. for c,param in pairs(member.Parameters) do
  10473. table.insert(newMember.Parameters,{Name = param.Name, Type = param.Type.Name})
  10474. end
  10475. table.insert(newClass.Functions,newMember)
  10476. elseif mType == "Event" then
  10477. newMember.Parameters = {}
  10478. for c,param in pairs(member.Parameters) do
  10479. table.insert(newMember.Parameters,{Name = param.Name, Type = param.Type.Name})
  10480. end
  10481. table.insert(newClass.Events,newMember)
  10482. end
  10483. end
  10484.  
  10485. classes[class.Name] = newClass
  10486. end
  10487.  
  10488. for _,class in pairs(classes) do
  10489. class.Superclass = classes[class.Superclass]
  10490. end
  10491.  
  10492. for _,enum in pairs(api.Enums) do
  10493. local newEnum = {}
  10494. newEnum.Name = enum.Name
  10495. newEnum.Items = {}
  10496. newEnum.Tags = {}
  10497.  
  10498. if enum.Tags then for c,tag in pairs(enum.Tags) do newEnum.Tags[tag] = true end end
  10499. for __,item in pairs(enum.Items) do
  10500. local newItem = {}
  10501. newItem.Name = item.Name
  10502. newItem.Value = item.Value
  10503. table.insert(newEnum.Items,newItem)
  10504. end
  10505.  
  10506. enums[enum.Name] = newEnum
  10507. end
  10508.  
  10509. local function getMember(class,member)
  10510. if not classes[class] or not classes[class][member] then return end
  10511. local result = {}
  10512.  
  10513. local currentClass = classes[class]
  10514. while currentClass do
  10515. for _,entry in pairs(currentClass[member]) do
  10516. result[#result+1] = entry
  10517. end
  10518. currentClass = currentClass.Superclass
  10519. end
  10520.  
  10521. table.sort(result,function(a,b) return a.Name < b.Name end)
  10522. return result
  10523. end
  10524.  
  10525. insertAbove(categoryOrder,"Behavior","Tuning")
  10526. insertAbove(categoryOrder,"Appearance","Data")
  10527. insertAbove(categoryOrder,"Attachments","Axes")
  10528. insertAbove(categoryOrder,"Cylinder","Slider")
  10529. insertAbove(categoryOrder,"Localization","Jump Settings")
  10530. insertAbove(categoryOrder,"Surface","Motion")
  10531. insertAbove(categoryOrder,"Surface Inputs","Surface")
  10532. insertAbove(categoryOrder,"Part","Surface Inputs")
  10533. insertAbove(categoryOrder,"Assembly","Surface Inputs")
  10534. insertAbove(categoryOrder,"Character","Controls")
  10535. categoryOrder[#categoryOrder+1] = "Unscriptable"
  10536. categoryOrder[#categoryOrder+1] = "Attributes"
  10537.  
  10538. local categoryOrderMap = {}
  10539. for i = 1,#categoryOrder do
  10540. categoryOrderMap[categoryOrder[i]] = i
  10541. end
  10542.  
  10543. return {
  10544. Classes = classes,
  10545. Enums = enums,
  10546. CategoryOrder = categoryOrderMap,
  10547. GetMember = getMember
  10548. }
  10549. end
  10550.  
  10551. Main.FetchRMD = function()
  10552. local rawXML
  10553. if Main.Elevated then
  10554. if Main.LocalDepsUpToDate() then
  10555. local localRMD = Lib.ReadFile("dex/rbx_rmd.dat")
  10556. if localRMD then
  10557. rawXML = localRMD
  10558. else
  10559. Main.DepsVersionData[1] = ""
  10560. end
  10561. end
  10562. rawXML = rawXML or game:HttpGet("https://raw.githubusercontent.com/CloneTrooper1019/Roblox-Client-Tracker/roblox/ReflectionMetadata.xml")
  10563. else
  10564. if script:FindFirstChild("RMD") then
  10565. rawXML = require(script.RMD)
  10566. else
  10567. error("NO RMD EXISTS")
  10568. end
  10569. end
  10570. Main.RawRMD = rawXML
  10571. local parsed = Lib.ParseXML(rawXML)
  10572. local classList = parsed.children[1].children[1].children
  10573. local enumList = parsed.children[1].children[2].children
  10574. local propertyOrders = {}
  10575.  
  10576. local classes,enums = {},{}
  10577. for _,class in pairs(classList) do
  10578. local className = ""
  10579. for _,child in pairs(class.children) do
  10580. if child.tag == "Properties" then
  10581. local data = {Properties = {}, Functions = {}}
  10582. local props = child.children
  10583. for _,prop in pairs(props) do
  10584. local name = prop.attrs.name
  10585. name = name:sub(1,1):upper()..name:sub(2)
  10586. data[name] = prop.children[1].text
  10587. end
  10588. className = data.Name
  10589. classes[className] = data
  10590. elseif child.attrs.class == "ReflectionMetadataProperties" then
  10591. local members = child.children
  10592. for _,member in pairs(members) do
  10593. if member.attrs.class == "ReflectionMetadataMember" then
  10594. local data = {}
  10595. if member.children[1].tag == "Properties" then
  10596. local props = member.children[1].children
  10597. for _,prop in pairs(props) do
  10598. if prop.attrs then
  10599. local name = prop.attrs.name
  10600. name = name:sub(1,1):upper()..name:sub(2)
  10601. data[name] = prop.children[1].text
  10602. end
  10603. end
  10604. if data.PropertyOrder then
  10605. local orders = propertyOrders[className]
  10606. if not orders then orders = {} propertyOrders[className] = orders end
  10607. orders[data.Name] = tonumber(data.PropertyOrder)
  10608. end
  10609. classes[className].Properties[data.Name] = data
  10610. end
  10611. end
  10612. end
  10613. elseif child.attrs.class == "ReflectionMetadataFunctions" then
  10614. local members = child.children
  10615. for _,member in pairs(members) do
  10616. if member.attrs.class == "ReflectionMetadataMember" then
  10617. local data = {}
  10618. if member.children[1].tag == "Properties" then
  10619. local props = member.children[1].children
  10620. for _,prop in pairs(props) do
  10621. if prop.attrs then
  10622. local name = prop.attrs.name
  10623. name = name:sub(1,1):upper()..name:sub(2)
  10624. data[name] = prop.children[1].text
  10625. end
  10626. end
  10627. classes[className].Functions[data.Name] = data
  10628. end
  10629. end
  10630. end
  10631. end
  10632. end
  10633. end
  10634.  
  10635. for _,enum in pairs(enumList) do
  10636. local enumName = ""
  10637. for _,child in pairs(enum.children) do
  10638. if child.tag == "Properties" then
  10639. local data = {Items = {}}
  10640. local props = child.children
  10641. for _,prop in pairs(props) do
  10642. local name = prop.attrs.name
  10643. name = name:sub(1,1):upper()..name:sub(2)
  10644. data[name] = prop.children[1].text
  10645. end
  10646. enumName = data.Name
  10647. enums[enumName] = data
  10648. elseif child.attrs.class == "ReflectionMetadataEnumItem" then
  10649. local data = {}
  10650. if child.children[1].tag == "Properties" then
  10651. local props = child.children[1].children
  10652. for _,prop in pairs(props) do
  10653. local name = prop.attrs.name
  10654. name = name:sub(1,1):upper()..name:sub(2)
  10655. data[name] = prop.children[1].text
  10656. end
  10657. enums[enumName].Items[data.Name] = data
  10658. end
  10659. end
  10660. end
  10661. end
  10662.  
  10663. return {Classes = classes, Enums = enums, PropertyOrders = propertyOrders}
  10664. end
  10665.  
  10666. Main.ShowGui = function(gui)
  10667. if env.protectgui then
  10668. env.protectgui(gui)
  10669. end
  10670. gui.Parent = Main.GuiHolder
  10671. end
  10672.  
  10673. Main.CreateIntro = function(initStatus) -- TODO: Must theme and show errors
  10674. local gui = create({
  10675. {1,"ScreenGui",{Name="Intro",}},
  10676. {2,"Frame",{Active=true,BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="Main",Parent={1},Position=UDim2.new(0.5,-175,0.5,-100),Size=UDim2.new(0,350,0,200),}},
  10677. {3,"Frame",{BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,ClipsDescendants=true,Name="Holder",Parent={2},Size=UDim2.new(1,0,1,0),}},
  10678. {4,"UIGradient",{Parent={3},Rotation=30,Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10679. {5,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=4,Name="Title",Parent={3},Position=UDim2.new(0,-190,0,15),Size=UDim2.new(0,100,0,50),Text="Dex",TextColor3=Color3.new(1,1,1),TextSize=50,TextTransparency=1,}},
  10680. {6,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Desc",Parent={3},Position=UDim2.new(0,-230,0,60),Size=UDim2.new(0,180,0,25),Text="Ultimate Debugging Suite",TextColor3=Color3.new(1,1,1),TextSize=18,TextTransparency=1,}},
  10681. {7,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="StatusText",Parent={3},Position=UDim2.new(0,20,0,110),Size=UDim2.new(0,180,0,25),Text="Fetching API",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=1,}},
  10682. {8,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="ProgressBar",Parent={3},Position=UDim2.new(0,110,0,145),Size=UDim2.new(0,0,0,4),}},
  10683. {9,"Frame",{BackgroundColor3=Color3.new(0.2392156869173,0.56078433990479,0.86274510622025),BorderSizePixel=0,Name="Bar",Parent={8},Size=UDim2.new(0,0,1,0),}},
  10684. {10,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://2764171053",ImageColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),Parent={8},ScaleType=1,Size=UDim2.new(1,0,1,0),SliceCenter=Rect.new(2,2,254,254),}},
  10685. {11,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Creator",Parent={2},Position=UDim2.new(1,-110,1,-20),Size=UDim2.new(0,105,0,20),Text="Developed by Moon",TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=1,}},
  10686. {12,"UIGradient",{Parent={11},Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10687. {13,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Version",Parent={2},Position=UDim2.new(1,-110,1,-35),Size=UDim2.new(0,105,0,20),Text=Main.Version,TextColor3=Color3.new(1,1,1),TextSize=14,TextXAlignment=1,}},
  10688. {14,"UIGradient",{Parent={13},Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10689. {15,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Image="rbxassetid://1427967925",Name="Outlines",Parent={2},Position=UDim2.new(0,-5,0,-5),ScaleType=1,Size=UDim2.new(1,10,1,10),SliceCenter=Rect.new(6,6,25,25),TileSize=UDim2.new(0,20,0,20),}},
  10690. {16,"UIGradient",{Parent={15},Rotation=-30,Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10691. {17,"UIGradient",{Parent={2},Rotation=-30,Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1,0),NumberSequenceKeypoint.new(1,1,0),}),}},
  10692. })
  10693. Main.ShowGui(gui)
  10694. local backGradient = gui.Main.UIGradient
  10695. local outlinesGradient = gui.Main.Outlines.UIGradient
  10696. local holderGradient = gui.Main.Holder.UIGradient
  10697. local titleText = gui.Main.Holder.Title
  10698. local descText = gui.Main.Holder.Desc
  10699. local versionText = gui.Main.Version
  10700. local versionGradient = versionText.UIGradient
  10701. local creatorText = gui.Main.Creator
  10702. local creatorGradient = creatorText.UIGradient
  10703. local statusText = gui.Main.Holder.StatusText
  10704. local progressBar = gui.Main.Holder.ProgressBar
  10705. local tweenS = service.TweenService
  10706.  
  10707. local renderStepped = service.RunService.RenderStepped
  10708. local signalWait = renderStepped.wait
  10709. local fastwait = function(s)
  10710. if not s then return signalWait(renderStepped) end
  10711. local start = tick()
  10712. while tick() - start < s do signalWait(renderStepped) end
  10713. end
  10714.  
  10715. statusText.Text = initStatus
  10716.  
  10717. local function tweenNumber(n,ti,func)
  10718. local tweenVal = Instance.new("IntValue")
  10719. tweenVal.Value = 0
  10720. tweenVal.Changed:Connect(func)
  10721. local tween = tweenS:Create(tweenVal,ti,{Value = n})
  10722. tween:Play()
  10723. tween.Completed:Connect(function()
  10724. tweenVal:Destroy()
  10725. end)
  10726. end
  10727.  
  10728. local ti = TweenInfo.new(0.4,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  10729. tweenNumber(100,ti,function(val)
  10730. val = val/200
  10731. local start = NumberSequenceKeypoint.new(0,0)
  10732. local a1 = NumberSequenceKeypoint.new(val,0)
  10733. local a2 = NumberSequenceKeypoint.new(math.min(0.5,val+math.min(0.05,val)),1)
  10734. if a1.Time == a2.Time then a2 = a1 end
  10735. local b1 = NumberSequenceKeypoint.new(1-val,0)
  10736. local b2 = NumberSequenceKeypoint.new(math.max(0.5,1-val-math.min(0.05,val)),1)
  10737. if b1.Time == b2.Time then b2 = b1 end
  10738. local goal = NumberSequenceKeypoint.new(1,0)
  10739. backGradient.Transparency = NumberSequence.new({start,a1,a2,b2,b1,goal})
  10740. outlinesGradient.Transparency = NumberSequence.new({start,a1,a2,b2,b1,goal})
  10741. end)
  10742.  
  10743. fastwait(0.4)
  10744.  
  10745. tweenNumber(100,ti,function(val)
  10746. val = val/166.66
  10747. local start = NumberSequenceKeypoint.new(0,0)
  10748. local a1 = NumberSequenceKeypoint.new(val,0)
  10749. local a2 = NumberSequenceKeypoint.new(val+0.01,1)
  10750. local goal = NumberSequenceKeypoint.new(1,1)
  10751. holderGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  10752. end)
  10753.  
  10754. tweenS:Create(titleText,ti,{Position = UDim2.new(0,60,0,15), TextTransparency = 0}):Play()
  10755. tweenS:Create(descText,ti,{Position = UDim2.new(0,20,0,60), TextTransparency = 0}):Play()
  10756.  
  10757. local function rightTextTransparency(obj)
  10758. tweenNumber(100,ti,function(val)
  10759. val = val/100
  10760. local a1 = NumberSequenceKeypoint.new(1-val,0)
  10761. local a2 = NumberSequenceKeypoint.new(math.max(0,1-val-0.01),1)
  10762. if a1.Time == a2.Time then a2 = a1 end
  10763. local start = NumberSequenceKeypoint.new(0,a1 == a2 and 0 or 1)
  10764. local goal = NumberSequenceKeypoint.new(1,0)
  10765. obj.Transparency = NumberSequence.new({start,a2,a1,goal})
  10766. end)
  10767. end
  10768. rightTextTransparency(versionGradient)
  10769. rightTextTransparency(creatorGradient)
  10770.  
  10771. fastwait(0.9)
  10772.  
  10773. local progressTI = TweenInfo.new(0.25,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
  10774.  
  10775. tweenS:Create(statusText,progressTI,{Position = UDim2.new(0,20,0,120), TextTransparency = 0}):Play()
  10776. tweenS:Create(progressBar,progressTI,{Position = UDim2.new(0,60,0,145), Size = UDim2.new(0,100,0,4)}):Play()
  10777.  
  10778. fastwait(0.25)
  10779.  
  10780. local function setProgress(text,n)
  10781. statusText.Text = text
  10782. tweenS:Create(progressBar.Bar,progressTI,{Size = UDim2.new(n,0,1,0)}):Play()
  10783. end
  10784.  
  10785. local function close()
  10786. tweenS:Create(titleText,progressTI,{TextTransparency = 1}):Play()
  10787. tweenS:Create(descText,progressTI,{TextTransparency = 1}):Play()
  10788. tweenS:Create(versionText,progressTI,{TextTransparency = 1}):Play()
  10789. tweenS:Create(creatorText,progressTI,{TextTransparency = 1}):Play()
  10790. tweenS:Create(statusText,progressTI,{TextTransparency = 1}):Play()
  10791. tweenS:Create(progressBar,progressTI,{BackgroundTransparency = 1}):Play()
  10792. tweenS:Create(progressBar.Bar,progressTI,{BackgroundTransparency = 1}):Play()
  10793. tweenS:Create(progressBar.ImageLabel,progressTI,{ImageTransparency = 1}):Play()
  10794.  
  10795. tweenNumber(100,TweenInfo.new(0.4,Enum.EasingStyle.Back,Enum.EasingDirection.In),function(val)
  10796. val = val/250
  10797. local start = NumberSequenceKeypoint.new(0,0)
  10798. local a1 = NumberSequenceKeypoint.new(0.6+val,0)
  10799. local a2 = NumberSequenceKeypoint.new(math.min(1,0.601+val),1)
  10800. if a1.Time == a2.Time then a2 = a1 end
  10801. local goal = NumberSequenceKeypoint.new(1,a1 == a2 and 0 or 1)
  10802. holderGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  10803. end)
  10804.  
  10805. fastwait(0.5)
  10806. gui.Main.BackgroundTransparency = 1
  10807. outlinesGradient.Rotation = 30
  10808.  
  10809. tweenNumber(100,ti,function(val)
  10810. val = val/100
  10811. local start = NumberSequenceKeypoint.new(0,1)
  10812. local a1 = NumberSequenceKeypoint.new(val,1)
  10813. local a2 = NumberSequenceKeypoint.new(math.min(1,val+math.min(0.05,val)),0)
  10814. if a1.Time == a2.Time then a2 = a1 end
  10815. local goal = NumberSequenceKeypoint.new(1,a1 == a2 and 1 or 0)
  10816. outlinesGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  10817. holderGradient.Transparency = NumberSequence.new({start,a1,a2,goal})
  10818. end)
  10819.  
  10820. fastwait(0.45)
  10821. gui:Destroy()
  10822. end
  10823.  
  10824. return {SetProgress = setProgress, Close = close}
  10825. end
  10826.  
  10827. Main.CreateApp = function(data)
  10828. if Main.MenuApps[data.Name] then return end -- TODO: Handle conflict
  10829. local control = {}
  10830.  
  10831. local app = Main.AppTemplate:Clone()
  10832.  
  10833. local iconIndex = data.Icon
  10834. if data.IconMap and iconIndex then
  10835. if type(iconIndex) == "number" then
  10836. data.IconMap:Display(app.Main.Icon,iconIndex)
  10837. elseif type(iconIndex) == "string" then
  10838. data.IconMap:DisplayByKey(app.Main.Icon,iconIndex)
  10839. end
  10840. elseif type(iconIndex) == "string" then
  10841. app.Main.Icon.Image = iconIndex
  10842. else
  10843. app.Main.Icon.Image = ""
  10844. end
  10845.  
  10846. local function updateState()
  10847. app.Main.BackgroundTransparency = data.Open and 0 or (Lib.CheckMouseInGui(app.Main) and 0 or 1)
  10848. app.Main.Highlight.Visible = data.Open
  10849. end
  10850.  
  10851. local function enable(silent)
  10852. if data.Open then return end
  10853. data.Open = true
  10854. updateState()
  10855. if not silent then
  10856. if data.Window then data.Window:Show() end
  10857. if data.OnClick then data.OnClick(data.Open) end
  10858. end
  10859. end
  10860.  
  10861. local function disable(silent)
  10862. if not data.Open then return end
  10863. data.Open = false
  10864. updateState()
  10865. if not silent then
  10866. if data.Window then data.Window:Hide() end
  10867. if data.OnClick then data.OnClick(data.Open) end
  10868. end
  10869. end
  10870.  
  10871. updateState()
  10872.  
  10873. local ySize = service.TextService:GetTextSize(data.Name,14,Enum.Font.SourceSans,Vector2.new(62,999999)).Y
  10874. app.Main.Size = UDim2.new(1,0,0,math.clamp(46+ySize,60,74))
  10875. app.Main.AppName.Text = data.Name
  10876.  
  10877. app.Main.InputBegan:Connect(function(input)
  10878. if input.UserInputType == Enum.UserInputType.MouseMovement then
  10879. app.Main.BackgroundTransparency = 0
  10880. app.Main.BackgroundColor3 = Settings.Theme.ButtonHover
  10881. end
  10882. end)
  10883.  
  10884. app.Main.InputEnded:Connect(function(input)
  10885. if input.UserInputType == Enum.UserInputType.MouseMovement then
  10886. app.Main.BackgroundTransparency = data.Open and 0 or 1
  10887. app.Main.BackgroundColor3 = Settings.Theme.Button
  10888. end
  10889. end)
  10890.  
  10891. app.Main.MouseButton1Click:Connect(function()
  10892. if data.Open then disable() else enable() end
  10893. end)
  10894.  
  10895. local window = data.Window
  10896. if window then
  10897. window.OnActivate:Connect(function() enable(true) end)
  10898. window.OnDeactivate:Connect(function() disable(true) end)
  10899. end
  10900.  
  10901. app.Visible = true
  10902. app.Parent = Main.AppsContainer
  10903. Main.AppsFrame.CanvasSize = UDim2.new(0,0,0,Main.AppsContainerGrid.AbsoluteCellCount.Y*82 + 8)
  10904.  
  10905. control.Enable = enable
  10906. control.Disable = disable
  10907. Main.MenuApps[data.Name] = control
  10908. return control
  10909. end
  10910.  
  10911. Main.SetMainGuiOpen = function(val)
  10912. Main.MainGuiOpen = val
  10913.  
  10914. Main.MainGui.OpenButton.Text = val and "X" or "Dex"
  10915. if val then Main.MainGui.OpenButton.MainFrame.Visible = true end
  10916. Main.MainGui.OpenButton.MainFrame:TweenSize(val and UDim2.new(0,224,0,200) or UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.2,true)
  10917. --Main.MainGui.OpenButton.BackgroundTransparency = val and 0 or (Lib.CheckMouseInGui(Main.MainGui.OpenButton) and 0 or 0.2)
  10918. service.TweenService:Create(Main.MainGui.OpenButton,TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundTransparency = val and 0 or (Lib.CheckMouseInGui(Main.MainGui.OpenButton) and 0 or 0.2)}):Play()
  10919.  
  10920. if Main.MainGuiMouseEvent then Main.MainGuiMouseEvent:Disconnect() end
  10921.  
  10922. if not val then
  10923. local startTime = tick()
  10924. Main.MainGuiCloseTime = startTime
  10925. coroutine.wrap(function()
  10926. Lib.FastWait(0.2)
  10927. if not Main.MainGuiOpen and startTime == Main.MainGuiCloseTime then Main.MainGui.OpenButton.MainFrame.Visible = false end
  10928. end)()
  10929. else
  10930. Main.MainGuiMouseEvent = service.UserInputService.InputBegan:Connect(function(input)
  10931. if input.UserInputType == Enum.UserInputType.MouseButton1 and not Lib.CheckMouseInGui(Main.MainGui.OpenButton) and not Lib.CheckMouseInGui(Main.MainGui.OpenButton.MainFrame) then
  10932. Main.SetMainGuiOpen(false)
  10933. end
  10934. end)
  10935. end
  10936. end
  10937.  
  10938. Main.CreateMainGui = function()
  10939. local gui = create({
  10940. {1,"ScreenGui",{IgnoreGuiInset=true,Name="MainMenu",}},
  10941. {2,"TextButton",{AnchorPoint=Vector2.new(0.5,0),AutoButtonColor=false,BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),BorderSizePixel=0,Font=4,Name="OpenButton",Parent={1},Position=UDim2.new(0.5,0,0,2),Size=UDim2.new(0,32,0,32),Text="Dex",TextColor3=Color3.new(1,1,1),TextSize=16,TextTransparency=0.20000000298023,}},
  10942. {3,"UICorner",{CornerRadius=UDim.new(0,4),Parent={2},}},
  10943. {4,"Frame",{AnchorPoint=Vector2.new(0.5,0),BackgroundColor3=Color3.new(0.17647059261799,0.17647059261799,0.17647059261799),ClipsDescendants=true,Name="MainFrame",Parent={2},Position=UDim2.new(0.5,0,1,-4),Size=UDim2.new(0,224,0,200),}},
  10944. {5,"UICorner",{CornerRadius=UDim.new(0,4),Parent={4},}},
  10945. {6,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),Name="BottomFrame",Parent={4},Position=UDim2.new(0,0,1,-24),Size=UDim2.new(1,0,0,24),}},
  10946. {7,"UICorner",{CornerRadius=UDim.new(0,4),Parent={6},}},
  10947. {8,"Frame",{BackgroundColor3=Color3.new(0.20392157137394,0.20392157137394,0.20392157137394),BorderSizePixel=0,Name="CoverFrame",Parent={6},Size=UDim2.new(1,0,0,4),}},
  10948. {9,"Frame",{BackgroundColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),BorderSizePixel=0,Name="Line",Parent={8},Position=UDim2.new(0,0,0,-1),Size=UDim2.new(1,0,0,1),}},
  10949. {10,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Settings",Parent={6},Position=UDim2.new(1,-48,0,0),Size=UDim2.new(0,24,1,0),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  10950. {11,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6578871732",ImageTransparency=0.20000000298023,Name="Icon",Parent={10},Position=UDim2.new(0,4,0,4),Size=UDim2.new(0,16,0,16),}},
  10951. {12,"TextButton",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Font=3,Name="Information",Parent={6},Position=UDim2.new(1,-24,0,0),Size=UDim2.new(0,24,1,0),Text="",TextColor3=Color3.new(1,1,1),TextSize=14,}},
  10952. {13,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6578933307",ImageTransparency=0.20000000298023,Name="Icon",Parent={12},Position=UDim2.new(0,4,0,4),Size=UDim2.new(0,16,0,16),}},
  10953. {14,"ScrollingFrame",{Active=true,AnchorPoint=Vector2.new(0.5,0),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderColor3=Color3.new(0.1294117718935,0.1294117718935,0.1294117718935),BorderSizePixel=0,Name="AppsFrame",Parent={4},Position=UDim2.new(0.5,0,0,0),ScrollBarImageColor3=Color3.new(0,0,0),ScrollBarThickness=4,Size=UDim2.new(0,222,1,-25),}},
  10954. {15,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="Container",Parent={14},Position=UDim2.new(0,7,0,8),Size=UDim2.new(1,-14,0,2),}},
  10955. {16,"UIGridLayout",{CellSize=UDim2.new(0,66,0,74),Parent={15},SortOrder=2,}},
  10956. {17,"Frame",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Name="App",Parent={1},Size=UDim2.new(0,100,0,100),Visible=false,}},
  10957. {18,"TextButton",{AutoButtonColor=false,BackgroundColor3=Color3.new(0.2352941185236,0.2352941185236,0.2352941185236),BorderSizePixel=0,Font=3,Name="Main",Parent={17},Size=UDim2.new(1,0,0,60),Text="",TextColor3=Color3.new(0,0,0),TextSize=14,}},
  10958. {19,"ImageLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,Image="rbxassetid://6579106223",ImageRectSize=Vector2.new(32,32),Name="Icon",Parent={18},Position=UDim2.new(0.5,-16,0,4),ScaleType=4,Size=UDim2.new(0,32,0,32),}},
  10959. {20,"TextLabel",{BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderSizePixel=0,Font=3,Name="AppName",Parent={18},Position=UDim2.new(0,2,0,38),Size=UDim2.new(1,-4,1,-40),Text="Explorer",TextColor3=Color3.new(1,1,1),TextSize=14,TextTransparency=0.10000000149012,TextTruncate=1,TextWrapped=true,TextYAlignment=0,}},
  10960. {21,"Frame",{BackgroundColor3=Color3.new(0,0.66666668653488,1),BorderSizePixel=0,Name="Highlight",Parent={18},Position=UDim2.new(0,0,1,-2),Size=UDim2.new(1,0,0,2),}},
  10961. })
  10962. Main.MainGui = gui
  10963. Main.AppsFrame = gui.OpenButton.MainFrame.AppsFrame
  10964. Main.AppsContainer = Main.AppsFrame.Container
  10965. Main.AppsContainerGrid = Main.AppsContainer.UIGridLayout
  10966. Main.AppTemplate = gui.App
  10967. Main.MainGuiOpen = false
  10968.  
  10969. local openButton = gui.OpenButton
  10970. openButton.BackgroundTransparency = 0.2
  10971. openButton.MainFrame.Size = UDim2.new(0,0,0,0)
  10972. openButton.MainFrame.Visible = false
  10973. openButton.MouseButton1Click:Connect(function()
  10974. Main.SetMainGuiOpen(not Main.MainGuiOpen)
  10975. end)
  10976.  
  10977. openButton.InputBegan:Connect(function(input)
  10978. if input.UserInputType == Enum.UserInputType.MouseMovement then
  10979. service.TweenService:Create(Main.MainGui.OpenButton,TweenInfo.new(0,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundTransparency = 0}):Play()
  10980. end
  10981. end)
  10982.  
  10983. openButton.InputEnded:Connect(function(input)
  10984. if input.UserInputType == Enum.UserInputType.MouseMovement then
  10985. service.TweenService:Create(Main.MainGui.OpenButton,TweenInfo.new(0,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundTransparency = Main.MainGuiOpen and 0 or 0.2}):Play()
  10986. end
  10987. end)
  10988.  
  10989. -- Create Main Apps
  10990. Main.CreateApp({Name = "Explorer", IconMap = Main.LargeIcons, Icon = "Explorer", Open = true, Window = Explorer.Window})
  10991.  
  10992. Main.CreateApp({Name = "Properties", IconMap = Main.LargeIcons, Icon = "Properties", Open = true, Window = Properties.Window})
  10993.  
  10994. Main.CreateApp({Name = "Script Viewer", IconMap = Main.LargeIcons, Icon = "Script_Viewer", Window = ScriptViewer.Window})
  10995.  
  10996. local cptsOnMouseClick = nil
  10997. Main.CreateApp({Name = "Click part to select", IconMap = Main.LargeIcons, Icon = 6, OnClick = function(callback)
  10998. if callback then
  10999. local mouse = Main.Mouse
  11000. cptsOnMouseClick = mouse.Button1Down:Connect(function()
  11001. pcall(function()
  11002. local object = mouse.Target
  11003. if nodes[object] then
  11004. selection:Set(nodes[object])
  11005. Explorer.ViewNode(nodes[object])
  11006. end
  11007. end)
  11008. end)
  11009. else if cptsOnMouseClick ~= nil then cptsOnMouseClick:Disconnect() cptsOnMouseClick = nil end end
  11010. end})
  11011.  
  11012. Lib.ShowGui(gui)
  11013. end
  11014.  
  11015. Main.SetupFilesystem = function()
  11016. if not env.writefile or not env.makefolder then return end
  11017. local writefile, makefolder = env.writefile, env.makefolder
  11018. makefolder("dex")
  11019. makefolder("dex/assets")
  11020. makefolder("dex/saved")
  11021. makefolder("dex/plugins")
  11022. makefolder("dex/ModuleCache")
  11023. end
  11024.  
  11025. Main.LocalDepsUpToDate = function()
  11026. return Main.DepsVersionData and Main.ClientVersion == Main.DepsVersionData[1]
  11027. end
  11028.  
  11029. Main.Init = function()
  11030. Main.Elevated = pcall(function() local a = clonerefs(game:GetService("CoreGui")):GetFullName() end)
  11031. Main.InitEnv()
  11032. Main.LoadSettings()
  11033. Main.SetupFilesystem()
  11034.  
  11035. -- Load Lib
  11036. local intro = Main.CreateIntro("Initializing Library")
  11037. Lib = Main.LoadModule("Lib")
  11038. Lib.FastWait()
  11039.  
  11040. -- Init other stuff
  11041. --Main.IncompatibleTest()
  11042.  
  11043. -- Init icons
  11044. Main.MiscIcons = Lib.IconMap.new("rbxassetid://6511490623",256,256,16,16)
  11045. Main.MiscIcons:SetDict({
  11046. Reference = 0, Cut = 1, Cut_Disabled = 2, Copy = 3, Copy_Disabled = 4, Paste = 5, Paste_Disabled = 6,
  11047. Delete = 7, Delete_Disabled = 8, Group = 9, Group_Disabled = 10, Ungroup = 11, Ungroup_Disabled = 12, TeleportTo = 13,
  11048. Rename = 14, JumpToParent = 15, ExploreData = 16, Save = 17, CallFunction = 18, CallRemote = 19, Undo = 20,
  11049. Undo_Disabled = 21, Redo = 22, Redo_Disabled = 23, Expand_Over = 24, Expand = 25, Collapse_Over = 26, Collapse = 27,
  11050. SelectChildren = 28, SelectChildren_Disabled = 29, InsertObject = 30, ViewScript = 31, AddStar = 32, RemoveStar = 33, Script_Disabled = 34,
  11051. LocalScript_Disabled = 35, Play = 36, Pause = 37, Rename_Disabled = 38
  11052. })
  11053. Main.LargeIcons = Lib.IconMap.new("rbxassetid://6579106223",256,256,32,32)
  11054. Main.LargeIcons:SetDict({
  11055. Explorer = 0, Properties = 1, Script_Viewer = 2,
  11056. })
  11057.  
  11058. -- Fetch version if needed
  11059. intro.SetProgress("Fetching Roblox Version",0.2)
  11060. if Main.Elevated then
  11061. local fileVer = Lib.ReadFile("dex/deps_version.dat")
  11062. Main.ClientVersion = Version()
  11063. if fileVer then
  11064. Main.DepsVersionData = string.split(fileVer,"\n")
  11065. if Main.LocalDepsUpToDate() then
  11066. Main.RobloxVersion = Main.DepsVersionData[2]
  11067. end
  11068. end
  11069. Main.RobloxVersion = Main.RobloxVersion or game:HttpGet("http://setup.roblox.com/versionQTStudio")
  11070. end
  11071.  
  11072. -- Fetch external deps
  11073. intro.SetProgress("Fetching API",0.35)
  11074. API = Main.FetchAPI()
  11075. Lib.FastWait()
  11076. intro.SetProgress("Fetching RMD",0.5)
  11077. RMD = Main.FetchRMD()
  11078. Lib.FastWait()
  11079.  
  11080. -- Save external deps locally if needed
  11081. if Main.Elevated and env.writefile and not Main.LocalDepsUpToDate() then
  11082. env.writefile("dex/deps_version.dat",Main.ClientVersion.."\n"..Main.RobloxVersion)
  11083. env.writefile("dex/rbx_api.dat",Main.RawAPI)
  11084. env.writefile("dex/rbx_rmd.dat",Main.RawRMD)
  11085. end
  11086.  
  11087. -- Load other modules
  11088. intro.SetProgress("Loading Modules",0.75)
  11089. Main.AppControls.Lib.InitDeps(Main.GetInitDeps()) -- Missing deps now available
  11090. Main.LoadModules()
  11091. Lib.FastWait()
  11092.  
  11093. -- Init other modules
  11094. intro.SetProgress("Initializing Modules",0.9)
  11095. Explorer.Init()
  11096. Properties.Init()
  11097. ScriptViewer.Init()
  11098. Lib.FastWait()
  11099.  
  11100. -- Done
  11101. intro.SetProgress("Complete",1)
  11102. coroutine.wrap(function()
  11103. Lib.FastWait(1.25)
  11104. intro.Close()
  11105. end)()
  11106.  
  11107. -- Init window system, create main menu, show explorer and properties
  11108. Lib.Window.Init()
  11109. Main.CreateMainGui()
  11110. Explorer.Window:Show({Align = "right", Pos = 1, Size = 0.5, Silent = true})
  11111. Properties.Window:Show({Align = "right", Pos = 2, Size = 0.5, Silent = true})
  11112. Lib.DeferFunc(function() Lib.Window.ToggleSide("right") end)
  11113. end
  11114.  
  11115. return Main
  11116. end)()
  11117.  
  11118. -- Start
  11119. Main.Init()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement