Image
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "MR_PoseTool"

-- **************************************************
-- General information about this script
-- **************************************************

MR_PoseTool = {}

function MR_PoseTool:Name()
	return self:Localize('UILabel')
end

function MR_PoseTool:Version()
	return '2.1.7'
end

function MR_PoseTool:UILabel()
	return self:Localize('UILabel')
end

function MR_PoseTool:Creator()
	return 'Eugene Babich'
end

function MR_PoseTool:Description()
	return self:Localize('Description')
end

-- **************************************************
-- Is Relevant / Is Enabled
-- **************************************************

function MR_PoseTool:IsRelevant(moho)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return false
	end
	
	local v1, v2, v3 = MR_Utilities:GetMohoVersion(moho)
	self.mohoVersion = v1
	
	return true
end

function MR_PoseTool:IsEnabled(moho)
	return true
end

-- **************************************************
-- Recurring Values
-- **************************************************

MR_PoseTool.quickMenuTooltips = true
MR_PoseTool.moveTargetParent = false
MR_PoseTool.doubleClickToSetKeyframe = true
MR_PoseTool.holdToReset = true
MR_PoseTool.blockOnEvenFrames = true
MR_PoseTool.blockOnOddFrames = false
MR_PoseTool.highlightBones = true
MR_PoseTool.highlightWidth = 3
MR_PoseTool.useHighlightCustomColor = false
MR_PoseTool.highlightOpacity = 1

MR_PoseTool.highlightCustomColorR = 255
MR_PoseTool.highlightCustomColorG = 0
MR_PoseTool.highlightCustomColorB = 0
MR_PoseTool.highlightCustomColorA = 255

MR_PoseTool.alignHandlesAlongBone = false
MR_PoseTool.handlesDistance = 1
MR_PoseTool.handleStrokeOpacity = 1
MR_PoseTool.handleFillOpacity = 1
MR_PoseTool.useCustomColors = false

MR_PoseTool.colorStrokeTranslateHandleR = 255
MR_PoseTool.colorStrokeTranslateHandleG = 0
MR_PoseTool.colorStrokeTranslateHandleB = 0
MR_PoseTool.colorStrokeTranslateHandleA = 255

MR_PoseTool.colorFillTranslateHandleR = 248
MR_PoseTool.colorFillTranslateHandleG = 121
MR_PoseTool.colorFillTranslateHandleB = 114
MR_PoseTool.colorFillTranslateHandleA = 255

MR_PoseTool.colorStrokeScaleHandleR = 255
MR_PoseTool.colorStrokeScaleHandleG = 0
MR_PoseTool.colorStrokeScaleHandleB = 0
MR_PoseTool.colorStrokeScaleHandleA = 255

MR_PoseTool.colorFillScaleHandleR = 248
MR_PoseTool.colorFillScaleHandleG = 121
MR_PoseTool.colorFillScaleHandleB = 114
MR_PoseTool.colorFillScaleHandleA = 255

MR_PoseTool.colorFollowBonesR = 46
MR_PoseTool.colorFollowBonesG = 120
MR_PoseTool.colorFollowBonesB = 255
MR_PoseTool.colorFollowBonesA = 255

MR_PoseTool.colorStrokeMoveJointHandleR = 255
MR_PoseTool.colorStrokeMoveJointHandleG = 63
MR_PoseTool.colorStrokeMoveJointHandleB = 15
MR_PoseTool.colorStrokeMoveJointHandleA = 255

MR_PoseTool.colorFillMoveJointHandleR = 255
MR_PoseTool.colorFillMoveJointHandleG = 189
MR_PoseTool.colorFillMoveJointHandleB = 46
MR_PoseTool.colorFillMoveJointHandleA = 255

MR_PoseTool.colorStrokeManipulateHandleR = 255
MR_PoseTool.colorStrokeManipulateHandleG = 63
MR_PoseTool.colorStrokeManipulateHandleB = 15
MR_PoseTool.colorStrokeManipulateHandleA = 255

MR_PoseTool.colorFillManipulateHandleR = 255
MR_PoseTool.colorFillManipulateHandleG = 189
MR_PoseTool.colorFillManipulateHandleB = 46
MR_PoseTool.colorFillManipulateHandleA = 255

MR_PoseTool.iconColorR = 34
MR_PoseTool.iconColorG = 70
MR_PoseTool.iconColorB = 65
MR_PoseTool.iconColorA = 255

MR_PoseTool.twosMode = false
MR_PoseTool.keepSelection = false
MR_PoseTool.multiTransform = false
MR_PoseTool.lockHandles = false
MR_PoseTool.bakeAdjacentFrames = false
MR_PoseTool.firstBoneID = -1
MR_PoseTool.firstBonePos = LM.Vector2:new_local()
MR_PoseTool.firstBoneScalePercent = 50
MR_PoseTool.clickOffset = LM.Vector2:new_local()
MR_PoseTool.secondBoneID = -1
MR_PoseTool.isActive = true
MR_PoseTool.firstBoneOffset = 0
MR_PoseTool.secondBoneOffset = 0
MR_PoseTool.interval = 1
MR_PoseTool.showPath = false
MR_PoseTool.range = false
MR_PoseTool.rangeFrames = 10
MR_PoseTool.secondBonePos = LM.Vector2:new_local()
MR_PoseTool.secondBoneTipPos = LM.Vector2:new_local()
MR_PoseTool.firstDist = 0
MR_PoseTool.secondBoneDist = 0
MR_PoseTool.firstBoneParentID = -1
MR_PoseTool.firstBoneParentIBIK = false
MR_PoseTool.firstBoneSizeDelta = 0
MR_PoseTool.secondBoneSizeDelta = 0
MR_PoseTool.firstBoneAngleDelta = 0
MR_PoseTool.secondBoneAngleDelta = 0
MR_PoseTool.selectedBonesList = {}
MR_PoseTool.mousePickedID = -1
MR_PoseTool.mouseHoverID = -1
MR_PoseTool.dragging = false
MR_PoseTool.lastVec = LM.Vector2:new_local()
MR_PoseTool.lastVec2 = LM.Vector2:new_local()
MR_PoseTool.handlesDist = 0.075
MR_PoseTool.handlesDistY = 0.026
MR_PoseTool.handlesDistYMultiplier = 1
MR_PoseTool.additionmarkerDist = 0.05
MR_PoseTool.markerR = 6
MR_PoseTool.markerR2 = 6
MR_PoseTool.additionHandles = false
MR_PoseTool.startBonePos = LM.Vector2:new_local()
MR_PoseTool.startBoneAngleDelta = 0
MR_PoseTool.startBoneDist = 0
MR_PoseTool.TOLERANCE = 10
MR_PoseTool.transformPath = false
MR_PoseTool.drawMode = -1
MR_PoseTool.keepHandles = false
MR_PoseTool.height = 1080
MR_PoseTool.ignoreZeroScaledBones = true
MR_PoseTool.clickToSelect = false
MR_PoseTool.pickWidth = 10
MR_PoseTool.handlesDistanceTreshhold = 0.2
MR_PoseTool.followBonesList = {}
MR_PoseTool.followBonesList.id = {}
MR_PoseTool.followBonesList.names = {}
MR_PoseTool.followBonesList.length = {}
MR_PoseTool.followBonesList.startBone = {}
MR_PoseTool.followBonesList.endBone = {}
MR_PoseTool.startFollowBone = -1
MR_PoseTool.endFollowBone = -1
MR_PoseTool.scaleFollowBones = false
MR_PoseTool.isMouseDragging = false
MR_PoseTool.selRect = LM.Rect:new_local()
MR_PoseTool.forceFollowBonesGraphics = false
MR_PoseTool.iconsDistance = 0.08
MR_PoseTool.iconsRadius = 18
MR_PoseTool.showIcons = false
MR_PoseTool.graphicsMenuCenter = LM.Vector2:new_local()
MR_PoseTool.mouseHoverIDGraphicMenu = -1
MR_PoseTool.graphicMenuMode = 0
MR_PoseTool.lockAngleList = {}
MR_PoseTool.lockAngleBoneNamesList = {}
MR_PoseTool.lockPosList = {}
MR_PoseTool.lockPosBoneNamesList = {}
MR_PoseTool.bonesReset = false
MR_PoseTool.multiSelectionUnselectedMovement = false
MR_PoseTool.showCross = false
MR_PoseTool.ignoreBonesList = {}
MR_PoseTool.scriptDataName = 'MR_PoseTool_'
MR_PoseTool.bonesDataActive = true
MR_PoseTool.selBonesList = {}
MR_PoseTool.isBoneHaveAngleKeyList = {}
MR_PoseTool.isBoneHaveScaleKeyList = {}
MR_PoseTool.clickTime = 0
MR_PoseTool.setKeyframe = false
MR_PoseTool.onMMTreshold = false

-- **************************************************
-- Prefs
-- **************************************************

function MR_PoseTool:LoadPrefs(prefs)
	self.quickMenuTooltips = prefs:GetBool("MR_PoseTool.quickMenuTooltips", true)
	self.doubleClickToSetKeyframe = prefs:GetBool("MR_PoseTool.doubleClickToSetKeyframe", true)
	self.holdToReset = prefs:GetBool("MR_PoseTool.holdToReset", true)
	self.moveTargetParent = prefs:GetBool("MR_PoseTool.moveTargetParent", false)
	self.blockOnEvenFrames = prefs:GetBool("MR_PoseTool.blockOnEvenFrames", true)
	self.blockOnOddFrames = prefs:GetBool("MR_PoseTool.blockOnOddFrames", false)
	self.highlightBones = prefs:GetBool("MR_PoseTool.highlightBones", true)
	self.highlightWidth = prefs:GetInt("MR_PoseTool.highlightWidth", 3)
	self.useHighlightCustomColor = prefs:GetBool("MR_PoseTool.useHighlightCustomColor", false)
	
	self.highlightCustomColorR = prefs:GetInt("MR_PoseTool.highlightCustomColorR", 255)
	self.highlightCustomColorG = prefs:GetInt("MR_PoseTool.highlightCustomColorG", 0)
	self.highlightCustomColorB = prefs:GetInt("MR_PoseTool.highlightCustomColorB", 0)
	self.highlightCustomColorA = prefs:GetInt("MR_PoseTool.highlightCustomColorA", 255)
	
	self.alignHandlesAlongBone = prefs:GetBool("MR_PoseTool.alignHandlesAlongBone", false)
	self.handlesDistance = prefs:GetFloat("MR_PoseTool.handlesDistance", 1)
	self.handleStrokeOpacity = prefs:GetFloat("MR_PoseTool.handleStrokeOpacity", 1)
	self.handleFillOpacity = prefs:GetFloat("MR_PoseTool.handleFillOpacity", 1)
	self.useCustomColors = prefs:GetBool("MR_PoseTool.useCustomColors", false)
	
	self.colorStrokeTranslateHandleR = prefs:GetInt("MR_PoseTool.colorStrokeTranslateHandleR", 255)
	self.colorStrokeTranslateHandleG = prefs:GetInt("MR_PoseTool.colorStrokeTranslateHandleG", 0)
	self.colorStrokeTranslateHandleB = prefs:GetInt("MR_PoseTool.colorStrokeTranslateHandleB", 0)
	self.colorStrokeTranslateHandleA = prefs:GetInt("MR_PoseTool.colorStrokeTranslateHandleA", 255)
	
	self.colorFillTranslateHandleR = prefs:GetInt("MR_PoseTool.colorFillTranslateHandleR", 248)
	self.colorFillTranslateHandleG = prefs:GetInt("MR_PoseTool.colorFillTranslateHandleG", 121)
	self.colorFillTranslateHandleB = prefs:GetInt("MR_PoseTool.colorFillTranslateHandleB", 114)
	self.colorFillTranslateHandleA = prefs:GetInt("MR_PoseTool.colorFillTranslateHandleA", 255)
	
	self.colorStrokeScaleHandleR = prefs:GetInt("MR_PoseTool.colorStrokeScaleHandleR", 255)
	self.colorStrokeScaleHandleG = prefs:GetInt("MR_PoseTool.colorStrokeScaleHandleG", 0)
	self.colorStrokeScaleHandleB = prefs:GetInt("MR_PoseTool.colorStrokeScaleHandleB", 0)
	self.colorStrokeScaleHandleA = prefs:GetInt("MR_PoseTool.colorStrokeScaleHandleA", 255)
	
	self.colorFillScaleHandleR = prefs:GetInt("MR_PoseTool.colorFillScaleHandleR", 248)
	self.colorFillScaleHandleG = prefs:GetInt("MR_PoseTool.colorFillScaleHandleG", 121)
	self.colorFillScaleHandleB = prefs:GetInt("MR_PoseTool.colorFillScaleHandleB", 114)
	self.colorFillScaleHandleA = prefs:GetInt("MR_PoseTool.colorFillScaleHandleA", 255)
	
	self.colorStrokeMoveJointHandleR = prefs:GetInt("MR_PoseTool.colorStrokeMoveJointHandleR", 255)
	self.colorStrokeMoveJointHandleG = prefs:GetInt("MR_PoseTool.colorStrokeMoveJointHandleG", 63)
	self.colorStrokeMoveJointHandleB = prefs:GetInt("MR_PoseTool.colorStrokeMoveJointHandleB", 15)
	self.colorStrokeMoveJointHandleA = prefs:GetInt("MR_PoseTool.colorStrokeMoveJointHandleA", 255)
	
	self.colorFillMoveJointHandleR = prefs:GetInt("MR_PoseTool.colorFillMoveJointHandleR", 255)
	self.colorFillMoveJointHandleG = prefs:GetInt("MR_PoseTool.colorFillMoveJointHandleG", 189)
	self.colorFillMoveJointHandleB = prefs:GetInt("MR_PoseTool.colorFillMoveJointHandleB", 46)
	self.colorFillMoveJointHandleA = prefs:GetInt("MR_PoseTool.colorFillMoveJointHandleA", 255)
	
	self.colorStrokeManipulateHandleR = prefs:GetInt("MR_PoseTool.colorStrokeManipulateHandleR", 255)
	self.colorStrokeManipulateHandleG = prefs:GetInt("MR_PoseTool.colorStrokeManipulateHandleG", 63)
	self.colorStrokeManipulateHandleB = prefs:GetInt("MR_PoseTool.colorStrokeManipulateHandleB", 15)
	self.colorStrokeManipulateHandleA = prefs:GetInt("MR_PoseTool.colorStrokeManipulateHandleA", 255)
	
	self.colorFillManipulateHandleR = prefs:GetInt("MR_PoseTool.colorFillManipulateHandleR", 255)
	self.colorFillManipulateHandleG = prefs:GetInt("MR_PoseTool.colorFillManipulateHandleG", 189)
	self.colorFillManipulateHandleB = prefs:GetInt("MR_PoseTool.colorFillManipulateHandleB", 46)
	self.colorFillManipulateHandleA = prefs:GetInt("MR_PoseTool.colorFillManipulateHandleA", 255)
	
	self.twosMode = prefs:GetBool("MR_PoseTool.twosMode", false)
	self.keepSelection = prefs:GetBool("MR_PoseTool.keepSelection", false)
	self.multiTransform = prefs:GetBool("MR_PoseTool.multiTransform", false)
	self.lockHandles = prefs:GetBool("MR_PoseTool.lockHandles", false)
	self.bakeAdjacentFrames = prefs:GetBool("MR_PoseTool.bakeAdjacentFrames", false)
	self.interval = prefs:GetInt("MR_PoseTool.interval", 1)
	self.showPath = prefs:GetBool("MR_PoseTool.showPath", false)
	self.range = prefs:GetBool("MR_PoseTool.range", false)
	self.rangeFrames = prefs:GetInt("MR_PoseTool.rangeFrames", 10)
	
	self.scaleFollowBones = prefs:GetBool("MR_PoseTool.scaleFollowBones", false)
end

function MR_PoseTool:SavePrefs(prefs)
	prefs:SetBool("MR_PoseTool.quickMenuTooltips", self.quickMenuTooltips)
	prefs:SetBool("MR_PoseTool.doubleClickToSetKeyframe", self.doubleClickToSetKeyframe)
	prefs:SetBool("MR_PoseTool.holdToReset", self.holdToReset)
	prefs:SetBool("MR_PoseTool.moveTargetParent", self.moveTargetParent)
	prefs:SetBool("MR_PoseTool.blockOnEvenFrames", self.blockOnEvenFrames)
	prefs:SetBool("MR_PoseTool.blockOnOddFrames", self.blockOnOddFrames)
	prefs:SetBool("MR_PoseTool.highlightBones", self.highlightBones)
	prefs:SetInt("MR_PoseTool.highlightWidth", self.highlightWidth)
	prefs:SetBool("MR_PoseTool.useHighlightCustomColor", self.useHighlightCustomColor)
	
	prefs:SetInt("MR_PoseTool.highlightCustomColorR", self.highlightCustomColorR)
	prefs:SetInt("MR_PoseTool.highlightCustomColorG", self.highlightCustomColorG)
	prefs:SetInt("MR_PoseTool.highlightCustomColorB", self.highlightCustomColorB)
	prefs:SetInt("MR_PoseTool.highlightCustomColorA", self.highlightCustomColorA)
	
	prefs:SetBool("MR_PoseTool.alignHandlesAlongBone", self.alignHandlesAlongBone)
	prefs:SetFloat("MR_PoseTool.handlesDistance", self.handlesDistance)
	prefs:SetFloat("MR_PoseTool.handleStrokeOpacity", self.handleStrokeOpacity)
	prefs:SetFloat("MR_PoseTool.handleFillOpacity", self.handleFillOpacity)
	prefs:SetBool("MR_PoseTool.useCustomColors", self.useCustomColors)
	
	prefs:SetInt("MR_PoseTool.colorStrokeTranslateHandleR", self.colorStrokeTranslateHandleR)
	prefs:SetInt("MR_PoseTool.colorStrokeTranslateHandleG", self.colorStrokeTranslateHandleG)
	prefs:SetInt("MR_PoseTool.colorStrokeTranslateHandleB", self.colorStrokeTranslateHandleB)
	prefs:SetInt("MR_PoseTool.colorStrokeTranslateHandleA", self.colorStrokeTranslateHandleA)
	
	prefs:SetInt("MR_PoseTool.colorFillTranslateHandleR", self.colorFillTranslateHandleR)
	prefs:SetInt("MR_PoseTool.colorFillTranslateHandleG", self.colorFillTranslateHandleG)
	prefs:SetInt("MR_PoseTool.colorFillTranslateHandleB", self.colorFillTranslateHandleB)
	prefs:SetInt("MR_PoseTool.colorFillTranslateHandleA", self.colorFillTranslateHandleA)
	
	prefs:SetInt("MR_PoseTool.colorStrokeScaleHandleR", self.colorStrokeScaleHandleR)
	prefs:SetInt("MR_PoseTool.colorStrokeScaleHandleG", self.colorStrokeScaleHandleG)
	prefs:SetInt("MR_PoseTool.colorStrokeScaleHandleB", self.colorStrokeScaleHandleB)
	prefs:SetInt("MR_PoseTool.colorStrokeScaleHandleA", self.colorStrokeScaleHandleA)
	
	prefs:SetInt("MR_PoseTool.colorFillScaleHandleR", self.colorFillScaleHandleR)
	prefs:SetInt("MR_PoseTool.colorFillScaleHandleG", self.colorFillScaleHandleG)
	prefs:SetInt("MR_PoseTool.colorFillScaleHandleB", self.colorFillScaleHandleB)
	prefs:SetInt("MR_PoseTool.colorFillScaleHandleA", self.colorFillScaleHandleA)
	
	prefs:SetInt("MR_PoseTool.colorStrokeMoveJointHandleR", self.colorStrokeMoveJointHandleR)
	prefs:SetInt("MR_PoseTool.colorStrokeMoveJointHandleG", self.colorStrokeMoveJointHandleG)
	prefs:SetInt("MR_PoseTool.colorStrokeMoveJointHandleB", self.colorStrokeMoveJointHandleB)
	prefs:SetInt("MR_PoseTool.colorStrokeMoveJointHandleA", self.colorStrokeMoveJointHandleA)
	
	prefs:SetInt("MR_PoseTool.colorFillMoveJointHandleR", self.colorFillMoveJointHandleR)
	prefs:SetInt("MR_PoseTool.colorFillMoveJointHandleG", self.colorFillMoveJointHandleG)
	prefs:SetInt("MR_PoseTool.colorFillMoveJointHandleB", self.colorFillMoveJointHandleB)
	prefs:SetInt("MR_PoseTool.colorFillMoveJointHandleA", self.colorFillMoveJointHandleA)
	
	prefs:SetInt("MR_PoseTool.colorStrokeManipulateHandleR", self.colorStrokeManipulateHandleR)
	prefs:SetInt("MR_PoseTool.colorStrokeManipulateHandleG", self.colorStrokeManipulateHandleG)
	prefs:SetInt("MR_PoseTool.colorStrokeManipulateHandleB", self.colorStrokeManipulateHandleB)
	prefs:SetInt("MR_PoseTool.colorStrokeManipulateHandleA", self.colorStrokeManipulateHandleA)
	
	prefs:SetInt("MR_PoseTool.colorFillManipulateHandleR", self.colorFillManipulateHandleR)
	prefs:SetInt("MR_PoseTool.colorFillManipulateHandleG", self.colorFillManipulateHandleG)
	prefs:SetInt("MR_PoseTool.colorFillManipulateHandleB", self.colorFillManipulateHandleB)
	prefs:SetInt("MR_PoseTool.colorFillManipulateHandleA", self.colorFillManipulateHandleA)
	
	prefs:SetBool("MR_PoseTool.twosMode", self.twosMode)
	prefs:SetBool("MR_PoseTool.keepSelection", self.keepSelection)
	prefs:SetBool("MR_PoseTool.multiTransform", self.multiTransform)
	prefs:SetBool("MR_PoseTool.lockHandles", self.lockHandles)
	prefs:SetBool("MR_PoseTool.bakeAdjacentFrames", self.bakeAdjacentFrames)
	prefs:SetInt("MR_PoseTool.interval", self.interval)
	prefs:SetBool("MR_PoseTool.showPath", self.showPath)
	prefs:SetBool("MR_PoseTool.range", self.range)
	prefs:SetInt("MR_PoseTool.rangeFrames", self.rangeFrames)
	
	prefs:SetBool("MR_PoseTool.scaleFollowBones", self.scaleFollowBones)
end

function MR_PoseTool:ResetPrefs()
	self.quickMenuTooltips = true
	self.doubleClickToSetKeyframe = true
	self.holdToReset = true
	self.moveTargetParent = false
	self.blockOnEvenFrames = true
	self.blockOnOddFrames = false
	self.highlightBones = true
	self.highlightWidth = 3
	self.useHighlightCustomColor = false
	
	self.highlightCustomColorR = 255
	self.highlightCustomColorG = 0
	self.highlightCustomColorB = 0
	self.highlightCustomColorA = 255
	
	self.alignHandlesAlongBone = false
	self.handlesDistance = 1
	self.handleFillOpacity = 1
	self.useCustomColors = false
	
	self.colorStrokeTranslateHandleR = 255
	self.colorStrokeTranslateHandleG = 0
	self.colorStrokeTranslateHandleB = 0
	self.colorStrokeTranslateHandleA = 255

	self.colorFillTranslateHandleR = 248
	self.colorFillTranslateHandleG = 121
	self.colorFillTranslateHandleB = 114
	self.colorFillTranslateHandleA = 255

	self.colorStrokeScaleHandleR = 255
	self.colorStrokeScaleHandleG = 0
	self.colorStrokeScaleHandleB = 0
	self.colorStrokeScaleHandleA = 255

	self.colorFillScaleHandleR = 248
	self.colorFillScaleHandleG = 121
	self.colorFillScaleHandleB = 114
	self.colorFillScaleHandleA = 255

	self.colorStrokeMoveJointHandleR = 255
	self.colorStrokeMoveJointHandleG = 63
	self.colorStrokeMoveJointHandleB = 15
	self.colorStrokeMoveJointHandleA = 255

	self.colorFillMoveJointHandleR = 255
	self.colorFillMoveJointHandleG = 189
	self.colorFillMoveJointHandleB = 46
	self.colorFillMoveJointHandleA = 255

	self.colorStrokeManipulateHandleR = 255
	self.colorStrokeManipulateHandleG = 63
	self.colorStrokeManipulateHandleB = 15
	self.colorStrokeManipulateHandleA = 255

	self.colorFillManipulateHandleR = 255
	self.colorFillManipulateHandleG = 189
	self.colorFillManipulateHandleB = 46
	self.colorFillManipulateHandleA = 255
	
	self.twosMode = false
	self.keepSelection = false
	self.multiTransform = false
	self.lockHandles = false
	self.bakeAdjacentFrames = false
	self.interval = 1
	self.showPath = false
	self.range = false
	self.rangeFrames = 10
	self.scaleFollowBones = false
end

function MR_PoseTool:NonDragMouseMove()
	return true -- Call MouseMoved() even if the mouse button is not down
end

-- **************************************************
-- Settings Menu
-- **************************************************

local MR_PoseToolSettingsDialog = {}

MR_PoseToolSettingsDialog.QUICK_MENU_TOOLTIPS = MOHO.MSG_BASE
MR_PoseToolSettingsDialog.DOUBLE_CLICK_TO_SET_KEYFRAME = MOHO.MSG_BASE + 1
MR_PoseToolSettingsDialog.HOLD_TO_RESET = MOHO.MSG_BASE + 2
MR_PoseToolSettingsDialog.MOVE_TARGET_PARENT = MOHO.MSG_BASE + 3
MR_PoseToolSettingsDialog.BLOCK_ON_EVEN_FRAMES = MOHO.MSG_BASE + 4
MR_PoseToolSettingsDialog.BLOCK_ON_ODD_FRAMES = MOHO.MSG_BASE + 5
MR_PoseToolSettingsDialog.HIGHLIGHT_BONES = MOHO.MSG_BASE + 6
MR_PoseToolSettingsDialog.HIGHLIGHT_WIDTH = MOHO.MSG_BASE + 7
MR_PoseToolSettingsDialog.HIGHLIGHT_OPACITY = MOHO.MSG_BASE + 8
MR_PoseToolSettingsDialog.USE_HIGHLIGHT_CUSTOM_COLOR = MOHO.MSG_BASE + 9
MR_PoseToolSettingsDialog.HIGHLIGHT_CUSTOM_COLOR = MOHO.MSG_BASE + 10
MR_PoseToolSettingsDialog.ALIGN_HANDLES_ALONG_BONE = MOHO.MSG_BASE + 11
MR_PoseToolSettingsDialog.HANDLES_DISTANCE = MOHO.MSG_BASE + 12
MR_PoseToolSettingsDialog.HANDLES_STROKE_OPACITY = MOHO.MSG_BASE + 13
MR_PoseToolSettingsDialog.HANDLES_FILL_OPACITY = MOHO.MSG_BASE + 14
MR_PoseToolSettingsDialog.USE_CUSTOM_COLORS = MOHO.MSG_BASE + 15
MR_PoseToolSettingsDialog.COLOR_TRANSLATE_STROKE = MOHO.MSG_BASE + 16
MR_PoseToolSettingsDialog.COLOR_TRANSLATE_FILL = MOHO.MSG_BASE + 17
MR_PoseToolSettingsDialog.COLOR_SCALE_STROKE = MOHO.MSG_BASE + 18
MR_PoseToolSettingsDialog.COLOR_SCALE_FILL = MOHO.MSG_BASE + 19
MR_PoseToolSettingsDialog.COLOR_MOVE_JOINT_STROKE = MOHO.MSG_BASE + 20
MR_PoseToolSettingsDialog.COLOR_MOVE_JOINT_FILL = MOHO.MSG_BASE + 21
MR_PoseToolSettingsDialog.COLOR_MANIPULATE_STROKE = MOHO.MSG_BASE + 22
MR_PoseToolSettingsDialog.COLOR_MANIPULATE_FILL = MOHO.MSG_BASE + 23
MR_PoseToolSettingsDialog.RESET_COLOR = MOHO.MSG_BASE + 24

function MR_PoseToolSettingsDialog:new()
	local d = LM.GUI.SimpleDialog(MR_PoseTool:Localize('UILabel'), MR_PoseToolSettingsDialog)
    local l = d:GetLayout()
	if HV_Font then
		d.quickMenuTooltipsCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Quick menu tooltips'), self.QUICK_MENU_TOOLTIPS)
		l:AddChild(d.quickMenuTooltipsCheck, LM.GUI.ALIGN_LEFT, 0)
	end
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.doubleClickToSetKeyframeCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Double-click to set keyframe'), self.DOUBLE_CLICK_TO_SET_KEYFRAME)
    l:AddChild(d.doubleClickToSetKeyframeCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-17)
	
	d.holdToResetCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Click and hold to reset'), self.HOLD_TO_RESET)
    l:AddChild(d.holdToResetCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-17)
	
	d.moveTargetParentCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Move target parent'), self.MOVE_TARGET_PARENT)
    l:AddChild(d.moveTargetParentCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.blockOnEvenFramesCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Block on even frames'), self.BLOCK_ON_EVEN_FRAMES)
    l:AddChild(d.blockOnEvenFramesCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-17)
	
	d.blockOnOddFramesCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Block on odd frames'), self.BLOCK_ON_ODD_FRAMES)
    l:AddChild(d.blockOnOddFramesCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.highlightBonesCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Highlight bones'), self.HIGHLIGHT_BONES)
    l:AddChild(d.highlightBonesCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-17)
	
	d.highlightWidthInput = LM.GUI.TextControl(0, '100', self.HIGHLIGHT_WIDTH, LM.GUI.FIELD_INT, MR_PoseTool:Localize('Highlight width:'))
    l:AddChild(d.highlightWidthInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:AddPadding(-10)
	
	d.highlightOpacityInput = LM.GUI.TextControl(0, '100', self.HIGHLIGHT_OPACITY, LM.GUI.FIELD_FLOAT, MR_PoseTool:Localize('Highlight opacity:'))
	d.highlightOpacityInput:SetWheelInc(0.01)
    l:AddChild(d.highlightOpacityInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:PushH()
	
		d.useHighlightCustomColorCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Custom'), self.USE_HIGHLIGHT_CUSTOM_COLOR)
		l:AddChild(d.useHighlightCustomColorCheck, LM.GUI.ALIGN_LEFT, 0)
		
		d.highlightCustomColorSwatch = LM.GUI.ShortColorSwatch(true, self.HIGHLIGHT_CUSTOM_COLOR)
		l:AddChild(d.highlightCustomColorSwatch, LM.GUI.ALIGN_LEFT)
	
	l:Pop()
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.alignHandlesAlongBoneCheck = LM.GUI.CheckBox(MR_PoseTool:Localize('Align handles along bone'), self.ALIGN_HANDLES_ALONG_BONE)
    l:AddChild(d.alignHandlesAlongBoneCheck, LM.GUI.ALIGN_LEFT, 0)
	
	l:AddPadding(-10)
	
	d.handlesDistanceInput = LM.GUI.TextControl(0, '100', self.HANDLES_DISTANCE, LM.GUI.FIELD_FLOAT, MR_PoseTool:Localize('Handles distance:'))
	d.handlesDistanceInput:SetWheelInc(0.01)
    l:AddChild(d.handlesDistanceInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:AddPadding(-10)
	
	d.handlesStrokeOpacityInput = LM.GUI.TextControl(0, '100', self.HANDLES_STROKE_OPACITY, LM.GUI.FIELD_FLOAT, MR_PoseTool:Localize('Handles stroke opacity:'))
	d.handlesStrokeOpacityInput:SetWheelInc(0.01)
    l:AddChild(d.handlesStrokeOpacityInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:AddPadding(-10)
	
	d.handlesFillOpacityInput = LM.GUI.TextControl(0, '100', self.HANDLES_FILL_OPACITY, LM.GUI.FIELD_FLOAT, MR_PoseTool:Localize('Handles fill opacity:'))
	d.handlesFillOpacityInput:SetWheelInc(0.01)
    l:AddChild(d.handlesFillOpacityInput, LM.GUI.ALIGN_RIGHT, 0)
	
	l:AddPadding(-10)
	
	l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
	
	l:AddPadding(-10)
	
	d.useCustomColorsInput = LM.GUI.CheckBox(MR_PoseTool:Localize('Use custom colors'), self.USE_CUSTOM_COLORS)
    l:AddChild(d.useCustomColorsInput, LM.GUI.ALIGN_LEFT, 0)
	
	l:PushH()
	
		d.colorTranslateStrokeSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_TRANSLATE_STROKE)
		l:AddChild(d.colorTranslateStrokeSwatch, LM.GUI.ALIGN_LEFT)
		d.colorTranslateStrokeSwatch:SetToolTip(MR_PoseTool:Localize('Translate handle stroke color Tooltip'))
		
		d.colorTranslateFillSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_TRANSLATE_FILL)
		l:AddChild(d.colorTranslateFillSwatch, LM.GUI.ALIGN_LEFT)
		d.colorTranslateFillSwatch:SetToolTip(MR_PoseTool:Localize('Translate handle fill color Tooltip'))
	
	l:Pop()
	
	l:PushH()
	
		d.colorScaleStrokeSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_SCALE_STROKE)
		l:AddChild(d.colorScaleStrokeSwatch, LM.GUI.ALIGN_LEFT)
		d.colorScaleStrokeSwatch:SetToolTip(MR_PoseTool:Localize('Scale handle stroke color Tooltip'))
		
		d.colorScaleFillSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_SCALE_FILL)
		l:AddChild(d.colorScaleFillSwatch, LM.GUI.ALIGN_LEFT)
		d.colorScaleFillSwatch:SetToolTip(MR_PoseTool:Localize('Scale handle fill color Tooltip'))
	
	l:Pop()
	
	l:PushH()
	
		d.colorMoveJointStrokeSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_MOVE_JOINT_STROKE)
		l:AddChild(d.colorMoveJointStrokeSwatch, LM.GUI.ALIGN_LEFT)
		d.colorMoveJointStrokeSwatch:SetToolTip(MR_PoseTool:Localize('Move joint handle stroke color Tooltip'))
		
		d.colorMoveJointFillSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_MOVE_JOINT_FILL)
		l:AddChild(d.colorMoveJointFillSwatch, LM.GUI.ALIGN_LEFT)
		d.colorMoveJointFillSwatch:SetToolTip(MR_PoseTool:Localize('Move joint handle fill color Tooltip'))
	
	l:Pop()
	
	l:PushH()
	
		d.colorManipulateStrokeSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_MANIPULATE_STROKE)
		l:AddChild(d.colorManipulateStrokeSwatch, LM.GUI.ALIGN_LEFT)
		d.colorManipulateStrokeSwatch:SetToolTip(MR_PoseTool:Localize('Manipulate handle stroke color Tooltip'))
		
		d.colorManipulatFillSwatch = LM.GUI.ShortColorSwatch(true, self.COLOR_MANIPULATE_FILL)
		l:AddChild(d.colorManipulatFillSwatch, LM.GUI.ALIGN_LEFT)
		d.colorManipulatFillSwatch:SetToolTip(MR_PoseTool:Localize('Manipulate handle fill color Tooltip'))
	
	l:Pop()
	
	d.resetColorButton = LM.GUI.Button(MR_PoseTool:Localize('Reset colors'), self.RESET_COLOR)
	l:AddChild(d.resetColorButton, LM.GUI.ALIGN_FILL, 0)
	
	return d
end

function MR_PoseToolSettingsDialog:UpdateWidgets(moho)
	if HV_Font then
		self.quickMenuTooltipsCheck:SetValue(MR_PoseTool.quickMenuTooltips)
	end
    self.doubleClickToSetKeyframeCheck:SetValue(MR_PoseTool.doubleClickToSetKeyframe)
    self.holdToResetCheck:SetValue(MR_PoseTool.holdToReset)
    self.moveTargetParentCheck:SetValue(MR_PoseTool.moveTargetParent)
    self.blockOnEvenFramesCheck:SetValue(MR_PoseTool.blockOnEvenFrames)
    self.blockOnOddFramesCheck:SetValue(MR_PoseTool.blockOnOddFrames)
    self.highlightBonesCheck:SetValue(MR_PoseTool.highlightBones)
    self.highlightWidthInput:SetValue(MR_PoseTool.highlightWidth)
    self.highlightOpacityInput:SetValue(MR_PoseTool.highlightOpacity)
    self.useHighlightCustomColorCheck:SetValue(MR_PoseTool.useHighlightCustomColor)
    self.alignHandlesAlongBoneCheck:SetValue(MR_PoseTool.alignHandlesAlongBone)
	if MR_PoseTool.alignHandlesAlongBone then
		self.handlesDistanceInput:Enable(false)
	else
		self.handlesDistanceInput:Enable(true)
	end
    self.handlesDistanceInput:SetValue(MR_PoseTool.handlesDistance)
    self.handlesStrokeOpacityInput:SetValue(MR_PoseTool.handleStrokeOpacity)
    self.handlesFillOpacityInput:SetValue(MR_PoseTool.handleFillOpacity)
    self.useCustomColorsInput:SetValue(MR_PoseTool.useCustomColors)
	
	if MR_PoseTool.useCustomColors then
		self.colorTranslateStrokeSwatch:Enable(true)
		self.colorTranslateFillSwatch:Enable(true)
		self.colorScaleStrokeSwatch:Enable(true)
		self.colorScaleFillSwatch:Enable(true)
		self.colorMoveJointStrokeSwatch:Enable(true)
		self.colorMoveJointFillSwatch:Enable(true)
		self.colorManipulateStrokeSwatch:Enable(true)
		self.colorManipulatFillSwatch:Enable(true)
		self.resetColorButton:Enable(true)
	else
		self.colorTranslateStrokeSwatch:Enable(false)
		self.colorTranslateFillSwatch:Enable(false)
		self.colorScaleStrokeSwatch:Enable(false)
		self.colorScaleFillSwatch:Enable(false)
		self.colorMoveJointStrokeSwatch:Enable(false)
		self.colorMoveJointFillSwatch:Enable(false)
		self.colorManipulateStrokeSwatch:Enable(false)
		self.colorManipulatFillSwatch:Enable(false)
		self.resetColorButton:Enable(false)
	end
	
	if MR_PoseTool.highlightBones then
		self.highlightWidthInput:Enable(true)
		self.highlightOpacityInput:Enable(true)
		self.useHighlightCustomColorCheck:Enable(true)
	else
		self.highlightWidthInput:Enable(false)
		self.highlightOpacityInput:Enable(false)
		self.useHighlightCustomColorCheck:Enable(false)
	end
	
	if MR_PoseTool.highlightBones and MR_PoseTool.useHighlightCustomColor then
		self.highlightCustomColorSwatch:Enable(true)
	else
		self.highlightCustomColorSwatch:Enable(false)
	end
	
	local highlightCustomColor = LM.rgb_color:new_local()
	highlightCustomColor.r = MR_PoseTool.highlightCustomColorR
	highlightCustomColor.g = MR_PoseTool.highlightCustomColorG
	highlightCustomColor.b = MR_PoseTool.highlightCustomColorB
	highlightCustomColor.a = 255
	
	self.highlightCustomColorSwatch:SetValue(highlightCustomColor)
	
	local colorTranslateStroke = LM.rgb_color:new_local()
	colorTranslateStroke.r = MR_PoseTool.colorStrokeTranslateHandleR
	colorTranslateStroke.g = MR_PoseTool.colorStrokeTranslateHandleG
	colorTranslateStroke.b = MR_PoseTool.colorStrokeTranslateHandleB
	colorTranslateStroke.a = 255
	
	self.colorTranslateStrokeSwatch:SetValue(colorTranslateStroke)
	
	local colorTranslateFill = LM.rgb_color:new_local()
	colorTranslateFill.r = MR_PoseTool.colorFillTranslateHandleR
	colorTranslateFill.g = MR_PoseTool.colorFillTranslateHandleG
	colorTranslateFill.b = MR_PoseTool.colorFillTranslateHandleB
	colorTranslateFill.a = 255
	
	self.colorTranslateFillSwatch:SetValue(colorTranslateFill)
	
	local colorScaleStroke = LM.rgb_color:new_local()
	colorScaleStroke.r = MR_PoseTool.colorStrokeScaleHandleR
	colorScaleStroke.g = MR_PoseTool.colorStrokeScaleHandleG
	colorScaleStroke.b = MR_PoseTool.colorStrokeScaleHandleB
	colorScaleStroke.a = 255

	self.colorScaleStrokeSwatch:SetValue(colorScaleStroke)
	
	local colorScaleFill = LM.rgb_color:new_local()
	colorScaleFill.r = MR_PoseTool.colorFillScaleHandleR
	colorScaleFill.g = MR_PoseTool.colorFillScaleHandleG
	colorScaleFill.b = MR_PoseTool.colorFillScaleHandleB
	colorScaleFill.a = 255

	self.colorScaleFillSwatch:SetValue(colorScaleFill)
	
	local colorMoveJointStroke = LM.rgb_color:new_local()
	colorMoveJointStroke.r = MR_PoseTool.colorStrokeMoveJointHandleR
	colorMoveJointStroke.g = MR_PoseTool.colorStrokeMoveJointHandleG
	colorMoveJointStroke.b = MR_PoseTool.colorStrokeMoveJointHandleB
	colorMoveJointStroke.a = 255

	self.colorMoveJointStrokeSwatch:SetValue(colorMoveJointStroke)
	
	local colorMoveJointFill = LM.rgb_color:new_local()
	colorMoveJointFill.r = MR_PoseTool.colorFillMoveJointHandleR
	colorMoveJointFill.g = MR_PoseTool.colorFillMoveJointHandleG
	colorMoveJointFill.b = MR_PoseTool.colorFillMoveJointHandleB
	colorMoveJointFill.a = 255

	self.colorMoveJointFillSwatch:SetValue(colorMoveJointFill)

	local colorManipulateStroke = LM.rgb_color:new_local()
	colorManipulateStroke.r = MR_PoseTool.colorStrokeManipulateHandleR
	colorManipulateStroke.g = MR_PoseTool.colorStrokeManipulateHandleG
	colorManipulateStroke.b = MR_PoseTool.colorStrokeManipulateHandleB
	colorManipulateStroke.a = 255

	self.colorManipulateStrokeSwatch:SetValue(colorManipulateStroke)
	
	local colorManipulateFill = LM.rgb_color:new_local()
	colorManipulateFill.r = MR_PoseTool.colorFillManipulateHandleR
	colorManipulateFill.g = MR_PoseTool.colorFillManipulateHandleG
	colorManipulateFill.b = MR_PoseTool.colorFillManipulateHandleB
	colorManipulateFill.a = 255

	self.colorManipulatFillSwatch:SetValue(colorManipulateFill)
end

function MR_PoseToolSettingsDialog:OnOK(moho)
	if HV_Font then
		MR_PoseTool.quickMenuTooltips = self.quickMenuTooltipsCheck:Value()
	end
    MR_PoseTool.doubleClickToSetKeyframe = self.doubleClickToSetKeyframeCheck:Value()
    MR_PoseTool.holdToReset = self.holdToResetCheck:Value()
    MR_PoseTool.moveTargetParent = self.moveTargetParentCheck:Value()
    MR_PoseTool.blockOnEvenFrames = self.blockOnEvenFramesCheck:Value()
    MR_PoseTool.blockOnOddFrames = self.blockOnOddFramesCheck:Value()
    MR_PoseTool.highlightBones = self.highlightBonesCheck:Value()
    MR_PoseTool.highlightWidth = self.highlightWidthInput:Value()
    MR_PoseTool.highlightOpacity = self.highlightOpacityInput:Value()
    MR_PoseTool.useHighlightCustomColor = self.useHighlightCustomColorCheck:Value()
    MR_PoseTool.alignHandlesAlongBone = self.alignHandlesAlongBoneCheck:Value()
    MR_PoseTool.handlesDistance = self.handlesDistanceInput:Value()
    MR_PoseTool.handleFillOpacity = self.handlesFillOpacityInput:Value()
    MR_PoseTool.useCustomColors = self.useCustomColorsInput:Value()
end

function MR_PoseToolSettingsDialog:HandleMessage(msg)
	local needRedraw = false
	if msg == self.QUICK_MENU_TOOLTIPS then
		MR_PoseTool.quickMenuTooltips = self.quickMenuTooltipsCheck:Value()
	elseif msg == self.DOUBLE_CLICK_TO_SET_KEYFRAME then
		MR_PoseTool.doubleClickToSetKeyframe = self.doubleClickToSetKeyframeCheck:Value()
	elseif msg == self.HOLD_TO_RESET then
		MR_PoseTool.holdToReset = self.holdToResetCheck:Value()
	elseif msg == self.MOVE_TARGET_PARENT then
		MR_PoseTool.moveTargetParent = self.moveTargetParentCheck:Value()
	elseif msg == self.BLOCK_ON_EVEN_FRAMES then
		MR_PoseTool.blockOnEvenFrames = self.blockOnEvenFramesCheck:Value()
	elseif msg == self.BLOCK_ON_ODD_FRAMES then
		MR_PoseTool.blockOnOddFrames = self.blockOnOddFramesCheck:Value()
	elseif msg == self.HIGHLIGHT_BONES then
		MR_PoseTool.highlightBones = self.highlightBonesCheck:Value()
		if MR_PoseTool.highlightBones then
			self.highlightWidthInput:Enable(true)
			self.highlightOpacityInput:Enable(true)
			self.useHighlightCustomColorCheck:Enable(true)
		else
			self.highlightWidthInput:Enable(false)
			self.highlightOpacityInput:Enable(false)
			self.useHighlightCustomColorCheck:Enable(false)
		end
		
		if MR_PoseTool.highlightBones and MR_PoseTool.useHighlightCustomColor then
			self.highlightCustomColorSwatch:Enable(true)
		else
			self.highlightCustomColorSwatch:Enable(false)
		end
		needRedraw = true
	elseif msg == self.HIGHLIGHT_WIDTH then
		MR_PoseTool.highlightWidth = LM.Clamp(self.highlightWidthInput:Value(), 1, 12)
		self.highlightWidthInput:SetValue(MR_PoseTool.highlightWidth)
		needRedraw = true
	elseif msg == self.HIGHLIGHT_OPACITY then
		MR_PoseTool.highlightOpacity = LM.Clamp(self.highlightOpacityInput:Value(), 0, 1)
		self.highlightOpacityInput:SetValue(MR_PoseTool.highlightOpacity)
		needRedraw = true
	elseif msg == self.USE_HIGHLIGHT_CUSTOM_COLOR then
		MR_PoseTool.useHighlightCustomColor = self.useHighlightCustomColorCheck:Value()
		if MR_PoseTool.highlightBones and MR_PoseTool.useHighlightCustomColor then
			self.highlightCustomColorSwatch:Enable(true)
		else
			self.highlightCustomColorSwatch:Enable(false)
		end
		needRedraw = true
	elseif msg == self.HIGHLIGHT_CUSTOM_COLOR then
		local colorSwatchValue = self.highlightCustomColorSwatch:Value()
		MR_PoseTool.highlightCustomColorR = colorSwatchValue.r
		MR_PoseTool.highlightCustomColorG = colorSwatchValue.g
		MR_PoseTool.highlightCustomColorB = colorSwatchValue.b
		MR_PoseTool.highlightCustomColorA = 255
		needRedraw = true
	elseif msg == self.ALIGN_HANDLES_ALONG_BONE then
		MR_PoseTool.alignHandlesAlongBone = self.alignHandlesAlongBoneCheck:Value()
		if MR_PoseTool.alignHandlesAlongBone then
		self.handlesDistanceInput:Enable(false)
		else
			self.handlesDistanceInput:Enable(true)
		end
		needRedraw = true
	elseif msg == self.HANDLES_DISTANCE then
		MR_PoseTool.handlesDistance = LM.Clamp(self.handlesDistanceInput:Value(), 0.5, 2)
		self.handlesDistanceInput:SetValue(MR_PoseTool.handlesDistance)
		needRedraw = true
	elseif msg == self.HANDLES_STROKE_OPACITY then
		MR_PoseTool.handleStrokeOpacity = LM.Clamp(self.handlesStrokeOpacityInput:Value(), 0, 1)
		self.handlesStrokeOpacityInput:SetValue(MR_PoseTool.handleStrokeOpacity)
		needRedraw = true
	elseif msg == self.HANDLES_FILL_OPACITY then
		MR_PoseTool.handleFillOpacity = LM.Clamp(self.handlesFillOpacityInput:Value(), 0, 1)
		self.handlesFillOpacityInput:SetValue(MR_PoseTool.handleFillOpacity)
		needRedraw = true
	elseif msg == self.USE_CUSTOM_COLORS then
		MR_PoseTool.useCustomColors = self.useCustomColorsInput:Value()
		if MR_PoseTool.useCustomColors then
			self.colorTranslateStrokeSwatch:Enable(true)
			self.colorTranslateFillSwatch:Enable(true)
			self.colorScaleStrokeSwatch:Enable(true)
			self.colorScaleFillSwatch:Enable(true)
			self.colorMoveJointStrokeSwatch:Enable(true)
			self.colorMoveJointFillSwatch:Enable(true)
			self.colorManipulateStrokeSwatch:Enable(true)
			self.colorManipulatFillSwatch:Enable(true)
			self.resetColorButton:Enable(true)
		else
			self.colorTranslateStrokeSwatch:Enable(false)
			self.colorTranslateFillSwatch:Enable(false)
			self.colorScaleStrokeSwatch:Enable(false)
			self.colorScaleFillSwatch:Enable(false)
			self.colorMoveJointStrokeSwatch:Enable(false)
			self.colorMoveJointFillSwatch:Enable(false)
			self.colorManipulateStrokeSwatch:Enable(false)
			self.colorManipulatFillSwatch:Enable(false)
			self.resetColorButton:Enable(false)
		end
		needRedraw = true
	elseif msg == self.COLOR_TRANSLATE_STROKE then
		local colorSwatchValue = self.colorTranslateStrokeSwatch:Value()
		MR_PoseTool.colorStrokeTranslateHandleR = colorSwatchValue.r
		MR_PoseTool.colorStrokeTranslateHandleG = colorSwatchValue.g
		MR_PoseTool.colorStrokeTranslateHandleB = colorSwatchValue.b
		MR_PoseTool.colorStrokeTranslateHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_TRANSLATE_FILL then
		local colorSwatchValue = self.colorTranslateFillSwatch:Value()
		MR_PoseTool.colorFillTranslateHandleR = colorSwatchValue.r
		MR_PoseTool.colorFillTranslateHandleG = colorSwatchValue.g
		MR_PoseTool.colorFillTranslateHandleB = colorSwatchValue.b
		MR_PoseTool.colorFillTranslateHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_SCALE_STROKE then
		local colorSwatchValue = self.colorScaleStrokeSwatch:Value()
		MR_PoseTool.colorStrokeScaleHandleR = colorSwatchValue.r
		MR_PoseTool.colorStrokeScaleHandleG = colorSwatchValue.g
		MR_PoseTool.colorStrokeScaleHandleB = colorSwatchValue.b
		MR_PoseTool.colorStrokeScaleHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_SCALE_FILL then
		local colorSwatchValue = self.colorScaleFillSwatch:Value()
		MR_PoseTool.colorFillScaleHandleR = colorSwatchValue.r
		MR_PoseTool.colorFillScaleHandleG = colorSwatchValue.g
		MR_PoseTool.colorFillScaleHandleB = colorSwatchValue.b
		MR_PoseTool.colorFillScaleHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_MOVE_JOINT_STROKE then
		local colorSwatchValue = self.colorMoveJointStrokeSwatch:Value()
		MR_PoseTool.colorStrokeMoveJointHandleR = colorSwatchValue.r
		MR_PoseTool.colorStrokeMoveJointHandleG = colorSwatchValue.g
		MR_PoseTool.colorStrokeMoveJointHandleB = colorSwatchValue.b
		MR_PoseTool.colorStrokeMoveJointHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_MOVE_JOINT_FILL then
		local colorSwatchValue = self.colorMoveJointFillSwatch:Value()
		MR_PoseTool.colorFillMoveJointHandleR = colorSwatchValue.r
		MR_PoseTool.colorFillMoveJointHandleG = colorSwatchValue.g
		MR_PoseTool.colorFillMoveJointHandleB = colorSwatchValue.b
		MR_PoseTool.colorFillMoveJointHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_MANIPULATE_STROKE then
		local colorSwatchValue = self.colorManipulateStrokeSwatch:Value()
		MR_PoseTool.colorStrokeManipulateHandleR = colorSwatchValue.r
		MR_PoseTool.colorStrokeManipulateHandleG = colorSwatchValue.g
		MR_PoseTool.colorStrokeManipulateHandleB = colorSwatchValue.b
		MR_PoseTool.colorStrokeManipulateHandleA = 255
		needRedraw = true
	elseif msg == self.COLOR_MANIPULATE_FILL then
		local colorSwatchValue = self.colorManipulatFillSwatch:Value()
		MR_PoseTool.colorFillManipulateHandleR = colorSwatchValue.r
		MR_PoseTool.colorFillManipulateHandleG = colorSwatchValue.g
		MR_PoseTool.colorFillManipulateHandleB = colorSwatchValue.b
		MR_PoseTool.colorFillManipulateHandleA = 255
		needRedraw = true
	elseif msg == self.RESET_COLOR then
		MR_PoseTool.colorStrokeTranslateHandleR = 255
		MR_PoseTool.colorStrokeTranslateHandleG = 0
		MR_PoseTool.colorStrokeTranslateHandleB = 0
		MR_PoseTool.colorStrokeTranslateHandleA = 255

		MR_PoseTool.colorFillTranslateHandleR = 248
		MR_PoseTool.colorFillTranslateHandleG = 121
		MR_PoseTool.colorFillTranslateHandleB = 114
		MR_PoseTool.colorFillTranslateHandleA = 255

		MR_PoseTool.colorStrokeScaleHandleR = 255
		MR_PoseTool.colorStrokeScaleHandleG = 0
		MR_PoseTool.colorStrokeScaleHandleB = 0
		MR_PoseTool.colorStrokeScaleHandleA = 255

		MR_PoseTool.colorFillScaleHandleR = 248
		MR_PoseTool.colorFillScaleHandleG = 121
		MR_PoseTool.colorFillScaleHandleB = 114
		MR_PoseTool.colorFillScaleHandleA = 255

		MR_PoseTool.colorStrokeMoveJointHandleR = 255
		MR_PoseTool.colorStrokeMoveJointHandleG = 63
		MR_PoseTool.colorStrokeMoveJointHandleB = 15
		MR_PoseTool.colorStrokeMoveJointHandleA = 255

		MR_PoseTool.colorFillMoveJointHandleR = 255
		MR_PoseTool.colorFillMoveJointHandleG = 189
		MR_PoseTool.colorFillMoveJointHandleB = 46
		MR_PoseTool.colorFillMoveJointHandleA = 255

		MR_PoseTool.colorStrokeManipulateHandleR = 255
		MR_PoseTool.colorStrokeManipulateHandleG = 63
		MR_PoseTool.colorStrokeManipulateHandleB = 15
		MR_PoseTool.colorStrokeManipulateHandleA = 255

		MR_PoseTool.colorFillManipulateHandleR = 255
		MR_PoseTool.colorFillManipulateHandleG = 189
		MR_PoseTool.colorFillManipulateHandleB = 46
		MR_PoseTool.colorFillManipulateHandleA = 255
		
		local colorTranslateStroke = LM.rgb_color:new_local()
		colorTranslateStroke.r = MR_PoseTool.colorStrokeTranslateHandleR
		colorTranslateStroke.g = MR_PoseTool.colorStrokeTranslateHandleG
		colorTranslateStroke.b = MR_PoseTool.colorStrokeTranslateHandleB
		colorTranslateStroke.a = MR_PoseTool.colorStrokeTranslateHandleA
		
		self.colorTranslateStrokeSwatch:SetValue(colorTranslateStroke)
		
		local colorTranslateFill = LM.rgb_color:new_local()
		colorTranslateFill.r = MR_PoseTool.colorFillTranslateHandleR
		colorTranslateFill.g = MR_PoseTool.colorFillTranslateHandleG
		colorTranslateFill.b = MR_PoseTool.colorFillTranslateHandleB
		colorTranslateFill.a = MR_PoseTool.colorFillTranslateHandleA
		
		self.colorTranslateFillSwatch:SetValue(colorTranslateFill)
		
		local colorScaleStroke = LM.rgb_color:new_local()
		colorScaleStroke.r = MR_PoseTool.colorStrokeScaleHandleR
		colorScaleStroke.g = MR_PoseTool.colorStrokeScaleHandleG
		colorScaleStroke.b = MR_PoseTool.colorStrokeScaleHandleB
		colorScaleStroke.a = MR_PoseTool.colorStrokeScaleHandleA

		self.colorScaleStrokeSwatch:SetValue(colorScaleStroke)
		
		local colorScaleFill = LM.rgb_color:new_local()
		colorScaleFill.r = MR_PoseTool.colorFillScaleHandleR
		colorScaleFill.g = MR_PoseTool.colorFillScaleHandleG
		colorScaleFill.b = MR_PoseTool.colorFillScaleHandleB
		colorScaleFill.a = MR_PoseTool.colorFillScaleHandleA

		self.colorScaleFillSwatch:SetValue(colorScaleFill)
		
		local colorMoveJointStroke = LM.rgb_color:new_local()
		colorMoveJointStroke.r = MR_PoseTool.colorStrokeMoveJointHandleR
		colorMoveJointStroke.g = MR_PoseTool.colorStrokeMoveJointHandleG
		colorMoveJointStroke.b = MR_PoseTool.colorStrokeMoveJointHandleB
		colorMoveJointStroke.a = MR_PoseTool.colorStrokeMoveJointHandleA

		self.colorMoveJointStrokeSwatch:SetValue(colorMoveJointStroke)
		
		local colorMoveJointFill = LM.rgb_color:new_local()
		colorMoveJointFill.r = MR_PoseTool.colorFillMoveJointHandleR
		colorMoveJointFill.g = MR_PoseTool.colorFillMoveJointHandleG
		colorMoveJointFill.b = MR_PoseTool.colorFillMoveJointHandleB
		colorMoveJointFill.a = MR_PoseTool.colorFillMoveJointHandleA

		self.colorMoveJointFillSwatch:SetValue(colorMoveJointFill)

		local colorManipulateStroke = LM.rgb_color:new_local()
		colorManipulateStroke.r = MR_PoseTool.colorStrokeManipulateHandleR
		colorManipulateStroke.g = MR_PoseTool.colorStrokeManipulateHandleG
		colorManipulateStroke.b = MR_PoseTool.colorStrokeManipulateHandleB
		colorManipulateStroke.a = MR_PoseTool.colorStrokeManipulateHandleA

		self.colorManipulateStrokeSwatch:SetValue(colorManipulateStroke)
		
		local colorManipulateFill = LM.rgb_color:new_local()
		colorManipulateFill.r = MR_PoseTool.colorFillManipulateHandleR
		colorManipulateFill.g = MR_PoseTool.colorFillManipulateHandleG
		colorManipulateFill.b = MR_PoseTool.colorFillManipulateHandleB
		colorManipulateFill.a = MR_PoseTool.colorFillManipulateHandleA

		self.colorManipulatFillSwatch:SetValue(colorManipulateFill)
		needRedraw = true
	end
	if needRedraw then
		if MR_PoseTool.mohoVersion >= 14 then
			local helper = MOHO.ScriptInterfaceHelper:new_local()
			local moho = helper:MohoObject()
			moho.view:DrawMe()
			helper:delete()
		end
	end	
end

-- **************************************************
-- Keyboard/Mouse Control
-- **************************************************

function MR_PoseTool:OnMouseDown(moho, mouseEvent)
	self.onMMTreshold = true
	self.clickTime = os.time()
	self.forceFollowBonesGraphics = false
	local frame = moho.frame
	local skel = moho:Skeleton()
	if skel == nil or frame == 0 then
		return
	end
	
	if self.showIcons then
		self.graphicMenuMode = self:TestMousePointGraphicMenu(moho, mouseEvent)
		if self.graphicMenuMode == 1 then
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			if mouseEvent.altKey then
				self:AddToFollowBones(moho)
			else
				self:AddToFollowBonesChains(moho)
			end
		elseif self.graphicMenuMode == 2 then	
			self.scaleFollowBones = not self.scaleFollowBones
		elseif self.graphicMenuMode == 3 then	
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			self:AddToLockAngleList(moho)
		elseif self.graphicMenuMode == 4 then	
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			self:AddToLockPosList(moho)
		elseif self.graphicMenuMode == 5 then
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			if mouseEvent.altKey then
				self:CleanUpBonesData(moho.layer)
			else
				self:RemoveSelectedBonesFromFollowList(moho)
				self:RemoveFromLockList(moho)
			end
		elseif self.graphicMenuMode == 6 then
			moho.document:PrepUndo(moho.layer, true)
			moho.document:SetDirty()
			local scriptInfo = moho.layer:ScriptData()
			self.bonesDataActive = not self.bonesDataActive
			local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
			scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
		end
		return
	elseif self.showIcons2 then
		self.graphicMenuMode = self:TestMousePointGraphicMenu(moho, mouseEvent)
		if self.graphicMenuMode == 1 then
			if self.keepSelection then
				self.multiTransform = not self.multiTransform
			end
		elseif self.graphicMenuMode == 2 then	
			self.keepSelection = not self.keepSelection
		elseif self.graphicMenuMode == 3 then	
			self.lockHandles = not self.lockHandles
		elseif self.graphicMenuMode == 4 then	
			self.bakeAdjacentFrames = not self.bakeAdjacentFrames
		elseif self.graphicMenuMode == 5 then
			self.showPath = not self.showPath
		elseif self.graphicMenuMode == 6 then
			self.twosMode = not self.twosMode
		end
		return
	end

	if self.twosMode then
		if self.blockOnEvenFrames and frame % 2 == 0 or self.blockOnOddFrames and not (frame % 2 == 0) then
			return
		end
	end
	local lockHandles = self.lockHandles
	self.isBoneHaveAngleKeyList = {}
	self.isBoneHavePosKeyList = {}
	self.isBoneHaveScaleKeyList = {}
	local selBoneID = -1
	self.selBones = moho:CountSelectedBones()
	if self.selBones == 1 then
		selBoneID = skel:SelectedBoneID()
	end
	self.isLockHandleMouseMoved = false
	self.translationFrame = frame

	if not mouseEvent.doubleClick then
		self.selBonesList = {}
		self.selectedBonesList = {}
		self.multiBoneTranslateList = {}
		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			if bone.fSelected then
				self.selBonesList[i] = true
				table.insert(self.selectedBonesList, i)
				if not skel:IsAncestorSelected(i) then
					table.insert(self.multiBoneTranslateList, i)
				end
			end
		end
	end
	
	self.setKeyframe = false
	self.trPathBone = nil
	self.keepHandles = false
	self.dragging = true
	self.lastVec:Set(mouseEvent.vec)
	self.ignoreBonesList = {}
	local id = -1
	local mouseHoverID = -1
	local secondId = -1
	
	local pickWidth = self.pickWidth
	
	if lockHandles and self.selBones > 0 then
		local bonesVisibilityList = {}
		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			if not bone.fSelected then
				bonesVisibilityList[i+1] = bone.fHidden
				bone.fHidden = true
			end	
		end

		local boneRegion = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
		id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)

		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			if not bone.fSelected then
				bone.fHidden = bonesVisibilityList[i+1]
			end
		end
		
		if boneRegion == -1 then
			id = -1
			secondId = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
			boneRegion = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
			if boneRegion == -1 then
				secondId = -1
			end
		end
	else
		id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
	end

	mouseHoverID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
	local clickToSelect = self.clickToSelect
	local pickID = id
	local firstBone
	local secondBone
	local firstBoneParent
	self.isActive = false
	self.transformPath = false
	self.lockHandlesSelection = false
	if not (mouseEvent.ctrlKey) then
		if lockHandles then
			if selBoneID == -1 and secondId == -1 then
				self.mousePickedID = id
				self.secondBoneID = id
				
				if mouseHoverID > -1 and clickToSelect then
					skel:SelectNone()
					local bone = skel:Bone(id)
					bone.fSelected = true
					self.dragging = false
					return
				end	
			else
				self.mode = self:TestMousePoint(moho, mouseEvent, selBoneID)
				if secondId > -1 and self.mode == 1 then
					id = secondId
					local bone = skel:Bone(id)
					self.mousePickedID = id
					self.secondBoneID = id
					selBoneID = id
					self.dragging = false
					self.lockHandlesSelection = true
					if self.multiTransform and self.keepSelection then
						goto multiTransformSelection
					end
					return
				else
					self.mousePickedID = selBoneID
					self.secondBoneID = selBoneID
				end
			end
		else
			self.mousePickedID = id
			self.secondBoneID = id
		end
	else
		if lockHandles then
			if selBoneID == -1 and secondId == -1 then
				self.mousePickedID = id
				self.secondBoneID = id

				if mouseHoverID > -1 and clickToSelect then
					skel:SelectNone()
					local bone = skel:Bone(id)
					bone.fSelected = true
					self.dragging = false

					return
				end	
			else
				id = selBoneID
				self.mousePickedID = selBoneID
				self.secondBoneID = selBoneID
			end
		else
			id = self.mousePickedID
			self.secondBoneID = id
		end
	end
	
	if id > -1 then
		self.mode = self:TestMousePoint(moho, mouseEvent, id)
	else
		self.mode = self:TestMousePoint(moho, mouseEvent, selBoneID)
	end

	if mouseEvent.doubleClick then	
		local doubleclickMode = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
		if doubleclickMode == -1 then
			local scriptInfo = moho.layer:ScriptData()
			self.bonesDataActive = not self.bonesDataActive
			local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
			scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
			return
		end
	end

	if self.mode > 1 and mouseHoverID < 0 then
		id = selBoneID
		self.mousePickedID = id
		self.secondBoneID = id
	end

	::multiTransformSelection::
	local multiTransformSelection = false
	self.multiSelectionUnselectedMovement = false
	if self.multiTransform and self.keepSelection and self.selBones > 0 then
		local isBoneWasSelected = false
		for i=1, #self.selectedBonesList do
			if self.selectedBonesList[i] == self.secondBoneID then
				isBoneWasSelected = true
				break
			end
		end
		if not isBoneWasSelected then
			skel:SelectNone()
			for _, id in ipairs(self.selectedBonesList) do
				local bone = skel:Bone(id)
				bone.fSelected = true
			end
			self.multiSelectionUnselectedMovement = true
			if mouseHoverID == -1 then
				multiTransformSelection = true
			else
				return
			end
		end
	end
	
	if mouseHoverID == -1 and self.mode ~= 5 or multiTransformSelection then
		self.isMouseDragging = true
		if not mouseEvent.shiftKey and not mouseEvent.altKey then
			if skel then
				skel:SelectNone()
			elseif mesh then
				mesh:SelectNone()
			end
		end
		
		self.selRect.left = mouseEvent.startPt.x
		self.selRect.top = mouseEvent.startPt.y
		self.selRect.right = mouseEvent.pt.x
		self.selRect.bottom = mouseEvent.pt.y
		mouseEvent.view:Graphics():SelectionRect(self.selRect)
		mouseEvent.view:DrawMe()
		return
	end
	
	if id < 0 then
		return
	end
	
	moho.document:PrepUndo(moho.layer, true)
	moho.document:SetDirty()
	
	self.isMouseMoved = false
	self.bonesReset = false
	if mouseEvent.doubleClick and self.secondBoneID > -1 and self.doubleClickToSetKeyframe then
		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			local secondBone = skel:Bone(self.secondBoneID)
			if secondBone then
				if secondBone.fSelected == self.selBonesList[self.secondBoneID] then
					if self.selBonesList[i] then
						bone.fSelected = true
					end
				end
			end
			if bone.fSelected then
				if self.mode == 0 then
					bone.fAnimPos:AddKey(moho.layerFrame)
				elseif self.mode == 1 then
					bone.fAnimAngle:AddKey(moho.layerFrame)
				elseif self.mode == 2 then
					bone.fAnimScale:AddKey(moho.layerFrame)
				end
			end
		end
		self.setKeyframe = true
		return
	end
	
	self.selBoneIsAncestorSelected = false
	if self.multiTransform and self.keepSelection then
		if self.mode == 0 then
			for i=1, #self.selectedBonesList do
				if skel:IsBoneParent(self.secondBoneID, self.selectedBonesList[i]) and self.secondBoneID ~= self.selectedBonesList[i] then
					self.selBoneIsAncestorSelected = true
					break
				end
			end
			
			self.multiBoneTranslateSBValuesPList = {}
			self.multiBoneTranslateSBValuesNList = {}
			self.multiBoneTranslateBakedList = {}
			for i=1, #self.multiBoneTranslateList do
				local sBone = skel:Bone(self.multiBoneTranslateList[i])
				sBone.fTempPos:Set(sBone.fAnimPos:GetValue(moho.layerFrame))
				self.multiBoneTranslateSBValuesPList[i] = sBone.fAnimPos:GetValue(moho.layerFrame - self.interval)
				self.multiBoneTranslateSBValuesNList[i] = sBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
				self.multiBoneTranslateBakedList[i] = false
			end
		elseif self.mode == 1 then
			self.multiBoneAngleSBValuesPList = {}
			self.multiBoneAngleSBValuesNList = {}
			self.multiBoneAngleBakedList = {}
			local lastVec = LM.Vector2:new_local()
			lastVec:Set(mouseEvent.vec)
			for i=1, #self.selectedBonesList do
				local sBone = skel:Bone(self.selectedBonesList[i])
				sBone.fTempAngle = sBone.fAnimAngle:GetValue(moho.layerFrame)
				self.multiBoneAngleSBValuesPList[i] = sBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
				self.multiBoneAngleSBValuesNList[i] = sBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
				self.multiBoneAngleBakedList[i] = false
			end
		elseif self.mode == 2 then
			self.multiBoneScaleSBValuesPList = {}
			self.multiBoneScaleSBValuesNList = {}
			self.multiBoneScaleDeltaList = {}
			self.multiBoneScaleBakedList = {}
			for i=1, #self.selectedBonesList do
				local sBone = skel:Bone(self.selectedBonesList[i])
				sBone.fTempScale = sBone.fAnimScale:GetValue(moho.layerFrame)
				self.multiBoneScaleSBValuesPList[i] = sBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
				self.multiBoneScaleSBValuesNList[i] = sBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
				self.multiBoneScaleDeltaList[i] = sBone.fScale - sBone.fAnimScale:GetValue(moho.layerFrame)
				self.multiBoneScaleBakedList[i] = false
			end
		end
	end

	skel:SelectNone()
	self.startAngle = 0
	self.startAngle2 = 0
	secondBone = skel:Bone(self.secondBoneID)
	
	self.isBoneHaveAngleKeyList[self.secondBoneID] = secondBone.fAnimAngle:HasKey(moho.layerFrame)
	self.isBoneHaveScaleKeyList[self.secondBoneID] = secondBone.fAnimScale:HasKey(moho.layerFrame)
	
	self.jointChain = false
	self.firstBoneID = -1
	
	if self.bonesDataActive then
		self:ValidateLockList(moho)
		
		if #self.lockAngleList > 0 then
			self.lockedBonesSBAngleValuesP = {}
			self.lockedBonesSBAngleValuesN = {}
			self.lockBonesParentStartAngle = {}
			self.lockBonesLastParentTipVec = {}
			self.lockBonesLastParentBaseVec = {}
			self.lockAngleBaked = {}
			
			for l=1, #self.lockAngleList do
				local lBone = skel:Bone(self.lockAngleList[l])
				if lBone then
					if lBone.fParent > -1 then
						local parentBoneTipPos = LM.Vector2:new_local()
						local parentBoneBasePos = LM.Vector2:new_local()
						local parentBone = skel:Bone(lBone.fParent)
						parentBoneBasePos:Set(0, 0)
						
						if (parentBone:IsZeroLength()) then
							parentBoneTipPos:Set(0.1, 0)
						else
							if lBone:IsZeroLength() then
								parentBoneTipPos:Set(0.1, 0)
							else
								parentBoneTipPos:Set(lBone.fLength, 0)
							end
						end
						
						if moho.frame == 0 then
							parentBone.fRestMatrix:Transform(parentBoneBasePos)
							parentBone.fRestMatrix:Transform(parentBoneTipPos)
						else
							parentBone.fMovedMatrix:Transform(parentBoneBasePos)
							parentBone.fMovedMatrix:Transform(parentBoneTipPos)
						end
						
						lBone.fTempAngle = lBone.fAnimAngle:GetValue(moho.layerFrame)
						
						self.lockedBonesSBAngleValuesP[l] = lBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
						self.lockedBonesSBAngleValuesN[l] = lBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
						self.lockBonesLastParentTipVec[l] = parentBoneTipPos
						self.lockBonesLastParentBaseVec[l] = parentBoneBasePos
						self.lockBonesParentStartAngle[l] = 0
						self.lockAngleBaked[l] = false
					end
				end
			end
		end
		
		if #self.lockPosList > 0 then
			self.lockedBonesSBPosValuesP = {}
			self.lockedBonesSBPosValuesN = {}
			self.lockedBonesPos = {}
			self.lockedBonesDeltaPos = {}
			self.lockPosBaked = {}
			for l=1, #self.lockPosList do
				local lBone = skel:Bone(self.lockPosList[l])
				if lBone then
					local bonePos = LM.Vector2:new_local()
					bonePos:Set(0, 0)
					
					if moho.frame == 0 then
						lBone.fRestMatrix:Transform(bonePos)
					else
						lBone.fMovedMatrix:Transform(bonePos)
					end
					
					self.lockPosBaked[l] = false
					self.lockedBonesDeltaPos[l] = lBone.fPos - lBone.fAnimPos:GetValue(moho.layerFrame)
					self.lockedBonesPos[l] = bonePos
					self.lockedBonesSBPosValuesP[l] = lBone.fAnimPos:GetValue(moho.layerFrame - self.interval)
					self.lockedBonesSBPosValuesN[l] = lBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
				end
			end
		end
		
		if #self.followBonesList.id > 0 then
			self:ValidateFollowList(moho)
		end
		
		if #self.followBonesList.id > 0 then
			self.followBonesDataList = {}
			self.followBonesDataList.sBValuesP = {}
			self.followBonesDataList.sBValuesN = {}
			self.followBonesDataList.sBValuesBakedS = {}
			self.followBonesDataList.scaleDelta = {}
			self.followBonesDataList.targetPos = {}
			self.followBonesDataList.distance = {}
			self.followBonesDataList.startAngle = {}
			self.followBonesDataList.lastVec = {}
			self.followBonesDataList.angleDelta = {}
			self.followBonesDataList.lastParentBaseVec = {}
			self.followBonesDataList.lastParentTipVec = {}
			self.followBonesDataList.parentStartAngle = {}
			self.followBonesDataList.bakedA = {}
			self.followBonesDataList.bakedS = {}
			self.followBonesDataList.FAngleP = {}
			self.followBonesDataList.FAngleN = {}
			self.followBonesDataList.block = {}
			for b=1, #self.followBonesList.id do
				local startFollowBone = skel:Bone(self.followBonesList.startBone[b])
				local endFollowBone = skel:Bone(self.followBonesList.endBone[b])
				if startFollowBone and endFollowBone then
					local boneTipPos = LM.Vector2:new_local()
					local boneBasePos = LM.Vector2:new_local()
					local valuesPLis = {}
					local valuesNLis = {}
					local scaleDeltaList = {}
					local bakedSList = {}
					local block = false
					for i=1, #self.followBonesList.id[b] do
						local fBone = skel:Bone(self.followBonesList.id[b][i])
						if fBone then
							if self.followBonesList.id[b][i] == self.secondBoneID then
								block = true
							end
							fBone.fTempScale = fBone.fScale
							table.insert(valuesPLis, fBone.fAnimScale:GetValue(moho.layerFrame - self.interval))
							table.insert(valuesNLis, fBone.fAnimScale:GetValue(moho.layerFrame + self.interval))
							table.insert(scaleDeltaList, fBone.fScale - fBone.fAnimScale:GetValue(moho.layerFrame))
							table.insert(bakedSList, false)
						end
					end
					
					self.followBonesDataList.sBValuesP[b] = valuesPLis
					self.followBonesDataList.sBValuesN[b] = valuesNLis
					self.followBonesDataList.scaleDelta[b] = scaleDeltaList
					self.followBonesDataList.sBValuesBakedS[b] = bakedSList
					self.followBonesDataList.block[b] = block
					
					boneBasePos:Set(0, 0)
					if (startFollowBone:IsZeroLength()) then
						boneTipPos:Set(0.1, 0)
					else
						boneTipPos:Set(endFollowBone.fLength, 0)
					end
					
					if moho.frame == 0 then
						startFollowBone.fRestMatrix:Transform(boneBasePos)
						endFollowBone.fRestMatrix:Transform(boneTipPos)
					else
						startFollowBone.fMovedMatrix:Transform(boneBasePos)
						endFollowBone.fMovedMatrix:Transform(boneTipPos)
					end
					self.followBonesDataList.targetPos[b] = boneTipPos
					
					self.followBonesDataList.distance[b] = MR_Utilities:GetDistance(boneBasePos, boneTipPos)
					self.followBonesDataList.startAngle[b] = 0
					
					self.followBonesDataList.lastVec[b] = boneBasePos
					startFollowBone.fTempAngle = startFollowBone.fAnimAngle:GetValue(moho.layerFrame)
					local followBoneActualAngle = startFollowBone.fAngle
					self.followBonesDataList.angleDelta[b] = followBoneActualAngle - startFollowBone.fAnimAngle:GetValue(moho.layerFrame)
					
					if startFollowBone.fParent > -1 then
						local parentBoneTipPos = LM.Vector2:new_local()
						local parentBoneBasePos = LM.Vector2:new_local()
						local parentBone = skel:Bone(startFollowBone.fParent)
						parentBoneBasePos:Set(0, 0)
						
						if (parentBone:IsZeroLength()) then
							parentBoneTipPos:Set(0.1, 0)
						else
							parentBoneTipPos:Set(endFollowBone.fLength, 0)
						end
						
						if moho.frame == 0 then
							parentBone.fRestMatrix:Transform(parentBoneBasePos)
							parentBone.fRestMatrix:Transform(parentBoneTipPos)
						else
							parentBone.fMovedMatrix:Transform(parentBoneBasePos)
							parentBone.fMovedMatrix:Transform(parentBoneTipPos)
						end
						self.followBonesDataList.lastParentBaseVec[b] = parentBoneBasePos
						self.followBonesDataList.lastParentTipVec[b] = parentBoneTipPos
						self.followBonesDataList.parentStartAngle[b] = 0
					end
					self.followBonesDataList.bakedA[b] = false
					self.followBonesDataList.bakedS[b] = false
					self.followBonesDataList.FAngleP[b] = startFollowBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
					self.followBonesDataList.FAngleN[b] = startFollowBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
				end
			end
		end
		
		self.followLockedBonesList = {}
		self.followLockedBonesList.id = {}
		self.followLockedBonesList.listIndex = {}
		self.followLockedBonesList.list = {} -- 1 follow, 2 lock angle, 3 lock pos
		
		for b=1, #self.followBonesList.id do
			table.insert(self.followLockedBonesList.id, self.followBonesList.id[b][1])
			table.insert(self.followLockedBonesList.listIndex, b)
			table.insert(self.followLockedBonesList.list, 1)
		end
		
		for b=1, #self.lockAngleList do
			table.insert(self.followLockedBonesList.id, self.lockAngleList[b])
			table.insert(self.followLockedBonesList.listIndex, b)
			table.insert(self.followLockedBonesList.list, 2)
		end
		
		for b=1, #self.lockPosList do
			table.insert(self.followLockedBonesList.id, self.lockPosList[b])
			table.insert(self.followLockedBonesList.listIndex, b)
			table.insert(self.followLockedBonesList.list, 3)
		end
		
		local isChanges = false
		
		repeat
			isChanges = false
			for i, y in ipairs(self.followLockedBonesList.id) do
				local myBone = skel:Bone(self.followLockedBonesList.id[i])
				if myBone.fParent > -1 then
					local newParentId = myBone.fParent
					for a, t in ipairs(self.followLockedBonesList.id) do
						if newParentId == self.followLockedBonesList.id[a] then
							if i < a then
								isChanges = true
								self.followLockedBonesList.id[i], self.followLockedBonesList.id[a] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.id, i, a)
								self.followLockedBonesList.listIndex[i], self.followLockedBonesList.listIndex[a] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.listIndex, i, a)
								self.followLockedBonesList.list[i], self.followLockedBonesList.list[a] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.list, i, a)
								break
							end	
						else
							local nextBone = skel:Bone(newParentId)
							repeat 
								local prevBone = nextBone
								for b, g in ipairs(self.followLockedBonesList.id) do
									if prevBone.fParent == self.followLockedBonesList.id[b] then
										if i < b then
											isChanges = true
											self.followLockedBonesList.id[i], self.followLockedBonesList.id[b] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.id, i, b)
											self.followLockedBonesList.listIndex[i], self.followLockedBonesList.listIndex[b] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.listIndex, i, b)
											self.followLockedBonesList.list[i], self.followLockedBonesList.list[b] = MR_Utilities:SwapTwoArrayKeys(self.followLockedBonesList.list, i, b)
										end	
									end		
								end
								if nextBone.fParent > -1 then
									nextBone = skel:Bone(nextBone.fParent)
								end
							until nextBone == prevBone
						end
					end
				end	
			end	
		until isChanges == false
	end

	if self.mode == 5 then
		local bone = skel:Bone(id)
		bone.fSelected = true
		self.selID = skel:BoneID(self.trPathBone)
		self.secondBoneID = id

		self.isBoneHaveAngleKeyList[self.secondBoneID] = bone.fAnimAngle:HasKey(moho.layerFrame)
		self.isBoneHaveScaleKeyList[self.secondBoneID] = bone.fAnimScale:HasKey(moho.layerFrame)
		
		local boneVec = LM.Vector2:new_local()
		boneVec:Set(0, 0)
		bone.fRestMatrix:Transform(boneVec)
		boneVec = boneVec - mouseEvent.startVec
		local d = boneVec:Mag()
		self.boneEnd = 0
		boneVec:Set(bone.fLength, 0)
		bone.fRestMatrix:Transform(boneVec)
		boneVec = boneVec - mouseEvent.startVec
		if (boneVec:Mag() < d) then
			self.boneEnd = 1
		end

		if (self.translationFrame ~= 0 and bone.fSelected) then
			self.boneChanged = true
			bone.fTempPos = bone.fAnimPos:GetValue(self.translationFrame)
			bone.fAnimPos:SetValue(self.translationFrame, bone.fTempPos)
		end
		
		self.isActive = true
		return
	elseif self.mode == 4 then -- manipulate bones
		self.selID = id
		self.boneBakedA = false
		self.boneBakedP = false
		self.boneBakedS = false
		if self.bakeAdjacentFrames then
			self.boneSAngleP = secondBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
			self.boneSAngleN = secondBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
			self.boneSScaleP = secondBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
			self.boneSScaleN = secondBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
		end
		local bone = skel:Bone(id)
		if id >= 0 then
			self.ignoreBonesList[id + 1] = true
		end
		bone.fTempPos:Set(bone.fAnimPos:GetValue(moho.layerFrame))
		bone.fTempAngle = bone.fAnimAngle:GetValue(moho.layerFrame)
		bone.fTempScale = bone.fScale
		
		self.secondBoneSecondDelta = bone.fScale - bone.fAnimScale:GetValue(moho.layerFrame)
		
		self.secondTarget = skel:TargetOfBoneChain(id, moho.layerFrame)
		
		if self.moveTargetParent then
			for b=0, skel:CountBones()-1 do
				local bone = skel:Bone(b)
				if bone.fParent == -1 and skel:IsBoneParent(self.secondTarget, b) then
					self.secondTarget = b
					break
				end
			end
		end
		
		if self.secondTarget >= 0 then
			self.isChainTargeted = true
			local targetBone = skel:Bone(self.secondTarget)
			targetBone.fTempPos = targetBone.fAnimPos:GetValue(moho.layerFrame)
			
			self.targetBonePosP = targetBone.fAnimPos:GetValue(moho.layerFrame - self.interval)
			
			self.targetBonePosN = targetBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
			
			self.isTargetBonePosPBaked = false
			self.isTargetBonePosNBaked = false
		else
			self.isChainTargeted = false
		end
		
		bone.fSelected = true
		local isSmartBone = moho.layer:IsSmartBoneAction(bone:Name())

		self.isParentBonesBaked = false
		self.lastVec:Set(mouseEvent.vec)
		self.parentBones = {}
		self.parentBonesAngleP = {}
		self.parentBonesAngleN = {}
		self.parentBonesScaleP = {}
		self.parentBonesScaleN = {}
		self.parentBonesScaleDelta = {}
		self.startAngle = 0
		self.boneStartAngles = {}
		self.boneStartActualAngles = {}
		table.insert(self.boneStartAngles, bone.fAnimAngle:GetValue(moho.layerFrame))
		table.insert(self.boneStartActualAngles, bone.fAnimAngle.value)

		while bone.fParent >= 0 do
			local parentBone = skel:Bone(bone.fParent)
			parentBone.fTempAngle = parentBone.fAnimAngle:GetValue(moho.layerFrame)
			parentBone.fTempScale = parentBone.fAnimScale:GetValue(moho.layerFrame)
			if (self:CountBoneChildren(skel, bone.fParent, true) > 1) or parentBone.fIgnoredByIK or parentBone.fFixedAngle then
				break
			end
			local parenBoneID = bone.fParent
			bone = skel:Bone(parenBoneID)
			
			self.ignoreBonesList[parenBoneID + 1] = true
			bone.fTempScale = bone.fScale
			table.insert(self.parentBones, parenBoneID)
			
			table.insert(self.parentBonesScaleDelta, bone.fScale - bone.fAnimScale:GetValue(moho.layerFrame))
			
			if moho.layerFrame - self.interval > 0 then
				table.insert(self.parentBonesAngleP, bone.fAnimAngle:GetValue(moho.layerFrame - self.interval))
				table.insert(self.parentBonesScaleP, bone.fAnimScale:GetValue(moho.layerFrame - self.interval))
			else
				table.insert(self.parentBonesAngleP, 0)
				table.insert(self.parentBonesScaleP, 0)
			end
			
			if moho.layerFrame + self.interval > 0 then
				table.insert(self.parentBonesAngleN, bone.fAnimAngle:GetValue(moho.layerFrame + self.interval))
				table.insert(self.parentBonesScaleN, bone.fAnimScale:GetValue(moho.layerFrame + self.interval))
			else
				table.insert(self.parentBonesAngleN, 0)
				table.insert(self.parentBonesScaleN, 0)
			end
			
			table.insert(self.boneStartAngles, bone.fAnimAngle:GetValue(moho.layerFrame))
			table.insert(self.boneStartActualAngles, bone.fAnimAngle.value)
		end

		local startBoneID = self.parentBones[#self.parentBones]
		local startBone = skel:Bone(startBoneID)
		startBone.fTempAngle = startBone.fAnimAngle:GetValue(moho.layerFrame)

		if startBoneID >= 0 then
			self.ignoreBonesList[startBoneID + 1] = true
		end
		
		local startBonePos = LM.Vector2:new_local()
		startBonePos:Set(0, 0)
		startBone.fMovedMatrix:Transform(startBonePos)
		self.startBonePos:Set(startBonePos)
		self.startBoneDist = MR_Utilities:GetDistance(startBonePos, mouseEvent.vec)
		
		self.isChildBonesBaked = false

		self.childBones = {}
		self.childBonesAngelP = {}
		self.childBonesAngelN = {}

		for i=0, skel:CountBones()-1 do
			local childBone = skel:Bone(i)

			if childBone.fParent == id and not childBone.fFixedAngle and not childBone.fIgnoredByIK then
				local angle = childBone.fAnimAngle:GetValue(moho.layerFrame)
				childBone.fTempAngle = angle
				table.insert(self.childBones, i)
				if moho.layerFrame - self.interval > 0 then
					table.insert(self.childBonesAngelP, childBone.fAnimAngle:GetValue(moho.layerFrame - self.interval))
				else
					table.insert(self.childBonesAngelP, 0)
				end
				
				if moho.layerFrame + self.interval > 0 then
					table.insert(self.childBonesAngelN, childBone.fAnimAngle:GetValue(moho.layerFrame + self.interval))
				else
					table.insert(self.childBonesAngelN, 0)
				end
			end
		end
		
		if self.mode == 4 then
			self.isActive = true
			moho:UpdateBonePointSelection()
			mouseEvent.view:DrawMe()
			moho:UpdateSelectedChannels()
			self.lastVec:Set(mouseEvent.vec)
			return
		end
	end

	if secondBone.fParent > -1 and not secondBone:IsZeroLength() then
		self.firstBoneID = secondBone.fParent
		firstBone = skel:Bone(self.firstBoneID)
		
		self.isBoneHaveAngleKeyList[self.firstBoneID] = firstBone.fAnimAngle:HasKey(moho.layerFrame)
		self.isBoneHaveScaleKeyList[self.firstBoneID] = firstBone.fAnimScale:HasKey(moho.layerFrame)

		local firstBoneChilds = skel:CountBoneChildren(self.firstBoneID, true)
		local secondBonePos = LM.Vector2:new_local()
		secondBonePos:Set(secondBone.fAnimPos:GetValue(moho.layerFrame))
		if firstBone.fIgnoredByIK == false and not firstBone.fFixedAngle and not secondBone.fFixedAngle and secondBone.fIgnoredByIK == false and firstBoneChilds == 1 and MR_Utilities:Round(secondBone.fPos.y) == 0 
		and not MR_Utilities:IsEqual(secondBonePos.x, 0, 0.0001) and not firstBone:IsZeroLength() then
			self.jointChain = true
		end
	end	
	
	self.secondBoneID = id
	secondBone.fSelected = true
	
	local useFirstBone = self.jointChain and (self.mode == 0 or self.mode == 3)
	
	
	if self.secondBoneID >= 0 then
		self.ignoreBonesList[self.secondBoneID + 1] = true
	end
	
	if self.bakeAdjacentFrames then
		self.boneBakedA = false
		self.boneBakedP = false
		self.boneBakedS = false
		
		if useFirstBone then
			if self.firstBoneID >= 0 then
				self.ignoreBonesList[self.firstBoneID + 1] = true
			end
			self.boneFAngleP = firstBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
			self.boneFAngleN = firstBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
			self.boneFScaleP = firstBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
			self.boneFScaleN = firstBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
		end	
		
		self.boneSAngleP = secondBone.fAnimAngle:GetValue(moho.layerFrame - self.interval)
		self.boneSAngleN = secondBone.fAnimAngle:GetValue(moho.layerFrame + self.interval)
		
		self.boneSPosP = secondBone.fAnimPos:GetValue(moho.layerFrame - self.interval) 
		self.boneSPosN = secondBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
		
		self.boneSScaleP = secondBone.fAnimScale:GetValue(moho.layerFrame - self.interval)
		self.boneSScaleN = secondBone.fAnimScale:GetValue(moho.layerFrame + self.interval)
	end
	
	moho.layer:UpdateCurFrame()
	self.secondTarget = skel:TargetOfBoneChain(self.secondBoneID, moho.layerFrame)
	if self.moveTargetParent then
		for b=0, skel:CountBones()-1 do
			local bone = skel:Bone(b)
			if bone.fParent == -1 and skel:IsBoneParent(self.secondTarget, b) then
				self.secondTarget = b
				break
			end
		end
	end
	
	if self.secondTarget >= 0 then
		self.isChainTargeted = true
		local targetBone = skel:Bone(self.secondTarget)
		targetBone.fTempPos = targetBone.fAnimPos:GetValue(moho.layerFrame)
		
		self.targetBonePosP = targetBone.fAnimPos:GetValue(moho.layerFrame - self.interval)
		
		self.targetBonePosN = targetBone.fAnimPos:GetValue(moho.layerFrame + self.interval)
		
		self.isTargetBonePosPBaked = false
		self.isTargetBonePosNBaked = false
		
	else
		self.isChainTargeted = false
	end
	
	local firstBoneAngleDelta = 0
	local secondBoneAngleDelta = 0

	if self.isChainTargeted then
		local firstBoneStretchDelta
		local firstBoneIKStratching
		if useFirstBone then
			firstBoneStretchDelta = 0
			firstBoneIKStratching = firstBone.fMaxAutoScaling
			firstBone.fMaxAutoScaling = 10000
		end
		
		local secondBoneStretchDelta = 0
		local secondBoneIKStratching = secondBone.fMaxAutoScaling
		
		secondBone.fMaxAutoScaling = 10000
		
		moho.layer:UpdateCurFrame()
		
		local firstBoneFSize
		local firstBoneFAngle
		local isFirstBoneIgnoredByIK
		if useFirstBone then
			firstBoneFSize = firstBone.fScale
			firstBoneFAngle = firstBone.fAngle
			isFirstBoneIgnoredByIK = firstBone.fIgnoredByIK
		end
		
		local secondBoneFSize = secondBone.fScale
		local secondBoneFAngle = secondBone.fAngle
		
		local isSecondBoneIgnoredByIK = secondBone.fIgnoredByIK
		if useFirstBone then
			firstBone.fIgnoredByIK = true
		end
		
		secondBone.fIgnoredByIK = true
		
		moho.layer:UpdateCurFrame()
		
		if useFirstBone then
			firstBoneStretchDelta = firstBoneFSize - firstBone.fScale
			firstBoneAngleDelta = firstBoneFAngle - firstBone.fAngle
		end
		
		secondBoneStretchDelta = secondBoneFSize - secondBone.fScale
		secondBoneAngleDelta = secondBoneFAngle - secondBone.fAngle
		
		if useFirstBone then
			firstBone.fIgnoredByIK = isFirstBoneIgnoredByIK
			firstBone.fMaxAutoScaling = firstBoneIKStratching
		end
		
		secondBone.fIgnoredByIK = isSecondBoneIgnoredByIK
		secondBone.fMaxAutoScaling = secondBoneIKStratching
		if useFirstBone then
			if (self.ignoreZeroScaledBones and MR_Utilities:Round(firstBone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
				firstBone.fAnimScale:SetValue(moho.layerFrame, firstBone.fAnimScale:GetValue(moho.layerFrame) + firstBoneStretchDelta)
			end	
			firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fAnimAngle:GetValue(moho.layerFrame) + firstBoneAngleDelta)
		end
		if (self.ignoreZeroScaledBones and MR_Utilities:Round(secondBone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
			secondBone.fAnimScale:SetValue(moho.layerFrame, secondBone.fAnimScale:GetValue(moho.layerFrame) + secondBoneStretchDelta)
		end	
		secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBone.fAnimAngle:GetValue(moho.layerFrame) + secondBoneAngleDelta)
		
		moho.layer:UpdateCurFrame()
	end	
	self.isTargetMoved = false
	
	local secondTipVec = LM.Vector2:new_local()
	local firstVec = LM.Vector2:new_local()
	local secondVec = LM.Vector2:new_local()
	secondTipVec:Set(secondBone.fLength, 0)
	firstVec:Set(0, 0)
	secondVec:Set(0, 0)
	secondBone.fMovedMatrix:Transform(secondTipVec)
	secondBone.fMovedMatrix:Transform(secondVec)
	
	self.secondBonePos:Set(secondVec)
	
	if useFirstBone then
		firstBone.fMovedMatrix:Transform(firstVec)
		self.firstBonePos:Set(firstVec)
		self.firstDist = MR_Utilities:GetDistance(self.firstBonePos, self.secondBonePos)
		self.ignoreBonesList[self.firstBoneID + 1] = true
	end
	
	self.secondBoneTipPos:Set(secondTipVec)
	self.secondBoneDist = MR_Utilities:GetDistance(self.secondBonePos, self.secondBoneTipPos)
	local mousePos = mouseEvent.vec
	
	self.clickOffset = self.secondBonePos - mousePos
	
	if self.mode == 2 then
		self.clickOffset = self.secondBoneTipPos - mousePos
	end
	
	if useFirstBone then
		self.firstBoneSizeDelta = firstBone.fScale - firstBone.fAnimScale:GetValue(moho.layerFrame)
	end	
	self.secondBoneSizeDelta = secondBone.fScale - secondBone.fAnimScale:GetValue(moho.layerFrame)
	
	self.isChildBonesBaked = false

	self.childBones = {}
	self.childBonesAngelP = {}
	self.childBonesAngelN = {}
	
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if  bone.fParent == self.secondBoneID and not bone.fFixedAngle and not bone.fIgnoredByIK then
			local angle = bone.fAnimAngle:GetValue(moho.layerFrame)
			bone.fTempAngle = angle
			table.insert(self.childBones, i)
			
			if moho.layerFrame - self.interval > 0 then
				table.insert(self.childBonesAngelP, bone.fAnimAngle:GetValue(moho.layerFrame - self.interval))
			else
				table.insert(self.childBonesAngelP, 0)
			end
			
			if moho.layerFrame + self.interval > 0 then
				table.insert(self.childBonesAngelN, bone.fAnimAngle:GetValue(moho.layerFrame + self.interval))
			else
				table.insert(self.childBonesAngelN, 0)
			end
		end
	end
	
	local firstBoneActualAngle
	
	if useFirstBone then
		firstBoneActualAngle = firstBone.fAngle
		self.firstBoneAngleDelta = firstBoneActualAngle - firstBone.fAnimAngle:GetValue(moho.layerFrame)
	end
	
	local secondBoneActualAngle = secondBone.fAngle
	self.secondBoneAngleDelta = secondBoneActualAngle - secondBone.fAnimAngle:GetValue(moho.layerFrame)
	
	self.lastVec2:Set(0, 0)
	skel:UpdateBoneMatrix()
	secondBone.fMovedMatrix:Transform(self.lastVec2)
	
	if self.mode > 1 then
		if useFirstBone then
			firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fAnimAngle:GetValue(moho.layerFrame))
			firstBone.fAnimAngle.value = firstBoneActualAngle
		end
	
		secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBone.fAnimAngle:GetValue(moho.layerFrame))
		secondBone.fAnimAngle.value = secondBoneActualAngle
	end	
	
	if useFirstBone then
		firstBone.fTempScale = firstBone.fScale
		firstBone.fTempAngle = firstBone.fAngle
	end

	secondBone.fTempScale = secondBone.fScale
	secondBone.fTempAngle = secondBone.fAngle
	
	if self.mode == 0 then
		secondBone.fTempPos:Set(secondBone.fAnimPos:GetValue(moho.layerFrame))
	end
	
	self.isActive = true
	
	if useFirstBone then
		self.firstBoneParentID = firstBone.fParent
		if self.firstBoneParentID > -1 then
			firstBoneParent = skel:Bone(self.firstBoneParentID)
			self.firstBoneParentIBIK = firstBoneParent.fIgnoredByIK
			firstBoneParent.fIgnoredByIK = true
		end
	end

	local boneFirstLenght
	local boneFirstScale
	if useFirstBone then
		boneFirstLenght = secondBone.fPos.x
		boneFirstScale = firstBone.fScale
	end
	local boneSecondLenght = secondBone.fLength
	local boneSecondScale = secondBone.fScale
	if useFirstBone then
		self.firstBoneScalePercent = ((boneFirstLenght * boneFirstScale) / ((boneFirstLenght * boneFirstScale) + (boneSecondLenght * boneSecondScale))) * 100
		self.firstBoneOffset = firstBone.fScale - firstBone.fAnimScale:GetValue(moho.layerFrame)
	end
	self.secondBoneOffset = secondBone.fScale - secondBone.fAnimScale:GetValue(moho.layerFrame)
	moho.layer:UpdateCurFrame()
	moho:UpdateBonePointSelection()
	mouseEvent.view:DrawMe()
	self.isMouseMoved = false
end

function MR_PoseTool:OnMouseMoved(moho, mouseEvent)
	if self.onMMTreshold then
		self.onMMTreshold = false
		return
	end
	local frame = moho.frame
	local skel = moho:Skeleton()
	if skel == nil or frame == 0 then
		mouseEvent.view:SetCursor(MOHO.disabledCursor)
		return
	end
	
	if not (mouseEvent.ctrlKey) then
		local pos = LM.Vector2:new_local()
		pos:Set(mouseEvent.vec)
		local m = LM.Matrix:new_local()
		moho.layer:GetFullTransform(moho.frame, m, moho.document)
		m:Transform(pos)
		self.graphicsMenuCenter:Set(pos)
	end
	
	if self.twosMode then
		if self.blockOnEvenFrames and frame % 2 == 0 or self.blockOnOddFrames and not (frame % 2 == 0)then
			self.showIcons = false
			self.showIcons2 = false
			
			local pickWidth = self.pickWidth
			if not mouseEvent.ctrlKey then
				self.mouseHoverIDGraphicMenu = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
				self.showIcons = false
				self.showIcons2 = false
				mouseEvent.view:SetCursor(MOHO.disabledCursor)
			elseif mouseEvent.ctrlKey and self.mouseHoverIDGraphicMenu == -1 then
				if mouseEvent.shiftKey then
					self.showIcons2 = true
					if self.showIcons or self.showIcons2 then
						self.graphicMenuMode = self:TestMousePointGraphicMenu(moho, mouseEvent)
					end
					mouseEvent.view:SetCursor(self.mainCursor)
				else
					self.showIcons2 = false
					mouseEvent.view:SetCursor(MOHO.disabledCursor)
				end
			end
			mouseEvent.view:DrawMe()
			return
		end
	end

	if self.isMouseDragging then
		mouseEvent.view:Graphics():SelectionRect(self.selRect)
		self.selRect.right = mouseEvent.pt.x
		self.selRect.bottom = mouseEvent.pt.y
		mouseEvent.view:Graphics():SelectionRect(self.selRect)
		mouseEvent.view:RefreshView()
		mouseEvent.view:DrawMe()
		return
	end

	if self.multiSelectionUnselectedMovement then
		self.isMouseMoved = true
		return
	end
		
	if self.lockHandlesSelection then
		self.isLockHandleMouseMoved = true
	end

	local boneID = -1
	local bone
	local lockMousePickedID = -1
	local selectedBones = moho:CountSelectedBones()
	local lockHandles = self.lockHandles
	
	if selectedBones == 1 then
		boneID = skel:SelectedBoneID()
		bone = skel:Bone(boneID)
	end
	self.showIcons = false
	self.showIcons2 = false
	self.showIcons2Alt = false
	
	local pickWidth = self.pickWidth
	if not mouseEvent.ctrlKey then
		self.mouseHoverIDGraphicMenu = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
		self.showIcons = false
		self.showIcons2 = false
	elseif mouseEvent.ctrlKey and self.mouseHoverIDGraphicMenu == -1 then
		if mouseEvent.shiftKey then
			self.showIcons2 = true
		else
			self.showIcons2 = false
		end
		
		if not mouseEvent.shiftKey then
			if mouseEvent.altKey then
				self.showIcons2Alt = true
			end
			self.showIcons = true
		else
			self.showIcons = false
		end
	end

	if self.showIcons or self.showIcons2 then
		self.graphicMenuMode = self:TestMousePointGraphicMenu(moho, mouseEvent)
	end
	
	self.mouseHoverID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)

	if (not self.dragging) then
		if (not mouseEvent.ctrlKey and not lockHandles) or lockHandles then
			if self.multiTransform and self.keepSelection and not lockHandles and selectedBones > 1 then
				local bones = {}
				for i=0, skel:CountBones()-1 do
					local tBone = skel:Bone(i)
					table.insert(bones, tBone.fHidden)
					if not tBone.fSelected then
						tBone.fHidden = true
					end
				end
				self.mousePickedID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
				self.mouseHoverID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
				for i, bool in ipairs(bones) do
					local tBone = skel:Bone(i-1)
					tBone.fHidden = bool
				end
			else
				if (selectedBones ~= 1 and not mouseEvent.ctrlKey) or (not lockHandles and not mouseEvent.ctrlKey) then
					if lockHandles and selectedBones > 1 then
						local bones = {}
						for i=0, skel:CountBones()-1 do
							local tBone = skel:Bone(i)
							table.insert(bones, tBone.fHidden)
							if not tBone.fSelected then
								tBone.fHidden = true
							end
						end

						self.mousePickedID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
						lockMousePickedID = self.mousePickedID 
						boneID = self.mousePickedID 
						self.mouseHoverID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)

						for i, bool in ipairs(bones) do
							local tBone = skel:Bone(i-1)
							tBone.fHidden = bool
						end
					else
						self.mousePickedID = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, false)
					end
				end
			end
		end
		
		if not (mouseEvent.ctrlKey) then
			if lockHandles and selectedBones >= 1 then
				self.additionHandles = self:CheckBone(moho, boneID)
				lockMousePickedID = self.mousePickedID 
				self.mousePickedID = boneID
			else
				if self.mouseHoverID == -1 then
					self.mousePickedID = -1
				end
				self.additionHandles = self:CheckBone(moho, self.mousePickedID)
			end	
		else
			if lockHandles and selectedBones == 1 then
				self.additionHandles = self:CheckBone(moho, boneID)
				lockMousePickedID = self.mousePickedID 
				self.mousePickedID = boneID
			end
		end
		
		local mode
		
		if self.multiTransform and self.keepSelection and not self.lockHandles then
			if self.mousePickedID > -1 and selectedBones > 0 then
				local tBone = skel:Bone(self.mousePickedID)
				if not tBone.fSelected then
					self.mousePickedID = -1
					mouseEvent.view:SetCursor(self.mainCursor)
					mouseEvent.view:DrawMe()
					return
				end
			end
		end
		
		if self.multiTransform and self.keepSelection and selectedBones > 1 then
			self.additionHandles = false
		end
		
		if lockHandles and selectedBones >= 1 then
			if not self.showIcons then
				mode = self:TestMousePoint(moho, mouseEvent, boneID)
				self.drawMode = mode
				if self.mouseHoverID > -1 then
					if mode == 0 or mode == 5 then
						mouseEvent.view:SetCursor(MOHO.moveCursor)
					elseif (mode == 1) then
						if lockMousePickedID ~= self.mouseHoverID then
							mouseEvent.view:SetCursor(self.mainCursor)
						else
							mouseEvent.view:SetCursor(MOHO.rotateCursor)
						end
					elseif (mode == 2) then
						mouseEvent.view:SetCursor(MOHO.scaleCursor)
					elseif (mode == 3) then
						mouseEvent.view:SetCursor(self.mjCursor)
					elseif (mode == 4) then
						mouseEvent.view:SetCursor(self.mbCursor)		
					end
				else
					mouseEvent.view:SetCursor(self.mainCursor)
				end
			end
		else
			if self.mouseHoverID > -1 or bone ~= nil then
				local isBoneSelected = false
				if self.multiTransform and self.keepSelection then
					if self.mousePickedID > -1 and self.mousePickedID == self.mouseHoverID then
						isBoneSelected = true
					end
				else
					if (not self.multiTransform and self.keepSelection) or (not self.multiTransform and self.keepSelection) and not self.lockHandles then
						isBoneSelected = true
					elseif not self.keepSelection and not self.lockHandles then
						isBoneSelected = true
					else
						if self.mouseHoverID > -1 then
							local selBone = skel:Bone(self.mouseHoverID)
							if selBone.fSelected then
								isBoneSelected = true
							end
						end
					end
				end

				if isBoneSelected then
					if not self.showIcons then
						if self.multiTransform and self.keepSelection then
							mode = self:TestMousePoint(moho, mouseEvent, self.mousePickedID)
						else
							mode = self:TestMousePoint(moho, mouseEvent, boneID)
						end
						
						self.drawMode = mode
						if not (self.mouseHoverID < 0 and mode ~= 5) then
							if mode == 0 or mode == 5 then
								mouseEvent.view:SetCursor(MOHO.moveCursor)
							elseif (mode == 1) then
								if self.mousePickedID ~= self.mouseHoverID and mouseEvent.ctrlKey then
									mouseEvent.view:SetCursor(self.mainCursor)
								else
									mouseEvent.view:SetCursor(MOHO.rotateCursor)
								end
							elseif (mode == 2) then
								mouseEvent.view:SetCursor(MOHO.scaleCursor)
							elseif (mode == 3) then
								mouseEvent.view:SetCursor(self.mjCursor)
							elseif (mode == 4) then
								mouseEvent.view:SetCursor(self.mbCursor)		
							end
						else
							mouseEvent.view:SetCursor(self.mainCursor)
						end
					end
				else
					mouseEvent.view:SetCursor(self.mainCursor)
				end
			else
				mouseEvent.view:SetCursor(self.mainCursor)
			end
		end
		
		mouseEvent.view:DrawMe()
		return
	end
	
	if self.isActive == false then
		return
	end

	if self.mode == 0 or self.mode == 5 then -- move
		self:OnMouseMovedT(moho, mouseEvent)
	elseif self.mode == 1 then -- rotate
		self:OnMouseMovedR(moho, mouseEvent)
	elseif self.mode == 2 then -- scale rotate
		self:OnMouseMovedS(moho, mouseEvent)
	elseif self.mode == 3 then -- move joint
		if self.jointChain then
			self:OnMouseMovedJ(moho, mouseEvent)
		end
	elseif self.mode == 4 then -- manipulate bones
		self:OnMouseMovedM(moho, mouseEvent)
	end
	self.isMouseMoved = true
end

function MR_PoseTool:OnMouseMovedJ(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	local firstBone = skel:Bone(self.firstBoneID)
	local secondBone = skel:Bone(self.secondBoneID)
	
	if self.bakeAdjacentFrames and not self.boneBakedA then
		self:BakeFrames(moho, secondBone, firstBone, true, false, true)
		self.boneBakedA = true
	end
	
	local vectorMousePos = (mouseEvent.vec + self.clickOffset)

	local firstCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.firstBonePos)

	local firstDelta = (firstCursorDist / self.firstDist)
	firstBone.fAnimScale:SetValue(moho.layerFrame, (firstBone.fTempScale * firstDelta) - self.firstBoneSizeDelta)
	
	if self.isChainTargeted then
		local secondCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.secondBoneTipPos)
		local secondDelta = (secondCursorDist / self.secondBoneDist)
		secondBone.fAnimScale:SetValue(moho.layerFrame, (secondBone.fTempScale * secondDelta) - self.secondBoneSizeDelta)
		
		if mouseEvent.shiftKey then
			local totalDist = firstCursorDist + secondCursorDist
			local distP = (totalDist / 100) * self.firstBoneScalePercent
			distP = distP / firstBone.fLength
			local secondDistP = (totalDist / 100) * (100 - self.firstBoneScalePercent)
			secondDistP = secondDistP / secondBone.fLength
			firstBone.fAnimScale:SetValue(moho.layerFrame, distP - self.firstBoneOffset)
			secondBone.fAnimScale:SetValue(moho.layerFrame, secondDistP - self.secondBoneOffset)
		end
		
		skel:IKAngleSolver(self.firstBoneID, vectorMousePos, 1, true, false)
		local firstBoneNewAngle = firstBone.fAngle - self.firstBoneAngleDelta
		
		firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBoneNewAngle)
		firstBone.fAnimAngle.value = firstBone.fAngle

		if not secondBone.fFixedAngle then
			firstBone.fIgnoredByIK = true
			skel:IKAngleSolver(self.secondBoneID, self.secondBoneTipPos, 1, true, true)
			
			secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBone.fAngle - self.secondBoneAngleDelta)
			secondBone.fAnimAngle.value = secondBone.fAngle

			firstBone.fIgnoredByIK = false

			moho.layer:UpdateCurFrame()

			skel:IKAngleSolver(self.secondBoneID, self.secondBoneTipPos, 1, true, true)
			
			local secondBoneNewAngle = secondBone.fAngle - self.secondBoneAngleDelta
			
			secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBoneNewAngle)
			secondBone.fAnimAngle.value = secondBone.fAngle

			firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fAngle - self.firstBoneAngleDelta)
			firstBone.fAnimAngle.value = firstBone.fAngle
			
			firstBone.fIgnoredByIK = currentIgnoredByIK
		end
	else
		if mouseEvent.shiftKey then
			local firstCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.firstBonePos)
			local secondCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.secondBoneTipPos)

			local firstDelta = (firstCursorDist / self.firstDist)
			local secondDelta = (secondCursorDist / self.secondBoneDist)
			firstBone.fAnimScale:SetValue(moho.layerFrame, (firstBone.fTempScale * firstDelta) - self.firstBoneSizeDelta)
			secondBone.fAnimScale:SetValue(moho.layerFrame, (secondBone.fTempScale * secondDelta) - self.secondBoneSizeDelta)
			
			local totalDist = firstCursorDist + secondCursorDist
			local distP = (totalDist / 100) * self.firstBoneScalePercent
			distP = distP / firstBone.fLength
			local secondDistP = (totalDist / 100) * (100 - self.firstBoneScalePercent)
			secondDistP = secondDistP / secondBone.fLength
			firstBone.fAnimScale:SetValue(moho.layerFrame, distP - self.firstBoneOffset)
			secondBone.fAnimScale:SetValue(moho.layerFrame, secondDistP - self.secondBoneOffset)
			
			skel:IKAngleSolver(self.firstBoneID, vectorMousePos, 1, true, false)
			
			local originalAngle = firstBone.fTempAngle
			local correctedAngle = firstBone.fAngle
			local delta = originalAngle - correctedAngle

			while math.abs(delta) > math.rad(180) do
				if delta > math.rad(180) then
					correctedAngle = correctedAngle + math.rad(360)
				elseif delta < math.rad(-180) then
					correctedAngle = correctedAngle - math.rad(360)
				end
				delta = originalAngle - correctedAngle
			end

			local restoredAngle = correctedAngle - self.firstBoneAngleDelta
			
			firstBone.fAnimAngle:SetValue(moho.layerFrame, restoredAngle)
			firstBone.fAnimAngle.value = firstBone.fAngle
			
			secondBone.fAnimScale.value = secondBone.fScale
			local currentIgnoredByIK = firstBone.fIgnoredByIK
			
			if not secondBone.fFixedAngle then
				firstBone.fIgnoredByIK = true
				skel:IKAngleSolver(self.secondBoneID, self.secondBoneTipPos, 10, true, true)
				
				secondBone.fAnimAngle:SetValue(moho.layerFrame, secondBone.fAngle - self.secondBoneAngleDelta)
				secondBone.fAnimAngle.value = secondBone.fAngle

				firstBone.fIgnoredByIK = false

				moho.layer:UpdateCurFrame()

				skel:IKAngleSolver(self.secondBoneID, self.secondBoneTipPos, 10, true, true)
				
				originalAngle = secondBone.fTempAngle
				correctedAngle = secondBone.fAngle
				delta = originalAngle - correctedAngle

				while math.abs(delta) > math.rad(180) do
					if delta > math.rad(180) then
						correctedAngle = correctedAngle + math.rad(360)
					elseif delta < math.rad(-180) then
						correctedAngle = correctedAngle - math.rad(360)
					end
					delta = originalAngle - correctedAngle
				end

				restoredAngle = correctedAngle - self.secondBoneAngleDelta
				
				secondBone.fAnimAngle:SetValue(moho.layerFrame, restoredAngle)
				secondBone.fAnimAngle.value = secondBone.fAngle

				originalAngle = firstBone.fTempAngle
				correctedAngle = firstBone.fAngle
				delta = originalAngle - correctedAngle

				while math.abs(delta) > math.rad(180) do
					if delta > math.rad(180) then
						correctedAngle = correctedAngle + math.rad(360)
					elseif delta < math.rad(-180) then
						correctedAngle = correctedAngle - math.rad(360)
					end
					delta = originalAngle - correctedAngle
				end

				restoredAngle = correctedAngle - self.firstBoneAngleDelta
				
				firstBone.fAnimAngle:SetValue(moho.layerFrame, restoredAngle)
				firstBone.fAnimAngle.value = firstBone.fAngle
				
				firstBone.fIgnoredByIK = currentIgnoredByIK
			end
		else
			local bone = firstBone
			local center = LM.Vector2:new_local()
			center:Set(0, 0)
			skel:UpdateBoneMatrix(self.firstBoneID)
			bone.fMovedMatrix:Transform(center)
			
			local mousePos = mouseEvent.vec
			
			local angle = self.startAngle
			local v1 = self.lastVec - center
			local v2 = mousePos - center
			v2:Rotate(-math.atan2(v1.y, v1.x))
			angle = angle + math.atan2(v2.y, v2.x)
			self.startAngle = angle
			self.lastVec:Set(mousePos)
			local angleSign = 1.0
			if (not bone.fFixedAngle) then
				angleSign = bone:ParentalFlipFactor()
			end

			local newAgle = (bone.fTempAngle + (angle * angleSign)) - self.firstBoneAngleDelta

			if not bone.fFixedAngle then
				if bone.fConstraints then
					local min = bone.fAnimAngle:GetValue(0) - self.firstBoneAngleDelta
					local max = min + bone.fMaxConstraint
					min = min + bone.fMinConstraint
					newAgle = LM.Clamp(newAgle, min, max)
				end
			end
			if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
				bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
				bone.fAnimAngle.value = bone.fAngle
				if self.bakeAdjacentFrames and not self.boneBakedA then
					self:BakeFrames(moho, firstBone, nil, true, false, false)
					self.boneBakedA = true
				end
			end
			
			moho.layer:UpdateCurFrame()

			local bone = secondBone
			local center = LM.Vector2:new_local()

			center:Set(0, 0)
			skel:UpdateBoneMatrix(self.secondBoneID)
			bone.fMovedMatrix:Transform(center)
			
			local angle2 = self.startAngle2
			local v1 = self.lastVec2 - self.secondBoneTipPos
			local v2 = center - self.secondBoneTipPos
			v2:Rotate(-math.atan2(v1.y, v1.x))
			angle2 = angle2 + math.atan2(v2.y, v2.x)
			self.startAngle2 = angle2
			self.lastVec2:Set(center)
			
			local angleSign2 = 1.0
			if (not bone.fFixedAngle) then
				angleSign2 = bone:ParentalFlipFactor()
			end

			local newAgle2 = (bone.fTempAngle + (angle2 * angleSign2)) - (angle * angleSign2) - self.secondBoneAngleDelta
			if not bone.fFixedAngle then
				if bone.fConstraints then
					local min = bone.fAnimAngle:GetValue(0) - self.secondBoneAngleDelta
					local max = min + bone.fMaxConstraint
					min = min + bone.fMinConstraint
					newAgle2 = LM.Clamp(newAgle2, min, max)
				end
			end
			if not MR_Utilities:IsEqual(newAgle2, bone.fAnimAngle:GetValue(moho.layerFrame), 0.0001) then
				bone.fAnimAngle:SetValue(moho.layerFrame, newAgle2)
				bone.fAnimAngle.value = bone.fAngle
				if self.bakeAdjacentFrames and not self.boneBakedA then
					self:BakeFrames(moho, secondBone, nil, true, false, false)
					self.boneBakedA = true
				end
			end

			moho.layer:UpdateCurFrame()
		
			local center = LM.Vector2:new_local()
			center:Set(0, 0)
			skel:UpdateBoneMatrix()
			secondBone.fMovedMatrix:Transform(center)
			local secondCursorDist = MR_Utilities:GetDistance(center, self.secondBoneTipPos)
			local secondDelta = (secondCursorDist / self.secondBoneDist)
			secondBone.fAnimScale:SetValue(moho.layerFrame, (secondBone.fTempScale * secondDelta) - self.secondBoneSizeDelta)
		end
		
		local angleSign = 1
		if (secondBone.fFlipH.value and not secondBone.fFlipV.value) or (not secondBone.fFlipH.value and secondBone.fFlipV.value) then
			angleSign = -1
		end
	end
	
	if self.isChainTargeted and self.isTargetMoved then
		local targetBone = skel:Bone(self.secondTarget)
		targetBone.fAnimPos:SetValue(moho.layerFrame, targetBone.fTempPos)
	end
	secondBone.fAnimScale.value = secondBone.fScale
	
	if mouseEvent.altKey then
		local angleSign = 1
		local angleSignS = 1
		if (secondBone.fFlipH.value and not secondBone.fFlipV.value) or (not secondBone.fFlipH.value and secondBone.fFlipV.value) then
			angleSignS = -1
		end
		local angleSignF = 1
		if (firstBone.fFlipH.value and not firstBone.fFlipV.value) or (not firstBone.fFlipH.value and firstBone.fFlipV.value) then
			angleSignF = -1
		end
		
		local angleDelta = 0
		if angleSignF == 1 and angleSignS == -1 then
			angleSign = -1
			angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + (secondBone.fAngle - secondBone.fTempAngle)
		elseif angleSignF == 1 and angleSignS == 1 then
			angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + (secondBone.fAngle - secondBone.fTempAngle)	
		elseif angleSignF == -1 and angleSignS == -1 then
			angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + ((secondBone.fAngle - secondBone.fTempAngle) * angleSignF)
		elseif angleSignF == -1 and angleSignS == 1 then
			angleSign = -1
			angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + ((secondBone.fAngle - secondBone.fTempAngle) * angleSignF)
		end
		
		while angleDelta > math.rad(180) do
			angleDelta = angleDelta - math.rad(360)
		end
		
		while angleDelta < math.rad(-180) do
			angleDelta = angleDelta + math.rad(360)
		end

		if not self.isChildBonesBaked and self.bakeAdjacentFrames then
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				if not self.isChildBonesBaked then
					if moho.layerFrame - self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
					end
				end
				if not self.isChildBonesBaked then
					if moho.layerFrame + self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
					end
				end
			end
			self.isChildBonesBaked = true
		end	
		for i, q in ipairs(self.childBones) do
			local bone = skel:Bone(q)
			local newAngle = bone.fTempAngle - (angleDelta * angleSign)
			bone.fAnimAngle:SetValue(moho.layerFrame, newAngle)
		end
	else
		for i, q in ipairs(self.childBones) do
			local firstBone = skel:Bone(q)
			if not MR_Utilities:IsEqual(firstBone.fTempAngle, firstBone.fAnimAngle:GetValue(moho.layerFrame), 0.0001) then
				firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fTempAngle)
			end	
		end
	end
	
	self:AdjustFollowAndLockBones(moho)
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
end

function MR_PoseTool:OnMouseMovedT(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end

	local bone = skel:Bone(self.secondBoneID)
	bone.fPos:Set(bone.fTempPos)

	local offset = mouseEvent.vec - mouseEvent.startVec
	
	local boneVec = LM.Vector2:new_local()
	local inverseM = LM.Matrix:new_local()
	
	local parent = nil
	boneVec:Set(0, 0)
	if (bone.fParent >= 0) then
		parent = skel:Bone(bone.fParent)
		parent.fMovedMatrix:Transform(boneVec)
	end
	boneVec = boneVec + offset
	if (parent) then
		inverseM:Set(parent.fMovedMatrix)
		inverseM:Invert()
		inverseM:Transform(boneVec)
	end
	if (mouseEvent.shiftKey) then
		if (math.abs(boneVec.x) > math.abs(boneVec.y)) then
			boneVec.y = 0
		else
			boneVec.x = 0
		end
	end
	local v = nil
	v = bone.fPos + boneVec
	if self.mode == 5 then
			bone.fAnimPos:SetValue(self.translationFrame, v)
	elseif self.mode == 0 then
		local bonePos = bone.fAnimPos:GetValue(moho.layerFrame)
		if not MR_Utilities:IsEqual(v.x, bonePos.x, 0.000001) or not MR_Utilities:IsEqual(v.y, bonePos.y, 0.000001) then
			if (self.multiTransform and self.keepSelection and not self.selBoneIsAncestorSelected) or not(self.multiTransform and self.keepSelection) then
				bone.fAnimPos:SetValue(moho.layerFrame, v)
				if self.bakeAdjacentFrames and not self.boneBakedP then
					self:BakeFrames(moho, bone, nil, false, true, false)
					self.boneBakedP = true
				end
			end
				
			if self.multiTransform and self.keepSelection then
				for i=1, #self.multiBoneTranslateList do
					if self.multiBoneTranslateList[i] ~= self.secondBoneID then
						local sBone = skel:Bone(self.multiBoneTranslateList[i])
						sBone.fPos:Set(sBone.fTempPos)

						local offset = mouseEvent.vec - mouseEvent.startVec
						
						local boneVec = LM.Vector2:new_local()
						local inverseM = LM.Matrix:new_local()
						
						local parent = nil
						boneVec:Set(0, 0)
						if (sBone.fParent >= 0) then
							parent = skel:Bone(sBone.fParent)
							parent.fMovedMatrix:Transform(boneVec)
						end
						boneVec = boneVec + offset
						if (parent) then
							inverseM:Set(parent.fMovedMatrix)
							inverseM:Invert()
							inverseM:Transform(boneVec)
						end
						if (mouseEvent.shiftKey) then
							if (math.abs(boneVec.x) > math.abs(boneVec.y)) then
								boneVec.y = 0
							else
								boneVec.x = 0
							end
						end
						local v = nil
						v = sBone.fPos + boneVec
						local bonePos = sBone.fAnimPos:GetValue(moho.layerFrame)
						if not MR_Utilities:IsEqual(v.x, bonePos.x, 0.000001) or not MR_Utilities:IsEqual(v.y, bonePos.y, 0.000001) then
							sBone.fAnimPos:SetValue(moho.layerFrame, v)
							if self.bakeAdjacentFrames and not self.multiBoneTranslateBakedList[i] then
								if moho.layerFrame - self.interval > 0 then
									sBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.multiBoneTranslateSBValuesPList[i])
								end
								if moho.layerFrame + self.interval > 0 then
									sBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.multiBoneTranslateSBValuesNList[i])
								end
								self.multiBoneTranslateBakedList[i] = true
							end
						end
					end
				end
			end
		end	
	end	
	if self.mode == 0 then
		if (self.ignoreZeroScaledBones and MR_Utilities:Round(bone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
			if mouseEvent.altKey and bone.fLength > 0 then
				if (self.selBones == 1 and self.multiTransform and self.keepSelection) or not self.multiTransform then
					local vectorMousePos = mouseEvent.vec + self.clickOffset
					local secondCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.secondBoneTipPos)
					local secondDelta = (secondCursorDist / self.secondBoneDist)
					local newScale = (bone.fTempScale * secondDelta) - self.secondBoneSizeDelta
					if not MR_Utilities:IsEqual(newScale, bone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
						bone.fAnimScale:SetValue(moho.layerFrame, newScale)
						if self.bakeAdjacentFrames and not self.boneBakedS then
							self:BakeFrames(moho, bone, nil, false, false, true)
							self.boneBakedS = true
						end
					end
					moho.layer:UpdateCurFrame()

					local center = LM.Vector2:new_local()

					center:Set(0, 0)
					skel:UpdateBoneMatrix(self.secondBoneID)
					bone.fMovedMatrix:Transform(center)
					
					local angle = self.startAngle2
					local v1 = self.lastVec2 - self.secondBoneTipPos
					local v2 = center - self.secondBoneTipPos
					v2:Rotate(-math.atan2(v1.y, v1.x))
					angle = angle + math.atan2(v2.y, v2.x)
					self.startAngle2 = angle
					self.lastVec2:Set(center)

					local angleSign = 1.0
					if (not bone.fFixedAngle) then
						angleSign = bone:ParentalFlipFactor()
					end
					
					local newAgle = (bone.fTempAngle + (angle * angleSign)) - self.secondBoneAngleDelta
					if not bone.fFixedAngle then
						if bone.fConstraints then
							local min = bone.fAnimAngle:GetValue(0) - self.secondBoneAngleDelta
							local max = min + bone.fMaxConstraint
							min = min + bone.fMinConstraint
							newAgle = LM.Clamp(newAgle, min, max)
						end
					end
					if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
						bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
						bone.fAnimAngle.value = bone.fAngle
					end
					if self.bakeAdjacentFrames and not self.boneBakedA then
						self:BakeFrames(moho, bone, nil, true, false, false)
						self.boneBakedA = true
						if not self.isChildBonesBaked then
							for i, q in ipairs(self.childBones) do
								local bone = skel:Bone(q)
								if moho.layerFrame - self.interval > 0 then
									bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
									bone.fAnimAngle.value = bone.fAngle
								end
								if moho.layerFrame + self.interval > 0 then
									bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
									bone.fAnimAngle.value = bone.fAngle
								end
							end
							self.isChildBonesBaked = true
						end
						
					end

					local angleSign = 1
					if (bone.fFlipH.value and not bone.fFlipV.value) or (not bone.fFlipH.value and bone.fFlipV.value) then
						angleSign = -1
					end
					
					moho.layer:UpdateCurFrame()
					local angleDelta = bone.fAngle - bone.fTempAngle
					
					for i, q in ipairs(self.childBones) do
						local bone = skel:Bone(q)
						bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle - (angleDelta * angleSign))
						bone.fAnimAngle.value = bone.fAngle
					end
				end
			end	
		else
			if not MR_Utilities:IsEqual(bone.fTempScale - self.secondBoneSizeDelta, bone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
				bone.fAnimScale:SetValue(moho.layerFrame, bone.fTempScale)
			end
			local newAngle = bone.fTempAngle - self.secondBoneAngleDelta
			if not MR_Utilities:IsEqual(newAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
				bone.fAnimAngle:SetValue(moho.layerFrame, newAngle)
			end	
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				if not MR_Utilities:IsEqual(bone.fTempAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle)
				end	
			end
		end
	end
	self:AdjustFollowAndLockBones(moho)
	
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
end

function MR_PoseTool:OnMouseMovedR(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end

	local secondBone = skel:Bone(self.secondBoneID)

	local bone = secondBone
	local center = LM.Vector2:new_local()
	center:Set(0, 0)
	skel:UpdateBoneMatrix()
	bone.fMovedMatrix:Transform(center)
	
	local mousePos = mouseEvent.vec
	local angle = self.startAngle
	local v1 = self.lastVec - center
	local v2 = mousePos - center
	v2:Rotate(-math.atan2(v1.y, v1.x))
	angle = angle + math.atan2(v2.y, v2.x)
	self.startAngle = angle
	self.lastVec:Set(mousePos)
	local angleSign = 1.0
	if (not bone.fFixedAngle) then
		angleSign = bone:ParentalFlipFactor()
	end

	local newAgle = (bone.fTempAngle + (angle * angleSign)) - self.secondBoneAngleDelta
	
	if not bone.fFixedAngle then
		if bone.fConstraints then
			local min = bone.fAnimAngle:GetValue(0) - self.secondBoneAngleDelta
			local max = min + bone.fMaxConstraint
			min = min + bone.fMinConstraint
			newAgle = LM.Clamp(newAgle, min, max)
		end
	end
	
	if (mouseEvent.shiftKey) then
		newAgle = newAgle / (math.pi / 4)
		newAgle = (math.pi / 4) * LM.Round(newAgle)
	end
	
	if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
		bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
		if self.bakeAdjacentFrames and not self.boneBakedA then
			self:BakeFrames(moho, secondBone, nil, true, false, false)
			self.boneBakedA = true
		end
	end	

	local angleSign = 1
	if (bone.fFlipH.value and not bone.fFlipV.value) or (not bone.fFlipH.value and bone.fFlipV.value) then
		angleSign = -1
	end
	
	if self.multiTransform and self.keepSelection then
		for i=1, #self.selectedBonesList do
			if self.selectedBonesList[i] ~= self.secondBoneID then
				local sBone = skel:Bone(self.selectedBonesList[i])
				local center = LM.Vector2:new_local()
				center:Set(0, 0)
				
				sBone.fMovedMatrix:Transform(center)

				local selectedAngleSign = 1.0
				if (not sBone.fFixedAngle) then
					selectedAngleSign = sBone:ParentalFlipFactor()
				end

				local newSelAgle = (sBone.fTempAngle + (angle * selectedAngleSign))

				if not MR_Utilities:IsEqual(newSelAgle, sBone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					sBone.fAnimAngle:SetValue(moho.layerFrame, newSelAgle)
					if self.bakeAdjacentFrames and not self.multiBoneAngleBakedList[i] then
						if moho.layerFrame - self.interval > 0 then
							sBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.multiBoneAngleSBValuesPList[i])
						end
						if moho.layerFrame + self.interval > 0 then
							sBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.multiBoneAngleSBValuesNList[i])
						end
						self.multiBoneAngleBakedList[i] = true
					end
				end
			end
		end
	end
	
	if self.isChainTargeted then
		local targetBone = skel:Bone(self.secondTarget)
		local newTargetPos = targetBone.fTempPos - (mouseEvent.startVec - mouseEvent.vec)
		targetBone.fAnimPos:SetValue(moho.layerFrame, newTargetPos)
		self.isTargetMoved = true
		if self.bakeAdjacentFrames then
			if not self.isTargetBonePosPBaked then
				if moho.layerFrame - self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.targetBonePosP)
				end
				self.isTargetBonePosPBaked = true
			end
			
			if not self.isTargetBonePosNBaked then
				if moho.layerFrame + self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.targetBonePosN)
				end
				self.isTargetBonePosNBaked = true
			end
		end	
	end
	if not (self.multiTransform and self.keepSelection and self.selBones > 1) then
		if mouseEvent.altKey then
			moho.layer:UpdateCurFrame()
			local angleDelta = secondBone.fAngle - secondBone.fTempAngle
			
			if self.bakeAdjacentFrames and not self.isChildBonesBaked then
				for i, q in ipairs(self.childBones) do
					local childBone = skel:Bone(q)
					if moho.layerFrame - self.interval > 0 then
						childBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
					end
					if moho.layerFrame + self.interval > 0 then
						childBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
					end
				end	
				self.isChildBonesBaked = true
			end
			
			for i, q in ipairs(self.childBones) do
				local childBone = skel:Bone(q)
				childBone.fAnimAngle:SetValue(moho.layerFrame, childBone.fTempAngle - (angleDelta * angleSign))
			end
		else
			for i, q in ipairs(self.childBones) do
				local childBone = skel:Bone(q)
				if not MR_Utilities:IsEqual(childBone.fTempAngle, childBone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					childBone.fAnimAngle:SetValue(moho.layerFrame, childBone.fTempAngle)
				end	
			end
		end
	end

	self:AdjustFollowAndLockBones(moho)
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
end

function MR_PoseTool:OnMouseMovedS(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	local secondBone = skel:Bone(self.secondBoneID)
	if secondBone:IsZeroLength() then
		local scaleFactor = (mouseEvent.pt.x - mouseEvent.startPt.x) / 100
		if (scaleFactor < 0) then
			scaleFactor = 1 / (-scaleFactor + 1)
		else
			scaleFactor = scaleFactor + 1
		end
		local newScale = (secondBone.fTempScale * scaleFactor) - self.secondBoneSizeDelta
		
		if not MR_Utilities:IsEqual(newScale, secondBone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
			secondBone.fAnimScale:SetValue(moho.layerFrame, newScale)
			if self.bakeAdjacentFrames and not self.boneBakedS then
				self:BakeFrames(moho, secondBone, nil, false, false, true)
				self.boneBakedS = true
			end
		end
		
		if self.multiTransform and self.keepSelection then
			for i=1, #self.selectedBonesList do
				local sBone = skel:Bone(self.selectedBonesList[i])
				local newSelectedScale = (sBone.fTempScale * scaleFactor) - self.multiBoneScaleDeltaList[i]
				if not MR_Utilities:IsEqual(newSelectedScale, sBone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
					sBone.fAnimScale:SetValue(moho.layerFrame, newSelectedScale)
					if self.bakeAdjacentFrames and not self.multiBoneScaleBakedList[i] then
						if moho.layerFrame - self.interval > 0 then
							sBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.multiBoneScaleSBValuesPList[i])
						end
						if moho.layerFrame + self.interval > 0 then
							sBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.multiBoneScaleSBValuesNList[i])
						end
						self.multiBoneScaleBakedList[i] = true
					end
				end
			end
		end
	else
		local vectorMousePos = mouseEvent.vec + self.clickOffset
		local secondCursorDist = MR_Utilities:GetDistance(vectorMousePos, self.secondBonePos)
		local secondDelta = (secondCursorDist / self.secondBoneDist)
		local newScale = (secondBone.fTempScale * secondDelta) - self.secondBoneSizeDelta
		if not MR_Utilities:IsEqual(newScale, secondBone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
			secondBone.fAnimScale:SetValue(moho.layerFrame, newScale)
			if self.bakeAdjacentFrames and not self.boneBakedS then
				self:BakeFrames(moho, secondBone, nil, false, false, true)
				self.boneBakedS = true
			end
		end
		
		if self.multiTransform and self.keepSelection then
			for i=1, #self.selectedBonesList do
				local sBone = skel:Bone(self.selectedBonesList[i])
				local newSelectedScale = (sBone.fTempScale * secondDelta) - self.multiBoneScaleDeltaList[i]
				if not MR_Utilities:IsEqual(newSelectedScale, sBone.fAnimScale:GetValue(moho.layerFrame), 0.000001) then
					sBone.fAnimScale:SetValue(moho.layerFrame, newSelectedScale)
					if self.bakeAdjacentFrames and not self.multiBoneScaleBakedList[i] then
						if moho.layerFrame - self.interval > 0 then
							sBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.multiBoneScaleSBValuesPList[i])
						end
						if moho.layerFrame + self.interval > 0 then
							sBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.multiBoneScaleSBValuesNList[i])
						end
						self.multiBoneScaleBakedList[i] = true
					end
				end
			end
		end
		if self.multiTransform and self.keepSelection and self.selBones == 1 or not (self.multiTransform and self.keepSelection) then
			if not mouseEvent.shiftKey then
				local bone = secondBone
				local center = LM.Vector2:new_local()
				center:Set(0, 0)
				skel:UpdateBoneMatrix()
				bone.fMovedMatrix:Transform(center)
				
				local mousePos = mouseEvent.vec
				
				local angle = self.startAngle
				local v1 = self.lastVec - center
				local v2 = mousePos - center
				v2:Rotate(-math.atan2(v1.y, v1.x))
				angle = angle + math.atan2(v2.y, v2.x)
				self.startAngle = angle
				self.lastVec:Set(mousePos)
				local angleSign = 1.0
				if (not bone.fFixedAngle) then
					angleSign = bone:ParentalFlipFactor()
				end

				local newAgle = (bone.fTempAngle + (angle * angleSign)) - self.secondBoneAngleDelta
				
				if not bone.fFixedAngle then
					if bone.fConstraints then
						local min = bone.fAnimAngle:GetValue(0) - self.secondBoneAngleDelta
						local max = min + bone.fMaxConstraint
						min = min + bone.fMinConstraint
						newAgle = LM.Clamp(newAgle, min, max)
					end
				end
				if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
					if self.bakeAdjacentFrames and not self.boneBakedA then
						self:BakeFrames(moho, secondBone, nil, true, false, false)
						self.boneBakedA = true
					end
				end	
			else
				local bone = secondBone
				local newAngle = bone.fTempAngle - self.secondBoneAngleDelta
				if not MR_Utilities:IsEqual(newAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					bone.fAnimAngle:SetValue(moho.layerFrame, newAngle)
					if self.bakeAdjacentFrames and not self.boneBakedA then
						self:BakeFrames(moho, secondBone, nil, true, false, false)
						self.boneBakedA = true
					end
				end	
			end
		end
	end
	
	local angleSign = 1
	if (secondBone.fFlipH.value and not secondBone.fFlipV.value) or (not secondBone.fFlipH.value and secondBone.fFlipV.value) then
		angleSign = -1
	end
	
	if self.isChainTargeted then
		local targetBone = skel:Bone(self.secondTarget)
		local newTargetPos = targetBone.fTempPos - (mouseEvent.startVec - mouseEvent.vec)
		targetBone.fAnimPos:SetValue(moho.layerFrame, newTargetPos)
		self.isTargetMoved = true
		if self.bakeAdjacentFrames then
			if not self.isTargetBonePosPBaked then
				if moho.layerFrame - self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.targetBonePosP)
				end
				self.isTargetBonePosPBaked = true
			end
			
			if not self.isTargetBonePosNBaked then
				if moho.layerFrame + self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.targetBonePosN)
				end
				self.isTargetBonePosNBaked = true
			end
		end	
	end
	if not (self.multiTransform and self.keepSelection and self.selBones > 1) then
		if mouseEvent.altKey then
			moho.layer:UpdateCurFrame()
			if self.bakeAdjacentFrames and not self.isChildBonesBaked then
				for i, q in ipairs(self.childBones) do
					local bone = skel:Bone(q)
					if moho.layerFrame - self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
					end
					if moho.layerFrame + self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
					end
				end
				self.isChildBonesBaked = true
			end

			local angleDelta = secondBone.fAngle - secondBone.fTempAngle
			
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle - (angleDelta * angleSign))
			end
		else
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				if not MR_Utilities:IsEqual(bone.fTempAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
					bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle)
				end	
			end
		end
	end
	
	self:AdjustFollowAndLockBones(moho)
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
end

function MR_PoseTool:OnMouseMovedM(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end

	local riggingFrame = 0
	local bone = skel:Bone(self.selID)
	local secondBone = skel:Bone(self.selID)
	
	if self.bakeAdjacentFrames and not self.boneBakedA then
		self:BakeFrames(moho, secondBone, nil, true, false, false)
		self.boneBakedA = true
	end
	skel:UpdateBoneMatrix(self.selID)

	local tipVec = LM.Vector2:new_local()

	tipVec:Set(bone.fLength, 0)
	bone.fMovedMatrix:Transform(tipVec)
	tipVec = tipVec + (mouseEvent.vec - self.lastVec)
	
	local startBone = skel:Bone(self.parentBones[#self.parentBones])
	local center = LM.Vector2:new_local()
	center:Set(0, 0)
	skel:UpdateBoneMatrix()
	startBone.fMovedMatrix:Transform(center)

	local mousePos = mouseEvent.vec
	
	local angle = self.startAngle
	local v1 = self.lastVec - center
	local v2 = mousePos - center
	v2:Rotate(-math.atan2(v1.y, v1.x))
	angle = angle + math.atan2(v2.y, v2.x)
	self.startAngle = angle
	self.lastVec:Set(mousePos)
	local angleSign = 1.0
	if (not startBone.fFixedAngle) then
		angleSign = startBone:ParentalFlipFactor()
	end

	local newAgle = (startBone.fTempAngle + (angle * angleSign))
	if mouseEvent.shiftKey then
		if self.bakeAdjacentFrames and not self.boneBakedS then
			self:BakeFrames(moho, secondBone, nil, false, false, true)
			for i, q in ipairs(self.parentBones) do
				local bone = skel:Bone(q)
				if moho.layerFrame - self.interval > 0 then
					bone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.parentBonesScaleP[i])
				end
				if moho.layerFrame + self.interval > 0 then
					bone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.parentBonesScaleN[i])
				end
			end	
			self.boneBakedS = true
		end
	
		if self.bakeAdjacentFrames and not self.boneBakedS then
			self:BakeFrames(moho, secondBone, nil, false, false, true)
			self.boneBakedS = true
		end
		
		local newStartBoneDist = MR_Utilities:GetDistance(self.startBonePos, mouseEvent.vec)
		local startBoneDistDelta = newStartBoneDist / self.startBoneDist
		bone.fAnimScale:SetValue(moho.layerFrame, (bone.fTempScale * startBoneDistDelta) - self.secondBoneSecondDelta)
		
		if not startBone.fFixedAngle then
			if startBone.fConstraints then
				local min = startBone.fAnimAngle:GetValue(0) - self.startBoneAngleDelta
				local max = min + startBone.fMaxConstraint
				min = min + startBone.fMinConstraint
				newAgle = LM.Clamp(newAgle, min, max)
			end
		end

		for i, q in ipairs(self.parentBones) do
			local parentBone = skel:Bone(q)

			parentBone.fAnimScale:SetValue(moho.layerFrame, (parentBone.fTempScale * startBoneDistDelta) - self.parentBonesScaleDelta[i])
			if not MR_Utilities:IsEqual(parentBone.fTempAngle, parentBone.fAnimAngle:GetValue(moho.layerFrame), 0.0000001) then
				parentBone.fAnimAngle:SetValue(moho.layerFrame, parentBone.fTempAngle)
			end	
		end	
		if not MR_Utilities:IsEqual(bone.fTempAngle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.0000001) then
			bone.fAnimAngle:SetValue(moho.layerFrame, bone.fTempAngle)
		end	
		startBone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
	else
		skel:IKAngleSolver(self.selID, tipVec)
		local boneID = 1
		bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAngle - (self.boneStartActualAngles[boneID] - self.boneStartAngles[boneID]))
		bone.fAnimAngle.value = bone.fAngle
		boneID = boneID + 1
		while bone.fParent >= 0 do
			if (self:CountBoneChildren(skel, bone.fParent, true) > 1) then
				break
			end
			local parentBone = skel:Bone(bone.fParent)
			if self.mohoVersion >= 14 then
				if (parentBone.fAngleControlParent >= 0 or
					parentBone.fPosControlParent >= 0 or
					parentBone.fScaleControlParent >= 0 or
					parentBone:AreDynamicsActive() or
					parentBone.fFixedAngle or
					parentBone.fIgnoredByIK) then
					break
				end
			else
				if (parentBone.fAngleControlParent >= 0 or
					parentBone.fPosControlParent >= 0 or
					parentBone.fScaleControlParent >= 0 or
					parentBone.fBoneDynamics.value or
					parentBone.fFixedAngle or
					parentBone.fIgnoredByIK) then
					break
				end
			end	

			bone = skel:Bone(bone.fParent)
			bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAngle - (self.boneStartActualAngles[boneID] - self.boneStartAngles[boneID]))
			bone.fAnimAngle.value = bone.fAngle
			boneID = boneID + 1
		end
	end

	if #self.parentBones == 1 then
		local firstBone = skel:Bone(self.parentBones[1])
		if mouseEvent.altKey then
			moho.layer:UpdateCurFrame()
			local angleSign = 1
			local angleSignS = 1
			if (secondBone.fFlipH.value and not secondBone.fFlipV.value) or (not secondBone.fFlipH.value and secondBone.fFlipV.value) then
				angleSignS = -1
			end
			local angleSignF = 1
			if (firstBone.fFlipH.value and not firstBone.fFlipV.value) or (not firstBone.fFlipH.value and firstBone.fFlipV.value) then
				angleSignF = -1
			end
			
			local angleDelta = 0
			if angleSignF == 1 and angleSignS == -1 then
				angleSign = -1
				angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + (secondBone.fAngle - secondBone.fTempAngle)
			elseif angleSignF == 1 and angleSignS == 1 then
				angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + (secondBone.fAngle - secondBone.fTempAngle)	
			elseif angleSignF == -1 and angleSignS == -1 then
				angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + ((secondBone.fAngle - secondBone.fTempAngle) * angleSignF)
			elseif angleSignF == -1 and angleSignS == 1 then
				angleSign = -1
				angleDelta = (firstBone.fAngle - firstBone.fTempAngle) + ((secondBone.fAngle - secondBone.fTempAngle) * angleSignF)
			end
		
			moho.layer:UpdateCurFrame()

			if not self.isChildBonesBaked and self.bakeAdjacentFrames then
				for i, q in ipairs(self.childBones) do
					local bone = skel:Bone(q)
					if not self.isChildBonesBaked then
						if moho.layerFrame - self.interval > 0 then
							bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.childBonesAngelP[i])
						end
					end
					if not self.isChildBonesBaked then
						if moho.layerFrame + self.interval > 0 then
							bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.childBonesAngelN[i])
						end
					end
				end
				self.isChildBonesBaked = true
			end	
			for i, q in ipairs(self.childBones) do
				local bone = skel:Bone(q)
				local newAngle = bone.fTempAngle - (angleDelta * angleSign)
				bone.fAnimAngle:SetValue(moho.layerFrame, newAngle)
			end
		else
			for i, q in ipairs(self.childBones) do
				local firstBone = skel:Bone(q)
				if not MR_Utilities:IsEqual(firstBone.fTempAngle, firstBone.fAnimAngle:GetValue(moho.layerFrame), 0.0000001) then
					firstBone.fAnimAngle:SetValue(moho.layerFrame, firstBone.fTempAngle)
				end	
			end
		end
	end
	
	if self.bakeAdjacentFrames and not self.isParentBonesBaked then
		for i, q in ipairs(self.parentBones) do
			local bone = skel:Bone(q)
			if moho.layerFrame - self.interval > 0 then
				bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.parentBonesAngleP[i])
			end
			if moho.layerFrame + self.interval > 0 then
				bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.parentBonesAngleN[i])
			end
		end	
		self.isParentBonesBaked = true
	end
	
	if self.isChainTargeted then
		local targetBone = skel:Bone(self.secondTarget)
		local newTargetPos = targetBone.fTempPos - (mouseEvent.startVec - mouseEvent.vec)
		targetBone.fAnimPos:SetValue(moho.layerFrame, newTargetPos)
		self.isTargetMoved = true
		if self.bakeAdjacentFrames then
			if not self.isTargetBonePosPBaked then
				if moho.layerFrame - self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.targetBonePosP)
				end
				self.isTargetBonePosPBaked = true
			end
			
			if not self.isTargetBonePosNBaked then
				if moho.layerFrame + self.interval > 0 then
					targetBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.targetBonePosN)
				end
				self.isTargetBonePosNBaked = true
			end
		end	
	end
	
	self:AdjustFollowAndLockBones(moho)
	skel:UpdateBoneMatrix()
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
	self.lastVec:Set(mouseEvent.vec)
end	

function MR_PoseTool:OnMouseUp(moho, mouseEvent)
	self.ignoreBonesList = {}
	moho:UpdateBonePointSelection()
	local frame = moho.frame
	if self.twosMode then
		if self.blockOnEvenFrames and frame % 2 == 0 or self.blockOnOddFrames and not (frame % 2 == 0) then
			moho:UpdateSelectedChannels()
			moho:UpdateUI()
			return
		end
	end
	
	self.dragging = false
	local skel = moho:Skeleton()
	if skel == nil or frame == 0 then
		moho:UpdateSelectedChannels()
		moho:UpdateUI()
		return
	end
	
	if self.showIcons or self.showIcons2 then
		moho:UpdateSelectedChannels()
		moho:UpdateUI()
		return
	end

	if self.lockHandlesSelection and self.isLockHandleMouseMoved then
		moho:UpdateSelectedChannels()
		moho:UpdateUI()
		return
	end
	
	if self.setKeyframe then
		moho:UpdateSelectedChannels()
		moho:UpdateUI()
		return
	end
	
	self.isLockHandleMouseMoved = false

	if self.multiSelectionUnselectedMovement then
		self.mousePickedID = -1
	end
	self.multiSelectionUnselectedMovement = false

	if not self.isMouseDragging then
		if not self.isMouseMoved or (self.lockHandlesSelection and not (self.multiTransform and self.keepSelection)) then
			if mouseEvent.shiftKey or mouseEvent.altKey then
				skel:SelectNone()
				for i, id in ipairs(self.selectedBonesList) do
					local sBone = skel:Bone(id)
					if sBone then
						sBone.fSelected = true
					end
				end
			end
			
			local bonesVisibilityList = {}
			for i=0, skel:CountBones()-1 do
				local bone = skel:Bone(i)
				if not bone.fSelected then
					bonesVisibilityList[i+1] = bone.fHidden
					bone.fHidden = true
				end	
			end
			
			local pickWidth = self.pickWidth
			
			local id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
			
			for i=0, skel:CountBones()-1 do
				local bone = skel:Bone(i)
				if not bone.fSelected then
					bone.fHidden = bonesVisibilityList[i+1]
				end
			end
			
			if id == -1 then
				id = mouseEvent.view:PickBone(mouseEvent.pt, mouseEvent.vec, moho.layer, true, pickWidth * self.handlesDistYMultiplier * self.handlesDistance)
			end
			
			if not mouseEvent.shiftKey and not mouseEvent.altKey then
				skel:SelectNone()
			end	
			if id ~= -1 then
				skel:Bone(id).fSelected = not mouseEvent.altKey
			end
		
			local firstBone = skel:Bone(self.firstBoneID)
			if self.isBoneHaveAngleKeyList[self.firstBoneID] == false then
				firstBone.fAnimAngle:DeleteKey(moho.layerFrame)
			end

			if self.isBoneHaveScaleKeyList[self.firstBoneID] == false then
				firstBone.fAnimScale:DeleteKey(moho.layerFrame)
			end
			
			local secondBone = skel:Bone(self.secondBoneID)
			if self.isBoneHaveAngleKeyList[self.secondBoneID] == false then
				secondBone.fAnimAngle:DeleteKey(moho.layerFrame)
			end

			if self.isBoneHaveScaleKeyList[self.secondBoneID] == false then
				secondBone.fAnimScale:DeleteKey(moho.layerFrame)
			end
			if self.holdToReset then
				local upTime = os.time()
				if upTime - self.clickTime >= 2 then
					if self.selBonesList[self.secondBoneID] then
						local bone = skel:Bone(self.secondBoneID)
						if self.mode == 0 then
							if mouseEvent.altKey then
								bone.fTempScale = bone.fScale
								
								self.childBones = {}
								self.childBonesAngelP = {}
								self.childBonesAngelN = {}
								
								for i=0, skel:CountBones()-1 do
									local childBone = skel:Bone(i)
									if  childBone.fParent == self.secondBoneID and not childBone.fFixedAngle and not childBone.fIgnoredByIK then
										local angle = childBone.fAnimAngle:GetValue(moho.layerFrame)
										childBone.fTempAngle = angle
										table.insert(self.childBones, i)
										
										if moho.layerFrame - self.interval > 0 then
											table.insert(self.childBonesAngelP, childBone.fAnimAngle:GetValue(moho.layerFrame - self.interval))
										else
											table.insert(self.childBonesAngelP, 0)
										end
										
										if moho.layerFrame + self.interval > 0 then
											table.insert(self.childBonesAngelN, childBone.fAnimAngle:GetValue(moho.layerFrame + self.interval))
										else
											table.insert(self.childBonesAngelN, 0)
										end
									end
								end
								
								local secondBoneSizeDelta = bone.fScale - bone.fAnimScale:GetValue(moho.layerFrame)
								local secondBoneAngleDelta = bone.fAngle - bone.fAnimAngle:GetValue(moho.layerFrame)
								
								local secondTipVec = LM.Vector2:new_local()
								secondTipVec:Set(bone.fLength, 0)
								bone.fMovedMatrix:Transform(secondTipVec)
								
								local secondVec = LM.Vector2:new_local()
								secondVec:Set(0, 0)
								bone.fMovedMatrix:Transform(secondVec)
								
								local boneDist = MR_Utilities:GetDistance(secondVec, secondTipVec)
								
								bone.fAnimPos:SetValue(moho.layerFrame, bone.fAnimPos:GetValue(0))
								skel:UpdateBoneMatrix()
								moho.layer:UpdateCurFrame()
								secondVec:Set(0, 0)
								bone.fMovedMatrix:Transform(secondVec)
								
								local NewboneDist = MR_Utilities:GetDistance(secondVec, secondTipVec)
								local secondDelta = (NewboneDist / boneDist)
								local newScale = (bone.fTempScale * secondDelta) - secondBoneSizeDelta
								
								bone.fAnimScale:SetValue(moho.layerFrame, newScale)
								
								local isIgnoredByIK = bone.fIgnoredByIK
								bone.fIgnoredByIK = false
								moho.layer:UpdateCurFrame()
								
								skel:IKAngleSolver(self.secondBoneID, secondTipVec, 1, true, true)

								bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAngle - secondBoneAngleDelta)
								bone.fAnimAngle.value = bone.fAngle
								
								local angleSign = 1
								if (bone.fFlipH.value and not bone.fFlipV.value) or (not bone.fFlipH.value and bone.fFlipV.value) then
									angleSign = -1
								end

								local angleDelta = bone.fAngle - bone.fTempAngle
								
								for i, q in ipairs(self.childBones) do
									local childBone = skel:Bone(q)
									childBone.fAnimAngle:SetValue(moho.layerFrame, childBone.fTempAngle - (angleDelta * angleSign))
								end
								
								bone.fIgnoredByIK = isIgnoredByIK
							else	
								for i, b in ipairs(self.selectedBonesList) do
									local bone = skel:Bone(b)
									if bone then
										bone.fAnimPos:SetValue(moho.layerFrame, bone.fAnimPos:GetValue(0))
									end	
								end
							end

							skel:SelectNone()
							for i, boneID in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(boneID)
								bone.fSelected = true
							end
							
							moho.layer:UpdateCurFrame()
							moho:NewKeyframe(CHANNEL_BONE_T)
							moho:UpdateUI()
							return
						elseif self.mode == 1 then
							for i, b in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(b)
								if bone then
									bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAnimAngle:GetValue(0))
								end	
							end
							
							skel:SelectNone()
							for i, boneID in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(boneID)
								bone.fSelected = true
							end

							moho.layer:UpdateCurFrame()
							moho:NewKeyframe(CHANNEL_BONE)
							moho:UpdateUI()
							return
						elseif self.mode == 2 then
							for i, b in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(b)
								if bone then
									bone.fAnimScale:SetValue(moho.layerFrame, bone.fAnimScale:GetValue(0))
								end	
							end
							
							skel:SelectNone()
							for i, boneID in ipairs(self.selectedBonesList) do
								local bone = skel:Bone(boneID)
								bone.fSelected = true
							end

							moho.layer:UpdateCurFrame()
							moho:NewKeyframe(CHANNEL_BONE_S)
							moho:UpdateUI()
							return
						end
					else
						moho.layer:UpdateCurFrame()
						moho:NewKeyframe(CHANNEL_BONE_S)
						moho:UpdateUI()
						return
					end
				end
			end
			
			moho:UpdateSelectedChannels()
			moho:UpdateUI()
			return
		end
	end
	self.isMouseMoved = false
	self.lockHandlesSelection = false
	if self.isMouseDragging then
		local v = LM.Vector2:new_local()
		local screenPt = LM.Point:new_local()
		local m = LM.Matrix:new_local()
		
		self.selRect:Normalize()
		moho.layer:GetFullTransform(moho.frame, m, moho.document)
		for i = 0, skel:CountBones() - 1 do
			local bone = skel:Bone(i)
			local boneMatrix = bone.fMovedMatrix
			for j = 0, 10 do
				v:Set(bone.fLength * j / 10.0, 0)
				boneMatrix:Transform(v)
				m:Transform(v)
				mouseEvent.view:Graphics():WorldToScreen(v, screenPt)
				if (self.selRect:Contains(screenPt)) then
					if (mouseEvent.altKey) then
						bone.fSelected = false
					else
						bone.fSelected = true
					end
					break
				end
			end
		end
		self.isMouseDragging = false
		if self.bonesReset then
			skel:SelectNone()
			for i, boneID in ipairs(self.selectedBonesList) do
				local bone = skel:Bone(boneID)
				bone.fSelected = true
			end
		end
		self.bonesReset = false
		moho:UpdateSelectedChannels()
		return
	end

	if self.isActive == false then
		if self.bonesReset then
			skel:SelectNone()
			for i, boneID in ipairs(self.selectedBonesList) do
				local bone = skel:Bone(boneID)
				bone.fSelected = true
			end
		end
		moho:UpdateSelectedChannels()
		self.bonesReset = false
		return
	end
	
	local bone
	if self.firstBoneID > -1 then
		bone = skel:Bone(self.firstBoneID)
	end

	local secondBoneID = skel:Bone(self.secondBoneID)
	
	if self.firstBoneParentID > -1 then
		local firstBoneParent = skel:Bone(self.firstBoneParentID)
		if firstBoneParent then
			firstBoneParent.fIgnoredByIK = self.firstBoneParentIBIK
		end	
	end
	
	self.firstBoneID = -1
	self.firstBoneParentID = -1
	self.firstBoneParentIBIK = -1
	if self.keepSelection and self.selBones > 0 then
		skel:SelectNone()
		for i, boneID in ipairs(self.selectedBonesList) do
			local bone = skel:Bone(boneID)
			bone.fSelected = true
		end
	end
	
	if MOHO.MohoGlobals.AutoFreezeKeys then
		for i=0, skel:CountBones()-1 do
			local bone = skel:Bone(i)
			if not (bone.fHidden and not bone.fShy) then
				local frame = moho.layerFrame
				bone.fAnimAngle:SetValue(frame, bone.fAnimAngle:GetValue(frame))
				bone.fAnimPos:SetValue(frame, bone.fAnimPos:GetValue(frame))
				bone.fAnimScale:SetValue(frame, bone.fAnimScale:GetValue(frame))
			end
		end
	end
	
	moho.layer:UpdateCurFrame()
	mouseEvent.view:DrawMe()
	moho:UpdateSelectedChannels()
	moho:UpdateUI()
end

function MR_PoseTool:DrawMe(moho, view)
	local skel = moho:Skeleton()
	if (skel == nil) or moho.frame == 0 then
		return
	end
	
	local markerR = self.markerR
	
	if self.additionHandles then
		markerR = self.markerR2
	end
	local selBones = moho:CountSelectedBones()
	local v = LM.Vector2:new_local()
	local g = view:Graphics()
	local layerMatrix = LM.Matrix:new_local()
	local vc1 = LM.ColorVector:new_local()
	local vc2 = LM.ColorVector:new_local()
	local interp = MOHO.InterpSetting:new_local()
	local center = LM.Vector2:new_local()
	local tip = LM.Vector2:new_local()
	local offset = LM.Vector2:new_local()
	local boneCenterPos = LM.Vector2:new_local()
	local boneHandlePos = LM.Vector2:new_local()
	local angle = 0
	local newAngle = 0
	local offsetAngle = 0
	local alignHandlesAdaptation = false
	local handlesZoomAdaptationVal = 1
	local handlesAdaptation = false

	if self.isMouseDragging then
		local g = view:Graphics()
		g:SelectionRect(self.selRect)
		g:Pop()
		return
	end

	vc1:Set(MOHO.MohoGlobals.SelCol)
	vc2:Set(MOHO.MohoGlobals.BackCol)
	
	local whiteColor = LM.rgb_color:new_local()
	whiteColor.r = 255
	whiteColor.g = 255
	whiteColor.b = 255
	whiteColor.a = 255 * self.handleFillOpacity
	
	vc1 = (vc1 + vc2) / 2
	local fillCol = vc1:AsColorStruct()
	fillCol.a = 255 * self.handleFillOpacity
	
	local colorHighlightBone = LM.rgb_color:new_local()
	local colorTranslateStroke = LM.rgb_color:new_local()
	local colorTranslateFill = LM.rgb_color:new_local()
	local colorTranslateFillHL = LM.rgb_color:new_local()
	local colorScaleStroke = LM.rgb_color:new_local()
	local colorScaleFill = LM.rgb_color:new_local()
	local colorScaleFillHL = LM.rgb_color:new_local()
	local colorMoveJointStroke = LM.rgb_color:new_local()
	local colorMoveJointFill = LM.rgb_color:new_local()
	local colorMoveJointFillHL = LM.rgb_color:new_local()
	local colorManipulateStroke = LM.rgb_color:new_local()
	local colorManipulateFill = LM.rgb_color:new_local()
	local colorManipulateFillHL = LM.rgb_color:new_local()
	
	if self.useCustomColors then
		colorTranslateStroke.r = self.colorStrokeTranslateHandleR
		colorTranslateStroke.g = self.colorStrokeTranslateHandleG
		colorTranslateStroke.b = self.colorStrokeTranslateHandleB
		colorTranslateStroke.a = 255 * self.handleStrokeOpacity
		
		colorTranslateFill.r = self.colorFillTranslateHandleR
		colorTranslateFill.g = self.colorFillTranslateHandleG
		colorTranslateFill.b = self.colorFillTranslateHandleB
		colorTranslateFill.a = 255 * self.handleFillOpacity
		
		colorTranslateFillHL.r = ((colorTranslateFill.r * 3) + whiteColor.r) / 4
		colorTranslateFillHL.g = ((colorTranslateFill.g * 3) + whiteColor.g) / 4
		colorTranslateFillHL.b = ((colorTranslateFill.b * 3) + whiteColor.b) / 4
		colorTranslateFillHL.a = 255 * self.handleFillOpacity
		
		colorScaleStroke.r = self.colorStrokeScaleHandleR
		colorScaleStroke.g = self.colorStrokeScaleHandleG
		colorScaleStroke.b = self.colorStrokeScaleHandleB
		colorScaleStroke.a = 255 * self.handleStrokeOpacity

		colorScaleFill.r = self.colorFillScaleHandleR
		colorScaleFill.g = self.colorFillScaleHandleG
		colorScaleFill.b = self.colorFillScaleHandleB
		colorScaleFill.a = 255 * self.handleFillOpacity
		
		colorScaleFillHL.r = ((colorScaleFill.r * 3) + whiteColor.r) / 4
		colorScaleFillHL.g = ((colorScaleFill.g * 3) + whiteColor.g) / 4
		colorScaleFillHL.b = ((colorScaleFill.b * 3) + whiteColor.b) / 4
		colorScaleFillHL.a = 255 * self.handleFillOpacity

		colorMoveJointStroke.r = self.colorStrokeMoveJointHandleR
		colorMoveJointStroke.g = self.colorStrokeMoveJointHandleG
		colorMoveJointStroke.b = self.colorStrokeMoveJointHandleB
		colorMoveJointStroke.a = 255 * self.handleStrokeOpacity

		colorMoveJointFill.r = self.colorFillMoveJointHandleR
		colorMoveJointFill.g = self.colorFillMoveJointHandleG
		colorMoveJointFill.b = self.colorFillMoveJointHandleB
		colorMoveJointFill.a = 255 * self.handleFillOpacity
		
		colorMoveJointFillHL.r = ((colorMoveJointFill.r * 3) + whiteColor.r) / 4
		colorMoveJointFillHL.g = ((colorMoveJointFill.g * 3) + whiteColor.g) / 4
		colorMoveJointFillHL.b = ((colorMoveJointFill.b * 3) + whiteColor.b) / 4
		colorMoveJointFillHL.a = 255 * self.handleFillOpacity

		colorManipulateStroke.r = self.colorStrokeManipulateHandleR
		colorManipulateStroke.g = self.colorStrokeManipulateHandleG
		colorManipulateStroke.b = self.colorStrokeManipulateHandleB
		colorManipulateStroke.a = 255 * self.handleStrokeOpacity

		colorManipulateFill.r = self.colorFillManipulateHandleR
		colorManipulateFill.g = self.colorFillManipulateHandleG
		colorManipulateFill.b = self.colorFillManipulateHandleB
		colorManipulateFill.a = 255 * self.handleFillOpacity
		
		colorManipulateFillHL.r = ((colorManipulateFill.r * 3) + whiteColor.r) / 4
		colorManipulateFillHL.g = ((colorManipulateFill.g * 3) + whiteColor.g) / 4
		colorManipulateFillHL.b = ((colorManipulateFill.b * 3) + whiteColor.b) / 4
		colorManipulateFillHL.a = 255 * self.handleFillOpacity
	else
		colorTranslateStroke.r = MOHO.MohoGlobals.SelCol.r
		colorTranslateStroke.g = MOHO.MohoGlobals.SelCol.g
		colorTranslateStroke.b = MOHO.MohoGlobals.SelCol.b
		colorTranslateStroke.a = 255 * self.handleStrokeOpacity
		
		colorTranslateFill.r = fillCol.r
		colorTranslateFill.g = fillCol.g
		colorTranslateFill.b = fillCol.b
		colorTranslateFill.a = 255 * self.handleFillOpacity
		
		colorTranslateFillHL.r = ((colorTranslateFill.r * 3) + whiteColor.r) / 4
		colorTranslateFillHL.g = ((colorTranslateFill.g * 3) + whiteColor.g) / 4
		colorTranslateFillHL.b = ((colorTranslateFill.b * 3) + whiteColor.b) / 4
		colorTranslateFillHL.a = 255 * self.handleFillOpacity
		
		colorScaleStroke.r = MOHO.MohoGlobals.SelCol.r
		colorScaleStroke.g = MOHO.MohoGlobals.SelCol.g
		colorScaleStroke.b = MOHO.MohoGlobals.SelCol.b
		colorScaleStroke.a = 255 * self.handleStrokeOpacity

		colorScaleFill.r = fillCol.r
		colorScaleFill.g = fillCol.g
		colorScaleFill.b = fillCol.b
		colorScaleFill.a = 255 * self.handleFillOpacity
		
		colorScaleFillHL.r = ((colorScaleFill.r * 3) + whiteColor.r) / 4
		colorScaleFillHL.g = ((colorScaleFill.g * 3) + whiteColor.g) / 4
		colorScaleFillHL.b = ((colorScaleFill.b * 3) + whiteColor.b) / 4
		colorScaleFillHL.a = 255 * self.handleFillOpacity

		colorMoveJointFill.r = 255
		colorMoveJointFill.g = 189
		colorMoveJointFill.b = 46
		colorMoveJointFill.a = 255 * self.handleFillOpacity

		colorMoveJointStroke.r = (colorMoveJointFill.r + (MOHO.MohoGlobals.SelCol.r * 2)) / 3
		colorMoveJointStroke.g = (colorMoveJointFill.g + (MOHO.MohoGlobals.SelCol.g * 2)) / 3
		colorMoveJointStroke.b = (colorMoveJointFill.b + (MOHO.MohoGlobals.SelCol.b * 2)) / 3
		colorMoveJointStroke.a = 255 * self.handleStrokeOpacity
		
		colorMoveJointFillHL.r = ((colorMoveJointFill.r * 3) + whiteColor.r) / 4
		colorMoveJointFillHL.g = ((colorMoveJointFill.g * 3) + whiteColor.g) / 4
		colorMoveJointFillHL.b = ((colorMoveJointFill.b * 3) + whiteColor.b) / 4
		colorMoveJointFillHL.a = 255 * self.handleFillOpacity

		colorManipulateFill.r = 255
		colorManipulateFill.g = 189
		colorManipulateFill.b = 46
		colorManipulateFill.a = 255 * self.handleFillOpacity

		colorManipulateStroke.r = (colorManipulateFill.r + (MOHO.MohoGlobals.SelCol.r * 2)) / 3
		colorManipulateStroke.g = (colorManipulateFill.g + (MOHO.MohoGlobals.SelCol.g * 2)) / 3
		colorManipulateStroke.b = (colorManipulateFill.b + (MOHO.MohoGlobals.SelCol.b * 2)) / 3
		colorManipulateStroke.a = 255 * self.handleStrokeOpacity
		
		colorManipulateFillHL.r = ((colorManipulateFill.r * 3) + whiteColor.r) / 4
		colorManipulateFillHL.g = ((colorManipulateFill.g * 3) + whiteColor.g) / 4
		colorManipulateFillHL.b = ((colorManipulateFill.b * 3) + whiteColor.b) / 4
		colorManipulateFillHL.a = 255 * self.handleFillOpacity
	end
	
	local colorFollowBones = LM.rgb_color:new_local()
	colorFollowBones.r = self.colorFollowBonesR
	colorFollowBones.g = self.colorFollowBonesG
	colorFollowBones.b = self.colorFollowBonesB
	colorFollowBones.a = self.colorFollowBonesA
		
	if self.useHighlightCustomColor then
		colorHighlightBone.r = self.highlightCustomColorR
		colorHighlightBone.g = self.highlightCustomColorG
		colorHighlightBone.b = self.highlightCustomColorB
		colorHighlightBone.a = 255 * self.highlightOpacity
	else
		colorHighlightBone.r = MOHO.MohoGlobals.SelCol.r
		colorHighlightBone.g = MOHO.MohoGlobals.SelCol.g
		colorHighlightBone.b = MOHO.MohoGlobals.SelCol.b
		colorHighlightBone.a = 255 * self.highlightOpacity
	end
	
	local iconColorBack = LM.rgb_color:new_local()
	iconColorBack.r = 255
	iconColorBack.g = 255
	iconColorBack.b = 255
	iconColorBack.a = 255
	
	local iconColor = LM.rgb_color:new_local()
	iconColor.r = self.iconColorR
	iconColor.g = self.iconColorG
	iconColor.b = self.iconColorB
	iconColor.a = self.iconColorA
	
	local disabledIconColor = LM.rgb_color:new_local()
	disabledIconColor.r = (self.iconColorR + iconColorBack.r) / 2
	disabledIconColor.g = (self.iconColorG + iconColorBack.g) / 2
	disabledIconColor.b = (self.iconColorB + iconColorBack.b) / 2
	disabledIconColor.a = (self.iconColorA + iconColorBack.a) / 2
	
	local iconHowerColor = LM.rgb_color:new_local()
	iconHowerColor.r = (self.iconColorR * 3 + iconColorBack.r) / 4 
	iconHowerColor.g = (self.iconColorG * 3 + iconColorBack.g) / 4
	iconHowerColor.b = (self.iconColorB * 3 + iconColorBack.b) / 4
	iconHowerColor.a = (self.iconColorA * 3 + iconColorBack.a) / 4
	
	local lockAngleColor = LM.rgb_color:new_local()
	lockAngleColor.r = 255
	lockAngleColor.g = 68 
	lockAngleColor.b = 68 
	lockAngleColor.a = 255
	
	local lockPosColor = LM.rgb_color:new_local()
	lockPosColor.r = 255
	lockPosColor.g = 192
	lockPosColor.b = 0  
	lockPosColor.a = 255
	
	local hlDelta = 0
	
	local handlesDistance = self.handlesDistance
	if self.alignHandlesAlongBone then
		handlesDistance = 1
	end
	
	moho.layer:GetFullTransform(moho.frame, layerMatrix, moho.document)
	g:Push()
	g:ApplyMatrix(layerMatrix)
	local height = g:Height() / moho.document:Height()
	height = g:Height() / self.height
	local markerMultiplier = 0.002
	local additionMarker1 = self.additionHandles
	local currentScale = g:CurrentScale(false)
	g:SetSmoothing(true)
	g:SetBezierTolerance(2)

	if self.bonesDataActive then
		local isFollowBonesSelected = false
		for i=1, #self.followBonesList do
			local followBone = skel:Bone(self.followBonesList[i])
			if followBone.fSelected then
				isFollowBonesSelected = true
				break
			end
		end

		if #self.lockAngleList > 0 then
			g:SetPenWidth(10)
			g:SetColor(255, 241, 229, 255)
			local radius = 14
			
			for b=1, #self.lockAngleList do
				local boneId = self.lockAngleList[b]
				local lockBone = skel:Bone(boneId)
				if lockBone then
					if not self.ignoreBonesList[boneId + 1] then
						local lockBoneCenter = LM.Vector2:new_local()
						local lockBoneTip = LM.Vector2:new_local()
						lockBoneCenter:Set(0, 0)
						lockBoneTip:Set(lockBone.fLength / 3, 0)
						lockBone.fMovedMatrix:Transform(lockBoneCenter)
						lockBone.fMovedMatrix:Transform(lockBoneTip)
						if not lockBone:IsZeroLength() then
							g:DrawLine(lockBoneCenter.x, lockBoneCenter.y, lockBoneTip.x, lockBoneTip.y)
						end
					end
				end
			end
			
			g:SetPenWidth(4)
			g:SetColor(lockAngleColor)
			
			for b=1, #self.lockAngleList do
				local boneId = self.lockAngleList[b]
				local lockBone = skel:Bone(boneId)
				if lockBone then
					if not self.ignoreBonesList[boneId + 1] then
						local lockBoneCenter = LM.Vector2:new_local()
						local lockBoneTip = LM.Vector2:new_local()
						lockBoneCenter:Set(0, 0)
						lockBoneTip:Set(lockBone.fLength / 3, 0)
						lockBone.fMovedMatrix:Transform(lockBoneCenter)
						lockBone.fMovedMatrix:Transform(lockBoneTip)
						if lockBone:IsZeroLength() then
							g:SetColor(lockAngleColor)
							g:FillCirclePixelRadius(lockBoneCenter, radius)
							g:SetColor(iconColorBack)
							g:FrameCirclePixelRadius(lockBoneCenter, radius)
							g:SetColor(lockAngleColor)
						else
							g:DrawLine(lockBoneCenter.x, lockBoneCenter.y, lockBoneTip.x, lockBoneTip.y)
						end
					end
				end
			end
			g:SetPenWidth(1)
		end
		
		if #self.lockPosList > 0 then
			g:SetPenWidth(10)
			g:SetColor(iconColorBack)
			local radius = 10
			
			for b=1, #self.lockPosList do
				local boneId = self.lockPosList[b]
				local lockBone = skel:Bone(boneId)
				if lockBone then
					if not self.ignoreBonesList[boneId + 1] then
						local lockBoneCenter = LM.Vector2:new_local()
						local lockBoneTip = LM.Vector2:new_local()
						lockBoneCenter:Set(lockBone.fLength, 0)
						lockBoneTip:Set(lockBone.fLength / 1.5, 0)
						lockBone.fMovedMatrix:Transform(lockBoneCenter)
						lockBone.fMovedMatrix:Transform(lockBoneTip)
						if not lockBone:IsZeroLength() then
							g:DrawLine(lockBoneCenter.x, lockBoneCenter.y, lockBoneTip.x, lockBoneTip.y)
						end
					end
				end
			end
			
			g:SetPenWidth(4)
			g:SetColor(lockPosColor)
			
			for b=1, #self.lockPosList do
				local boneId = self.lockPosList[b]
				local lockBone = skel:Bone(boneId)
				if lockBone then
					if not self.ignoreBonesList[boneId + 1] then
						local lockBoneCenter = LM.Vector2:new_local()
						local lockBoneTip = LM.Vector2:new_local()
						lockBoneCenter:Set(lockBone.fLength, 0)
						lockBoneTip:Set(lockBone.fLength / 1.5, 0)
						lockBone.fMovedMatrix:Transform(lockBoneCenter)
						lockBone.fMovedMatrix:Transform(lockBoneTip)
						if lockBone:IsZeroLength() then
							g:SetColor(lockPosColor)
							g:FrameCirclePixelRadius(lockBoneCenter, radius)
						else
							g:DrawLine(lockBoneCenter.x, lockBoneCenter.y, lockBoneTip.x, lockBoneTip.y)
						end
					end
				end
			end
			g:SetPenWidth(1)
		end

		if not isFollowBonesSelected or self.forceFollowBonesGraphics then
			if #self.followBonesList.id > 0 then
				for b=1, #self.followBonesList.id do
					local isBlocked = false
					if self.dragging then
						if self.followBonesDataList.block then
							isBlocked = self.followBonesDataList.block[b]
						end
					end

					if not isBlocked then
						g:SetPenWidth(2)
						g:SetColor(colorFollowBones)
						for i=1, #self.followBonesList.id[b] do
							local followBone = skel:Bone(self.followBonesList.id[b][i])
							if i + 1 <= #self.followBonesList.id[b] then
								if followBone then
									local nextBone = skel:Bone(self.followBonesList.id[b][i + 1])
									if nextBone then
										local followBoneCenter = LM.Vector2:new_local()
										local nextBoneCenter = LM.Vector2:new_local()
										followBoneCenter:Set(followBone.fLength / 2, 0)
										nextBoneCenter:Set(nextBone.fLength / 2, 0)
										followBone.fMovedMatrix:Transform(followBoneCenter)
										nextBone.fMovedMatrix:Transform(nextBoneCenter)
										g:DrawLine(followBoneCenter.x, followBoneCenter.y, nextBoneCenter.x, nextBoneCenter.y)
									end
								end
							end
						end
						g:SetPenWidth(1)
					end
				end

				for b=1, #self.followBonesList.id do
					local isBlocked = false
					if self.dragging then
						if self.followBonesDataList.block then
							isBlocked = self.followBonesDataList.block[b]
						end
					end
					if not isBlocked then
						g:SetPenWidth(10)
						g:SetColor(196, 235, 255, 255)
						for i=1, #self.followBonesList.id[b] do
							local boneId = self.followBonesList.id[b][i]
							local followBone = skel:Bone(boneId)
							if followBone then
								if not self.ignoreBonesList[boneId + 1] then
									local followBoneCenter = LM.Vector2:new_local()
									local followBoneTip = LM.Vector2:new_local()
									followBoneCenter:Set(followBone.fLength / 1.5, 0)
									followBoneTip:Set(followBone.fLength / 3, 0)
									followBone.fMovedMatrix:Transform(followBoneCenter)
									followBone.fMovedMatrix:Transform(followBoneTip)
									g:DrawLine(followBoneCenter.x, followBoneCenter.y, followBoneTip.x, followBoneTip.y)
								end
							end
						end
						g:SetPenWidth(4)
						g:SetColor(colorFollowBones)
						for i=1, #self.followBonesList.id[b] do
							local boneId = self.followBonesList.id[b][i]
							local followBone = skel:Bone(boneId)
							if followBone then
								if not self.ignoreBonesList[boneId + 1] then
									local followBoneCenter = LM.Vector2:new_local()
									local followBoneTip = LM.Vector2:new_local()
									followBoneCenter:Set(followBone.fLength / 1.5, 0)
									followBoneTip:Set(followBone.fLength / 3, 0)
									followBone.fMovedMatrix:Transform(followBoneCenter)
									followBone.fMovedMatrix:Transform(followBoneTip)
									g:DrawLine(followBoneCenter.x, followBoneCenter.y, followBoneTip.x, followBoneTip.y)
								end
							end
						end
						if self.dragging then
							g:SetColor(colorHighlightBone)
							g:SetPenWidth(3)
							local markersSize = (0.015) / currentScale / height
							local marker1VecCam = self.followBonesDataList.targetPos[b]
							g:DrawLine(marker1VecCam.x - markersSize, marker1VecCam.y, marker1VecCam.x + markersSize, marker1VecCam.y)
							g:DrawLine(marker1VecCam.x, marker1VecCam.y - markersSize, marker1VecCam.x, marker1VecCam.y + markersSize)
						elseif self.showCross then
							if MR_TweenMachine and MR_TweenMachine.followBonesDataList.targetPos[b] then
								g:SetColor(colorHighlightBone)
								g:SetPenWidth(3)
								local markersSize = (0.015) / currentScale / height
								local marker1VecCam = MR_TweenMachine.followBonesDataList.targetPos[b]
								g:DrawLine(marker1VecCam.x - markersSize, marker1VecCam.y, marker1VecCam.x + markersSize, marker1VecCam.y)
								g:DrawLine(marker1VecCam.x, marker1VecCam.y - markersSize, marker1VecCam.x, marker1VecCam.y + markersSize)
							end
						end
						g:SetPenWidth(1)
					end
				end
			end
		end
	end
	
	if self.mousePickedID > -1 and not (self.dragging or moho:IsPlaying()) and not self.showIcons then
		local bone = skel:Bone(self.mousePickedID)
		if bone ~= nil then
			local isPin = bone:IsZeroLength()
			if not bone.fHidden and bone:IsGroupVisible() then
				v:Set(bone.fLength - bone.fLength * self.handlesDist, 0)
				bone.fMovedMatrix:Transform(v)

				if self.alignHandlesAlongBone then
					v:Set(bone.fLength - bone.fLength, 0)
					bone.fMovedMatrix:Transform(v)
				
					boneCenterPos:Set(bone.fLength - bone.fLength / 2, 0)
					bone.fMovedMatrix:Transform(boneCenterPos)
					center:Set(0, 0)
					tip:Set(1, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					
					offset:Set(v.x, v.y)
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					angle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, angle))
					
					offset:Set(v.x - ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					boneHandlePos:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					
					local layerMatrixNoCam = LM.Matrix:new_local()
					moho.layer:GetFullTransform(moho.frame, layerMatrixNoCam, nil)
					layerMatrixNoCam:Transform(boneHandlePos)
					
					local globalBoneCenterPos = LM.Vector2:new_local()
					globalBoneCenterPos:Set(boneCenterPos)
					layerMatrixNoCam:Transform(globalBoneCenterPos)
					
					if MR_Utilities:GetDistance(globalBoneCenterPos, boneHandlePos) * currentScale * height < 0.065 then
						alignHandlesAdaptation = true
					end
					
					v:Set(bone.fLength * self.handlesDist, 0)
					bone.fMovedMatrix:Transform(v)
					
					local distanceValue = MR_Utilities:GetDistance(center, v) * currentScale * height
					
					if distanceValue > self.handlesDistanceTreshhold then
						handlesZoomAdaptationVal = distanceValue / self.handlesDistanceTreshhold
					end
				else
					v:Set(bone.fLength * self.handlesDist, 0)
					bone.fMovedMatrix:Transform(v)
					center:Set(0, 0)
					bone.fMovedMatrix:Transform(center)
					
					local distanceValue = MR_Utilities:GetDistance(center, v) * currentScale * height
					
					if distanceValue > self.handlesDistanceTreshhold then
						handlesZoomAdaptationVal = distanceValue / self.handlesDistanceTreshhold
					end
				end
		
				v:Set(bone.fLength - bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
				bone.fMovedMatrix:Transform(v)

				if selBones < 1 and self.highlightBones then
					center:Set(0, 0)
					tip:Set(bone.fLength, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					g:SetPenWidth(self.highlightWidth)
					g:SetColor(colorHighlightBone)
					g:DrawLine(center.x, center.y, tip.x, tip.y)
					g:SetPenWidth(1)
				end
				
				if additionMarker1 then
					center:Set(0, 0)
					tip:Set(1, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					
					if self.alignHandlesAlongBone then
						offset:Set(v.x, v.y)
						if alignHandlesAdaptation then
							offset:Set(boneCenterPos.x + (((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height) * 1.5), boneCenterPos.y)
						end
					else
						offset:Set(v.x, v.y - ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end	
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					angle = offsetAngle + (angle - offsetAngle)
					if alignHandlesAdaptation then
						v:Set(MR_Utilities:RotateVector2(offset, boneCenterPos, angle))
					else
						v:Set(MR_Utilities:RotateVector2(offset, v, angle))
					end
				end
				if self.drawMode == 2 then
					if isPin then
						g:SetColor(colorScaleFillHL)
					else
						g:SetColor(colorScaleFillHL)
					end	
					markerR = self.markerR + hlDelta
				else
					if isPin then
						g:SetColor(colorScaleFill)
					else
						g:SetColor(colorScaleFill)
					end	
					markerR = self.markerR
				end
				
				if bone.fLength == 0 and self.keepHandles then
					markerR = markerR * 3
				end
				if (self.ignoreZeroScaledBones and MR_Utilities:Round(bone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
					g:FillCirclePixelRadius(v, markerR)
					g:SetColor(colorScaleStroke)
					g:FrameCirclePixelRadius(v, markerR)
				end
				
				markerR = self.markerR
				if additionMarker1 then
					if self.alignHandlesAlongBone then
						offset:Set(v.x - ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					else
						v:Set(bone.fLength - (bone.fLength * (self.handlesDist / handlesZoomAdaptationVal)), 0)
						bone.fMovedMatrix:Transform(v)
						offset:Set(v.x, v.y + ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end	
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					
					if self.drawMode == 4 then
						g:SetColor(colorManipulateFillHL)
						markerR = self.markerR + hlDelta
					else
						g:SetColor(colorManipulateFill)
						markerR = self.markerR
					end
					g:FillCirclePixelRadius(v, markerR)
					g:SetColor(colorManipulateStroke)
					g:FrameCirclePixelRadius(v, markerR)
					markerR = self.markerR
				end	
				
				v:Set(bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
				bone.fMovedMatrix:Transform(v)
				
				if additionMarker1 then
					if self.alignHandlesAlongBone then
						offset:Set(v.x, v.y)
						if alignHandlesAdaptation then
							offset:Set(boneCenterPos.x - (((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height)* 1.5), boneCenterPos.y)
						end
					else
						offset:Set(v.x, v.y - ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					
					if alignHandlesAdaptation then
						v:Set(MR_Utilities:RotateVector2(offset, boneCenterPos, newAngle))
					else
						v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					end
				end

				if self.drawMode == 0 or self.drawMode == 5 then
					g:SetColor(colorTranslateFillHL)
					markerR = self.markerR + hlDelta
				else
					g:SetColor(colorTranslateFill)
					markerR = self.markerR
				end
				
				g:FillCirclePixelRadius(v, markerR)
				g:SetColor(colorTranslateStroke)
				g:FrameCirclePixelRadius(v, markerR)
				markerR = self.markerR
				
				if not isPin then
					if additionMarker1 then
						if self.alignHandlesAlongBone then
							offset:Set(v.x  + ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
						else	
							v:Set(bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
							bone.fMovedMatrix:Transform(v)
							offset:Set(v.x, v.y + ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
						end
						offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
						newAngle = offsetAngle + (angle - offsetAngle)
						v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
						
						if self.drawMode == 3 then
							g:SetColor(colorMoveJointFillHL)
							markerR = self.markerR + hlDelta
						else
							g:SetColor(colorMoveJointFill)
							markerR = self.markerR
						end
						g:FillCirclePixelRadius(v, markerR)
						g:SetColor(colorMoveJointStroke)
						g:FrameCirclePixelRadius(v, markerR)
						markerR = self.markerR
					end	
				end
			end
		end
	end
	if selBones == 1 then
		local bone = skel:Bone(skel:SelectedBoneID())
		if bone ~= nil then
			if (bone.fSelected and self.showPath and bone.fParent < 0) then
				-- draw path
				local channelPos = bone.fAnimPos
				local startFrame = channelPos:GetKeyWhen(0)
				local channelDuration = channelPos:Duration()
				local endFrame = channelDuration
				local totalTimingOffset = moho.layer:TotalTimingOffset()

				if (startFrame - totalTimingOffset < 0) then
					startFrame = totalTimingOffset
				end
				channelPos:GetKeyInterp(endFrame, interp)
				if (interp:IsAdditiveCycle()) then
					endFrame = moho.document:EndFrame() + totalTimingOffset
				end

				if (endFrame > startFrame) then
					local vec = LM.Vector2:new_local()
					local oldVec = LM.Vector2:new_local()
					if self.range then
						startFrame = LM.Clamp(moho.layerFrame - self.rangeFrames, 1, channelDuration)
						endFrame = LM.Clamp(moho.layerFrame + self.rangeFrames, 1, channelDuration)
					end
					g:SetColor(102, 152, 203)
					for frame = startFrame, endFrame do
						vec = channelPos:GetValue(frame)
						if (frame > startFrame) then
							g:DrawLine(oldVec.x, oldVec.y, vec.x, vec.y)
						end
						if (channelPos:HasKey(frame)) then
							g:DrawFatMarker(vec.x, vec.y, 5)
						else
							g:DrawMarker(vec.x, vec.y)
						end
						oldVec:Set(vec)
					end
				end
			end
		end	
	end
	
	g:Pop()
	
	if self.showIcons then
		local m = LM.Matrix:new_local()
		moho.document:GetCameraMatrix(moho.layerFrame, m)
		g:Push()
		currentScale = g:CurrentScale(false)
		height = g:Height() / moho.document:Height()
		height = g:Height() / self.height
		local offset = self.iconsDistance / currentScale / height
		local center = LM.Vector2:new_local()
		center:Set(self.graphicsMenuCenter)
		local radius = self.iconsRadius
		local howerRadius = 1.1
		local shadowOffset = LM.Vector2:new_local()
		shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
		local v = LM.Vector2:new_local()
		local v1 = LM.Vector2:new_local()
		local v2 = LM.Vector2:new_local()
		local tooltipSizeH = 0.35 / currentScale / height
		local tooltipSizeV = 0.05 / currentScale / height
		local tooltipTextOffsetH = 0.033 / currentScale / height
		local tooltipTextOffsetV = 0.011 / currentScale / height
		local tooltipTextSize = 3 / currentScale / height
		
		-- set follow bones icon
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(30)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 1 then
			if self.showIcons2Alt then
				tooltipSizeH = 0.506 / currentScale / height
				tooltipSizeV = 0.05 / currentScale / height
				tooltipTextOffsetH = 0.033 / currentScale / height
				tooltipTextOffsetV = 0.011 / currentScale / height
				tooltipTextSize = 3 / currentScale / height
				
				g:SetPenWidth(1)
				g:SetColor(255, 255, 255, 255)	
				g:BeginShape()
				v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
				v2:Set(v.x, v1.y)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x, v1.y + tooltipSizeV)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x - tooltipSizeH, v1.y)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x, v1.y -tooltipSizeV)
				g:AddLine(v1, v2)
				g:EndShape()
				
				g:SetColor(0, 0, 0, 255)	
				v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
				
				HV_Font:DrawLetters(moho, g, self:Localize('Set single follow bones'), tooltipTextSize, v1.x, v1.y, 0, 0)
			else
				tooltipSizeH = 0.518 / currentScale / height
				tooltipSizeV = 0.05 / currentScale / height
				tooltipTextOffsetH = 0.033 / currentScale / height
				tooltipTextOffsetV = 0.011 / currentScale / height
				tooltipTextSize = 3 / currentScale / height
				
				g:SetPenWidth(1)
				g:SetColor(255, 255, 255, 255)	
				g:BeginShape()
				v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
				v2:Set(v.x, v1.y)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x, v1.y + tooltipSizeV)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x - tooltipSizeH, v1.y)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x, v1.y -tooltipSizeV)
				g:AddLine(v1, v2)
				g:EndShape()
				
				g:SetColor(0, 0, 0, 255)	
				v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
				
				HV_Font:DrawLetters(moho, g, self:Localize('Set follow bones chains'), tooltipTextSize, v1.x, v1.y, 0, 0)
			end
		end
		
		if self.graphicMenuMode == 1 then
			radius = self.iconsRadius * howerRadius
		else
			radius = self.iconsRadius
		end
		
		g:SetColor(0, 0, 0, 75)		
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		if self.graphicMenuMode == 1 then
			g:SetColor(iconHowerColor)
		else
			g:SetColor(iconColor)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		g:SetColor(iconColor)
		local arrowLen = 0.012 / currentScale / height
		local arrowWidth = 0.012 / currentScale / height
		
		local iconCenter = LM.Vector2:new_local()
		local offsetCenter = -0.01 / currentScale / height
		iconCenter:Set(v.x + offsetCenter, v.y)
		g:BeginShape()
		v1:Set(iconCenter.x - arrowLen, iconCenter.y + arrowWidth)
		v2:Set(iconCenter.x + arrowLen, iconCenter.y + arrowWidth)
		v1:Set(MR_Utilities:RotateVector2(v1, v, math.rad(45)))
		v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x + arrowLen, iconCenter.y + arrowWidth * 2.0)
		v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x + arrowLen + arrowWidth * 2.0, iconCenter.y)
		v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x + arrowLen, iconCenter.y - (arrowWidth * 2.0))
		v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x + arrowLen, iconCenter.y - arrowWidth)
		v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x-arrowLen, iconCenter.y - arrowWidth )
		v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x - arrowLen, iconCenter.y + arrowWidth)
		v2:Set(MR_Utilities:RotateVector2(v2, v, math.rad(45)))
		g:AddLine(v1, v2)
		g:EndShape()
		
		if self.showIcons2Alt then
			g:SetColor(iconColorBack)	
			
			local offsetLine = 0.003 / currentScale / height
			
			v1:Set(iconCenter.x - offsetLine * 3, iconCenter.y + offsetLine * 0.6)
			v2:Set(iconCenter.x + offsetLine * 4, iconCenter.y - offsetLine * 6)

			local markersSize = (0.004) / currentScale / height
			g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		end
		
		-- scale follow bones icon
		if self.graphicMenuMode == 2 then
			radius = self.iconsRadius * howerRadius
		else
			radius = self.iconsRadius
		end
		
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(90)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 2 then
			tooltipSizeH = 0.424 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.033 / currentScale / height
			tooltipTextOffsetV = 0.011 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x - tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Scale follow bones'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		g:SetColor(0, 0, 0, 75)		
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		
		if self.graphicMenuMode == 2 then
			g:SetColor(iconHowerColor)
		else
			g:SetColor(iconColor)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		if self.scaleFollowBones then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		
		offsetCenter = -0.0025 / currentScale / height
		iconCenter:Set(v.x + offsetCenter, v.y - offsetCenter)
		local boxSize = 0.015 / currentScale / height
		g:SetPenWidth(2)

		v1:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		v2:Set(iconCenter.x + boxSize, iconCenter.y + boxSize)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(iconCenter.x + boxSize, iconCenter.y - boxSize)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y - boxSize)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		offsetCenter = 0.01 / currentScale / height
		iconCenter:Set(v.x + offsetCenter, v.y - offsetCenter)
		local boxSize = 0.008 / currentScale / height
		
		g:SetColor(iconColorBack)
		g:BeginShape()
		v1:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		v2:Set(iconCenter.x + boxSize, iconCenter.y + boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x + boxSize, iconCenter.y - boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y - boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		g:AddLine(v1, v2)
		g:EndShape()
		
		if self.scaleFollowBones then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		v1:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		v2:Set(iconCenter.x + boxSize, iconCenter.y + boxSize)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(iconCenter.x + boxSize, iconCenter.y - boxSize)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y - boxSize)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		-- lock angle icon
		if self.graphicMenuMode == 3 then
			radius = self.iconsRadius * howerRadius
		else
			radius = self.iconsRadius
		end
		
		g:SetPenWidth(3)
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-30)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 3 then
			tooltipSizeH = 0.275 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.0735 / currentScale / height
			tooltipTextOffsetV = 0.012 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x + tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Lock angle'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		g:SetColor(0, 0, 0, 75)		
		shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		
		if self.graphicMenuMode == 3 then
			g:SetColor(iconHowerColor)
		else
			g:SetColor(iconColor)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		g:SetColor(iconColor)
		
		offsetCenter = 0.005 / currentScale / height
		iconCenter:Set(v.x, v.y - offsetCenter)
		local boxSize = 0.015 / currentScale / height
		
		g:BeginShape()
		v1:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		v2:Set(iconCenter.x + boxSize, iconCenter.y + boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x + boxSize, iconCenter.y - boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y - boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetPenWidth(2)
		v1:Set((iconCenter.x - boxSize) - ((iconCenter.x - boxSize) - iconCenter.x)/3, iconCenter.y + boxSize + (0.0025 / currentScale / height))
		v2:Set(v1.x, v1.y + 0.01 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set((iconCenter.x + boxSize) + ((iconCenter.x - boxSize) - iconCenter.x)/3, v2.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(v1.x, iconCenter.y + boxSize + (0.0025 / currentScale / height))
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)

		local symbolWidth = 0.007 / currentScale / height
		local symbolHeight = 0.01 / currentScale / height
		g:SetColor(iconColorBack)
		v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
		v2:Set(iconCenter.x, iconCenter.y + symbolHeight)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(iconCenter.x + symbolWidth, iconCenter.y - symbolHeight)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(iconCenter.x - symbolWidth / 2, iconCenter.y - symbolHeight / 2)
		v2:Set(iconCenter.x + symbolWidth / 2, iconCenter.y - symbolHeight / 2)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		-- lock pos icon
		if self.graphicMenuMode == 4 then
			radius = self.iconsRadius * howerRadius
		else
			radius = self.iconsRadius
		end
		
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-90)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 4 then
			tooltipSizeH = 0.318 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.072 / currentScale / height
			tooltipTextOffsetV = 0.012 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x + tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Lock position'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		g:SetColor(0, 0, 0, 75)		
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		
		if self.graphicMenuMode == 4 then
			g:SetColor(iconHowerColor)
		else
			g:SetColor(iconColor)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		g:SetColor(iconColor)
		
		offsetCenter = 0.005 / currentScale / height
		iconCenter:Set(v.x, v.y - offsetCenter)
		local boxSize = 0.015 / currentScale / height
		
		g:BeginShape()
		v1:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		v2:Set(iconCenter.x + boxSize, iconCenter.y + boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x + boxSize, iconCenter.y - boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y - boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		g:AddLine(v1, v2)
		g:EndShape()
		
		g:SetPenWidth(2)
		v1:Set((iconCenter.x - boxSize) - ((iconCenter.x - boxSize) - iconCenter.x)/3, iconCenter.y + boxSize + (0.0025 / currentScale / height))
		v2:Set(v1.x, v1.y + 0.01 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set((iconCenter.x + boxSize) + ((iconCenter.x - boxSize) - iconCenter.x)/3, v2.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(v1.x, iconCenter.y + boxSize + (0.0025 / currentScale / height))
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)

		local symbolWidth = 0.007 / currentScale / height
		local symbolHeight = 0.008 / currentScale / height
		g:SetColor(iconColorBack)
		v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
		v2:Set(iconCenter.x - symbolWidth, iconCenter.y + symbolHeight)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(iconCenter.x + symbolWidth, v2.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(v2.x, v2.y - symbolHeight)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		v1:Set(v2)
		v2:Set(iconCenter.x - symbolWidth, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		-- clear icon
		if self.graphicMenuMode == 5 then
			radius = self.iconsRadius * howerRadius
		else
			radius = self.iconsRadius
		end
		
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(210)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 5 then
			if self.showIcons2Alt then
				tooltipSizeH = 0.22 / currentScale / height
				tooltipSizeV = 0.05 / currentScale / height
				tooltipTextOffsetH = 0.072 / currentScale / height
				tooltipTextOffsetV = 0.012 / currentScale / height
				tooltipTextSize = 3 / currentScale / height
				
				g:SetPenWidth(1)
				g:SetColor(255, 255, 255, 255)	
				g:BeginShape()
				v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
				v2:Set(v.x, v1.y)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x, v1.y + tooltipSizeV)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x + tooltipSizeH, v1.y)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x, v1.y -tooltipSizeV)
				g:AddLine(v1, v2)
				g:EndShape()
				
				g:SetColor(0, 0, 0, 255)	
				v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
				
				HV_Font:DrawLetters(moho, g, self:Localize('Clear all'), tooltipTextSize, v1.x, v1.y, 0, 0)
			else
				tooltipSizeH = 0.35 / currentScale / height
				tooltipSizeV = 0.05 / currentScale / height
				tooltipTextOffsetH = 0.072 / currentScale / height
				tooltipTextOffsetV = 0.012 / currentScale / height
				tooltipTextSize = 3 / currentScale / height
				
				g:SetPenWidth(1)
				g:SetColor(255, 255, 255, 255)	
				g:BeginShape()
				v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
				v2:Set(v.x, v1.y)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x, v1.y + tooltipSizeV)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x + tooltipSizeH, v1.y)
				g:AddLine(v1, v2)
				v1:Set(v2)
				v2:Set(v1.x, v1.y -tooltipSizeV)
				g:AddLine(v1, v2)
				g:EndShape()
				
				g:SetColor(0, 0, 0, 255)	
				v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
				
				HV_Font:DrawLetters(moho, g, self:Localize('Clear selection'), tooltipTextSize, v1.x, v1.y, 0, 0)
			end
			
		end
		
		if self.showIcons2Alt then
			g:SetColor(0, 0, 0, 75)		
			shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
			g:FillCirclePixelRadius(v + shadowOffset, radius)
			g:SetColor(iconColorBack)		
			g:FillCirclePixelRadius(v, radius)
			g:SetPenWidth(3)
			
			if self.graphicMenuMode == 6 then
				g:SetColor(iconHowerColor)
			else
				g:SetColor(iconColor)
			end
			
			g:FrameCirclePixelRadius(v, radius)
			g:SetColor(iconColor)
			
			offsetCenter = 0.005 / currentScale / height
			iconCenter:Set(v.x, v.y)
			
			local symbolWidth = 0.015 / currentScale / height
			local symbolHeight = 0.015 / currentScale / height
			v1:Set(iconCenter.x - symbolWidth, iconCenter.y + symbolHeight)
			v2:Set(iconCenter.x + symbolWidth, iconCenter.y - symbolHeight)
			g:DrawLine(v1.x, v1.y, v2.x, v2.y)
			v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
			v2:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
			g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		else
			g:SetColor(0, 0, 0, 75)		
			shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
			g:FillCirclePixelRadius(v + shadowOffset, radius)
			g:SetColor(iconColorBack)		
			g:FillCirclePixelRadius(v, radius)
			g:SetPenWidth(3)
			
			if self.graphicMenuMode == 5 then
				g:SetColor(iconHowerColor)
			else
				g:SetColor(iconColor)
			end
			
			g:FrameCirclePixelRadius(v, radius)
			g:SetColor(iconColor)
			
			offsetCenter = 0.005 / currentScale / height
			iconCenter:Set(v.x, v.y)
			
			local symbolWidth = 0.008 / currentScale / height
			local symbolHeight = 0.008 / currentScale / height
			v1:Set(iconCenter.x - symbolWidth, iconCenter.y + symbolHeight)
			v2:Set(iconCenter.x + symbolWidth, iconCenter.y - symbolHeight)
			g:DrawLine(v1.x, v1.y, v2.x, v2.y)
			v1:Set(iconCenter.x - symbolWidth, iconCenter.y - symbolHeight)
			v2:Set(iconCenter.x + symbolWidth, iconCenter.y + symbolHeight)
			g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		end
		
		-- clear enable icon
		local iconRadius = self.iconsRadius
		if self.graphicMenuMode == 6 then
			radius = self.iconsRadius * howerRadius
		else
			radius = self.iconsRadius
		end
		
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(150)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 6 then
			tooltipSizeH = 0.19 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.033 / currentScale / height
			tooltipTextOffsetV = 0.011 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x - tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Enable'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		g:SetColor(0, 0, 0, 75)		
		shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		
		if self.graphicMenuMode == 6 then
			g:SetColor(iconHowerColor)
		else
			g:SetColor(iconColor)
		end

		g:FrameCirclePixelRadius(v, radius)
		
		if self.bonesDataActive then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		
		iconCenter:Set(v.x, v.y)
		
		g:FrameCirclePixelRadius(v, iconRadius * 0.55)
		
		g:SetColor(iconColorBack)	
		
		offsetCenter = 0.014 / currentScale / height
		iconCenter:Set(v.x, v.y + offsetCenter)
		local boxSize = 0.008 / currentScale / height
		
		g:BeginShape()
		v1:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		v2:Set(iconCenter.x + boxSize, iconCenter.y + boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x + boxSize, iconCenter.y - boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y - boxSize)
		g:AddLine(v1, v2)
		v1:Set(v2)
		v2:Set(iconCenter.x - boxSize, iconCenter.y + boxSize)
		g:AddLine(v1, v2)
		g:EndShape()
		
		if self.bonesDataActive then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		
		local symbolHeight = 0.008 / currentScale / height
		v1:Set(iconCenter.x, iconCenter.y - symbolHeight)
		v2:Set(iconCenter.x, iconCenter.y + symbolHeight)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		g:Pop()
	end
	
	if self.showIcons2 then
		local m = LM.Matrix:new_local()
		moho.document:GetCameraMatrix(moho.layerFrame, m)
		g:Push()
		currentScale = g:CurrentScale(false)
		height = g:Height() / moho.document:Height()
		height = g:Height() / self.height
		local offset = self.iconsDistance * 1.05 / currentScale / height
		local center = LM.Vector2:new_local()
		center:Set(self.graphicsMenuCenter)
		local radius = self.iconsRadius
		local radiusMultiplier = 1.1
		local howerRadius = 1.1
		local shadowOffset = LM.Vector2:new_local()
		shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
		local v = LM.Vector2:new_local()
		local v1 = LM.Vector2:new_local()
		local v2 = LM.Vector2:new_local()
		local tooltipSizeH = 0.35 / currentScale / height
		local tooltipSizeV = 0.05 / currentScale / height
		local tooltipTextOffsetH = 0.033 / currentScale / height
		local tooltipTextOffsetV = 0.011 / currentScale / height
		local tooltipTextSize = 3 / currentScale / height
		
		-- Multi Transform icon
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(30)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 1 then
			tooltipSizeH = 0.34 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.033 / currentScale / height
			tooltipTextOffsetV = 0.011 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x - tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Multi transform'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		if self.graphicMenuMode == 1 then
			radius = self.iconsRadius * radiusMultiplier * howerRadius
		else
			radius = self.iconsRadius * radiusMultiplier
		end
		
		local arrowLen = 0.012 / currentScale / height
		local arrowWidth = 0.012 / currentScale / height
		
		local iconCenter = LM.Vector2:new_local()
		iconCenter:Set(v.x - 0.0011 / currentScale / height, v.y + 0.003 / currentScale / height)
		
		g:SetColor(0, 0, 0, 75)		
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		if self.graphicMenuMode == 1 then
			g:SetColor(255, 222, 120, 255)
		else
			g:SetColor(255, 195, 52, 255)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		
		if self.multiTransform and self.keepSelection then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		
		g:SetPenWidth(2)
		
		v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
		v2:Set(v1.x, v1.y + 0.022 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x + 0.007 / currentScale / height, v1.y - 0.012 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x + 0.007 / currentScale / height, v1.y + 0.012 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, iconCenter.y - 0.015 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)

		v1:Set(iconCenter.x + 0.012 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
		v2:Set(v1.x, v1.y + 0.02 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2.x - 0.007 / currentScale / height, v2.y)
		v2:Set(v2.x + 0.007 / currentScale / height, v2.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)

		-- Keep Selection icon
		if self.graphicMenuMode == 2 then
			radius = self.iconsRadius * radiusMultiplier * howerRadius
		else
			radius = self.iconsRadius * radiusMultiplier
		end
		
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(90)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 2 then
			tooltipSizeH = 0.35 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.033 / currentScale / height
			tooltipTextOffsetV = 0.011 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x - tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Keep selection'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		g:SetColor(0, 0, 0, 75)		
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		
		if self.graphicMenuMode == 2 then
			g:SetColor(70, 148, 255, 255)
		else
			g:SetColor(14, 116, 255, 255)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		if self.keepSelection then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		
		iconCenter:Set(v.x + 0.0012 / currentScale / height, v.y + 0.003 / currentScale / height)
		
		g:SetPenWidth(2)

		v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
		v2:Set(v1.x, v1.y + 0.022 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2.x, iconCenter.y - 0.005 / currentScale / height)
		v2:Set(v1.x + 0.01 / currentScale / height , v1.y + 0.0105 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v1.x, iconCenter.y - 0.005 / currentScale / height)
		v2:Set(v1.x + 0.01 / currentScale / height , v1.y - 0.009 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(iconCenter.x + 0.001 / currentScale / height, iconCenter.y - 0.013 / currentScale / height)
		v2:Set(v1.x  + 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x - 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		-- lock Handle icon
		if self.graphicMenuMode == 3 then
			radius = self.iconsRadius * radiusMultiplier * howerRadius
		else
			radius = self.iconsRadius * radiusMultiplier
		end
		
		g:SetPenWidth(3)
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-30)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 3 then
			tooltipSizeH = 0.325 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.0735 / currentScale / height
			tooltipTextOffsetV = 0.012 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x + tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Lock handles'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		g:SetColor(0, 0, 0, 75)		
		shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		
		if self.graphicMenuMode == 3 then
			g:SetColor(45, 243, 54, 255)
		else
			g:SetColor(19, 223, 29, 255)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		if self.lockHandles then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		
		iconCenter:Set(v.x - 0.0007 / currentScale / height, v.y + 0.003 / currentScale / height)
		
		g:SetPenWidth(2)
		
		v1:Set(iconCenter.x - 0.0145 / currentScale / height, iconCenter.y + 0.007 / currentScale / height)
		v2:Set(v1.x, iconCenter.y - 0.013 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x + 0.010 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
	
		v1:Set(iconCenter.x + 0.0013 / currentScale / height, iconCenter.y + 0.007 / currentScale / height)
		v2:Set(v1.x, iconCenter.y - 0.015 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2.x, iconCenter.y - 0.0035 / currentScale / height)
		v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2.x, iconCenter.y + 0.007 / currentScale / height)
		v2:Set(v1.x, iconCenter.y - 0.015 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		-- Smart Bake icon
		if self.graphicMenuMode == 4 then
			radius = self.iconsRadius * radiusMultiplier * howerRadius
		else
			radius = self.iconsRadius * radiusMultiplier
		end
		
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-90)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 4 then
			tooltipSizeH = 0.27 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.072 / currentScale / height
			tooltipTextOffsetV = 0.012 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x + tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Bake Adjacent Frames'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		g:SetColor(0, 0, 0, 75)		
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		
		if self.graphicMenuMode == 4 then
			g:SetColor(211, 94, 255, 255)
		else
			g:SetColor(202, 60, 255, 255)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		if self.bakeAdjacentFrames then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		
		iconCenter:Set(v.x + 0.0008 / currentScale / height, v.y + 0.003 / currentScale / height)
		
		g:SetPenWidth(2)
		
		v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.013 / currentScale / height)
		v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x - 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)

		v1:Set(iconCenter.x + 0.0045 / currentScale / height, iconCenter.y - 0.0126 / currentScale / height)
		v2:Set(v1.x, v1.y + 0.020 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2.x, v2.y - 0.001 / currentScale / height)
		v2:Set(v1.x + 0.008 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v2.x + 0.001 / currentScale / height, v2.y - 0.001 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, v1.y - 0.0075 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x - 0.001 / currentScale / height, v1.y - 0.001 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x - 0.010 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2.x + 0.011 / currentScale / height, v2.y)
		v2:Set(v1.x, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v2.x + 0.001 / currentScale / height, v2.y - 0.001 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, v1.y - 0.008 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x - 0.001 / currentScale / height, v1.y - 0.001 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x - 0.010 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		-- Show Path icon
		if self.graphicMenuMode == 5 then
			radius = self.iconsRadius * radiusMultiplier * howerRadius
		else
			radius = self.iconsRadius * radiusMultiplier
		end
		
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(210)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 5 then
			tooltipSizeH = 0.256 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.072 / currentScale / height
			tooltipTextOffsetV = 0.012 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x + tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x + tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Show path'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		g:SetColor(0, 0, 0, 75)		
		shadowOffset:Set(-0.005 / currentScale / height, -0.01 / currentScale / height)
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		
		if self.graphicMenuMode == 5 then
			g:SetColor(86, 225, 255, 255)
		else
			g:SetColor(27, 203, 241, 255)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		if self.showPath then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		
		iconCenter:Set(v.x + 0.00045 / currentScale / height, v.y + 0.003 / currentScale / height)
		
		g:SetPenWidth(2)
		
		v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.013 / currentScale / height)
		v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x - 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, v1.y + 0.009 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x + 0.012 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(iconCenter.x + 0.0045 / currentScale / height, iconCenter.y - 0.014 / currentScale / height)
		v2:Set(v1.x, v1.y + 0.021 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2.x, v2.y - 0.001 / currentScale / height)
		v2:Set(v1.x + 0.01 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v2.x + 0.001 / currentScale / height, v2.y - 0.001 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, v1.y - 0.0075 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x - 0.001 / currentScale / height, v1.y - 0.001 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x - 0.010 / currentScale / height, v1.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		-- Twos Mode icon
		if self.graphicMenuMode == 6 then
			radius = self.iconsRadius * radiusMultiplier * howerRadius
		else
			radius = self.iconsRadius * radiusMultiplier
		end
		
		v:Set(center.x, center.y + offset)
		v:Set(MR_Utilities:RotateVector2(v, center, math.rad(150)))
		
		if self.quickMenuTooltips and HV_Font and self.graphicMenuMode == 6 then
			tooltipSizeH = 0.275 / currentScale / height
			tooltipSizeV = 0.05 / currentScale / height
			tooltipTextOffsetH = 0.033 / currentScale / height
			tooltipTextOffsetV = 0.011 / currentScale / height
			tooltipTextSize = 3 / currentScale / height
			
			g:SetPenWidth(1)
			g:SetColor(255, 255, 255, 255)	
			g:BeginShape()
			v1:Set(v.x - tooltipSizeH, v.y - tooltipSizeV / 2)
			v2:Set(v.x, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y + tooltipSizeV)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x - tooltipSizeH, v1.y)
			g:AddLine(v1, v2)
			v1:Set(v2)
			v2:Set(v1.x, v1.y -tooltipSizeV)
			g:AddLine(v1, v2)
			g:EndShape()
			
			g:SetColor(0, 0, 0, 255)	
			v1:Set(v.x - tooltipSizeH + tooltipTextOffsetH, v.y - tooltipSizeV / 2 + tooltipTextOffsetV)
			
			HV_Font:DrawLetters(moho, g, self:Localize('Twos mode'), tooltipTextSize, v1.x, v1.y, 0, 0)
		end
		
		g:SetColor(0, 0, 0, 75)		
		shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
		g:FillCirclePixelRadius(v + shadowOffset, radius)
		g:SetColor(iconColorBack)		
		g:FillCirclePixelRadius(v, radius)
		g:SetPenWidth(3)
		
		if self.graphicMenuMode == 6 then
			g:SetColor(255, 100, 100, 255)
		else
			g:SetColor(255, 70, 70, 255)
		end
		
		g:FrameCirclePixelRadius(v, radius)
		if self.twosMode then
			g:SetColor(iconColor)
		else
			g:SetColor(disabledIconColor)
		end
		
		iconCenter:Set(v.x + 0.0018 / currentScale / height, v.y + 0.003 / currentScale / height)
		
		g:SetPenWidth(2)

		v1:Set(iconCenter.x - 0.015 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
		v2:Set(v1.x, v1.y + 0.02 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2.x - 0.007 / currentScale / height, v2.y)
		v2:Set(v2.x + 0.007 / currentScale / height, v2.y)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(iconCenter.x - 0.002 / currentScale / height, iconCenter.y - 0.015 / currentScale / height)
		v2:Set(v1.x, v1.y + 0.022 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x + 0.007 / currentScale / height, v1.y - 0.012 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x + 0.007 / currentScale / height, v1.y + 0.012 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		v1:Set(v2)
		v2:Set(v1.x, iconCenter.y - 0.015 / currentScale / height)
		g:DrawLine(v1.x, v1.y, v2.x, v2.y)
		
		g:Pop()
	end
end

-- **************************************************
-- Tool Panel Layout
-- **************************************************

MR_PoseTool.TWOS_MODE = MOHO.MSG_BASE
MR_PoseTool.KEEP_SELECTION = MOHO.MSG_BASE + 1
MR_PoseTool.MULTI_TRANSFORM = MOHO.MSG_BASE + 2
MR_PoseTool.LOCK_HANDLES = MOHO.MSG_BASE + 3
MR_PoseTool.BAKE_ADJACENT_FRAMES = MOHO.MSG_BASE + 4
MR_PoseTool.INTERVAL_1 = MOHO.MSG_BASE + 5
MR_PoseTool.INTERVAL_2 = MOHO.MSG_BASE + 6
MR_PoseTool.INTERVAL_3 = MOHO.MSG_BASE + 7
MR_PoseTool.INTERVAL_4 = MOHO.MSG_BASE + 8
MR_PoseTool.SHOW_PATH = MOHO.MSG_BASE + 9
MR_PoseTool.RANGE = MOHO.MSG_BASE + 10
MR_PoseTool.RANGE_FRAMES = MOHO.MSG_BASE + 11
MR_PoseTool.FLIP_H = MOHO.MSG_BASE + 12
MR_PoseTool.FLIP_V = MOHO.MSG_BASE + 13
MR_PoseTool.RESET_A = MOHO.MSG_BASE + 14
MR_PoseTool.RESET_T = MOHO.MSG_BASE + 15
MR_PoseTool.RESET_S = MOHO.MSG_BASE + 16

function MR_PoseTool:DoLayout(moho, layout)
	self.dlog = MR_PoseToolSettingsDialog:new()
    self.settingsPopup = LM.GUI.PopupDialog(self:Localize('Settings'), false, 0)
    self.settingsPopup:SetDialog(self.dlog)
    layout:AddChild(self.settingsPopup, LM.GUI.ALIGN_LEFT, 0)
	
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	self.twosModeCheckbox = LM.GUI.CheckBox(self:Localize('Twos mode'), self.TWOS_MODE)
    layout:AddChild(self.twosModeCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.keepSelectionCheckbox = LM.GUI.CheckBox(self:Localize('Keep selection'), self.KEEP_SELECTION)
    layout:AddChild(self.keepSelectionCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.multiTransformCheckbox = LM.GUI.CheckBox(self:Localize('Multi transform'), self.MULTI_TRANSFORM)
    layout:AddChild(self.multiTransformCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.lockHandlesCheckbox = LM.GUI.CheckBox(self:Localize('Lock handles'), self.LOCK_HANDLES)
    layout:AddChild(self.lockHandlesCheckbox, LM.GUI.ALIGN_LEFT, 0)

	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	self.bakeAdjacentFramesCheckbox = LM.GUI.CheckBox(self:Localize('Bake Adjacent Frames'), self.BAKE_ADJACENT_FRAMES)
    layout:AddChild(self.bakeAdjacentFramesCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	layout:AddChild(LM.GUI.StaticText(self:Localize("Interval")))

	self.intervalMenu = LM.GUI.Menu(MOHO.Localize("Interval=Interval"))
	self.intervalMenu:AddItem(MOHO.Localize("1=1"), 0, self.INTERVAL_1)
	self.intervalMenu:AddItemAlphabetically(MOHO.Localize("2=2"), 0, self.INTERVAL_2)
	self.intervalMenu:AddItemAlphabetically(MOHO.Localize("3=3"), 0, self.INTERVAL_3)
	self.intervalMenu:AddItemAlphabetically(MOHO.Localize("4=4"), 0, self.INTERVAL_4)

	self.intervalPopup = LM.GUI.PopupMenu(50, true)
	self.intervalPopup:SetMenu(self.intervalMenu)
	layout:AddChild(self.intervalPopup)
	
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	self.showPathCheckbox = LM.GUI.CheckBox(self:Localize('Show path'), self.SHOW_PATH)
    layout:AddChild(self.showPathCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.rangeCheckbox = LM.GUI.CheckBox(self:Localize('Range'), self.RANGE)
    layout:AddChild(self.rangeCheckbox, LM.GUI.ALIGN_LEFT, 0)
	
	self.rangeFramesInput = LM.GUI.TextControl(0, '1000', self.RANGE_FRAMES, LM.GUI.FIELD_INT, self:Localize('Range frames:'))
    layout:AddChild(self.rangeFramesInput, LM.GUI.ALIGN_LEFT, 0)
	
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	layout:AddChild(LM.GUI.ImageButton("ScriptResources/flip_bone_h", self:Localize('End flip'), false, self.FLIP_H, true))
	layout:AddChild(LM.GUI.ImageButton("ScriptResources/flip_bone_v", self:Localize('Side flip'), false, self.FLIP_V, true))
	
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	self.resetText = LM.GUI.DynamicText(self:Localize('Reset:'))
	layout:AddChild(self.resetText, LM.GUI.ALIGN_LEFT, 0)
	
	self.resetAButton = LM.GUI.Button(self:Localize('A'), self.RESET_A)
	self.resetAButton:SetToolTip(self:Localize('Reset angle'))
	layout:AddChild(self.resetAButton, LM.GUI.ALIGN_FILL, 0)
	
	self.resetPButton = LM.GUI.Button(self:Localize('T'), self.RESET_T)
	self.resetPButton:SetToolTip(self:Localize('Reset translation'))
	layout:AddChild(self.resetPButton, LM.GUI.ALIGN_FILL, 0)
	
	self.resetSButton = LM.GUI.Button(self:Localize('S'), self.RESET_S)
	self.resetSButton:SetToolTip(self:Localize('Reset scale'))
	layout:AddChild(self.resetSButton, LM.GUI.ALIGN_FILL, 0)
	
	layout:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
	
	layout:AddChild(LM.GUI.StaticText('v'..MR_PoseTool:Version()))
end

function MR_PoseTool:UpdateWidgets(moho)
	if self.mainCursor == nil then
		self.mainCursor = LM.GUI.Cursor(moho:UserContentDir()..'/Scripts/Tool/mr_pose_tool_cursor', 1, 1)
	end	
	if self.mjCursor == nil then
		self.mjCursor = LM.GUI.Cursor(moho:UserContentDir()..'/Scripts/ScriptResources/mr_pose_tool/mr_mj_cursor', 1, 1)
	end	
	if self.mbCursor == nil then
		self.mbCursor = LM.GUI.Cursor(moho:UserContentDir()..'/Scripts/ScriptResources/mr_pose_tool/mr_mb_cursor', 1, 1)
	end	
	
	self:LoadBonesData(moho.layer)

	self:ValidateFollowList(moho)
	
	self:ValidateLockList(moho)

	if #self.followBonesList.id > 0 or #self.lockPosList > 0 or #self.lockAngleList > 0 then
		local scriptInfo = moho.layer:ScriptData()
		local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
		if scriptInfo:HasKey(bonesDataActiveKey) then
			self.bonesDataActive = scriptInfo:GetBool(bonesDataActiveKey)
		else
			self.bonesDataActive = true
		end
	else
		self.bonesDataActive = true
		local scriptInfo = moho.layer:ScriptData()
		local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
		scriptInfo:Set(bonesDataActiveKey, true)
	end
	
	local frame = moho.frame
	
	if self.blockOnEvenFrames and frame % 2 == 0 or self.blockOnOddFrames and not (frame % 2 == 0) and self.twosMode then
		moho.view:SetCursor(MOHO.disabledCursor)
	else
		moho.view:SetCursor(self.mainCursor)
	end

	self.twosModeCheckbox:SetValue(self.twosMode)
	self.keepSelectionCheckbox:SetValue(self.keepSelection)
	self.multiTransformCheckbox:SetValue(self.multiTransform)
	self.multiTransformCheckbox:Enable(self.keepSelection)
	self.lockHandlesCheckbox:SetValue(self.lockHandles)
	self.bakeAdjacentFramesCheckbox:SetValue(self.bakeAdjacentFrames)
	if self.interval < 1 or self.interval > 4 or self.interval == nil then
		self.interval = 1
	end
	
	self.intervalMenu:SetChecked(self.INTERVAL_1, false)
	self.intervalMenu:SetChecked(self.INTERVAL_2, false)
	self.intervalMenu:SetChecked(self.INTERVAL_3, false)
	self.intervalMenu:SetChecked(self.INTERVAL_4, false)
	if (self.interval == 1) then
		self.intervalMenu:SetChecked(self.INTERVAL_1, true)
	elseif (self.interval == 2) then
		self.intervalMenu:SetChecked(self.INTERVAL_2, true)
	elseif (self.interval == 3) then
		self.intervalMenu:SetChecked(self.INTERVAL_3, true)
	elseif (self.interval == 4) then
		self.intervalMenu:SetChecked(self.INTERVAL_4, true)
	end
	self.intervalPopup:Enable(self.bakeAdjacentFrames)
	self.intervalPopup:Redraw()
	self.showPathCheckbox:SetValue(self.showPath)
	self.rangeCheckbox:SetValue(self.range)
	self.rangeFramesInput:SetValue(self.rangeFrames)
	self.rangeCheckbox:Enable(self.showPath)
	self.rangeFramesInput:Enable(self.range and self.showPath)
end

function MR_PoseTool:HandleMessage(moho, view, msg)
	if msg == self.TWOS_MODE then
        self.twosMode = self.twosModeCheckbox:Value()
	elseif msg == self.KEEP_SELECTION then
        self.keepSelection = self.keepSelectionCheckbox:Value()
		self.multiTransformCheckbox:Enable(self.keepSelection)
	elseif msg == self.MULTI_TRANSFORM then
        self.multiTransform = self.multiTransformCheckbox:Value()
	elseif msg == self.LOCK_HANDLES then
        self.lockHandles = self.lockHandlesCheckbox:Value()
	elseif msg == self.BAKE_ADJACENT_FRAMES then
		self.bakeAdjacentFrames = self.bakeAdjacentFramesCheckbox:Value()
		self.intervalPopup:Enable(self.bakeAdjacentFrames)
	elseif (msg >= self.INTERVAL_1 and msg <= self.INTERVAL_4) then
		local int = 1
		if (msg == self.INTERVAL_1) then
			int = 1
		elseif (msg == self.INTERVAL_2) then
			int = 2
		elseif (msg == self.INTERVAL_3) then
			int = 3
		elseif (msg == self.INTERVAL_4) then
			int = 4
		end	
		self.interval = int
		self:UpdateWidgets(moho)
	elseif msg == self.SHOW_PATH then
        self.showPath = self.showPathCheckbox:Value()
		self.rangeCheckbox:Enable(self.showPath)
		self.rangeFramesInput:Enable(self.range and self.showPath)
	elseif msg == self.RANGE then
        self.range = self.rangeCheckbox:Value()	
		self.rangeCheckbox:Enable(self.showPath)
		self.rangeFramesInput:Enable(self.range and self.showPath)
	elseif msg == self.RANGE_FRAMES then
        self.rangeFrames = LM.Clamp(self.rangeFramesInput:Value(), 1, 1000)	
		self.rangeFramesInput:SetValue(self.rangeFrames)
	elseif (msg == self.FLIP_H) then
		self:FlipBones(moho, true)
	elseif (msg == self.FLIP_V) then
		self:FlipBones(moho, false)
	elseif (msg == self.RESET_A) then
		local skel = moho:Skeleton()
		if skel then
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fAnimAngle:SetValue(moho.layerFrame, bone.fAnimAngle:GetValue(0))
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE)
				self:UpdateWidgets(moho)
			end
		end
	elseif (msg == self.RESET_T) then
		local skel = moho:Skeleton()
		if skel then
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fAnimPos:SetValue(moho.layerFrame, bone.fAnimPos:GetValue(0))
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE_T)
				self:UpdateWidgets(moho)
			end
		end
	elseif (msg == self.RESET_S) then
		local skel = moho:Skeleton()
		if skel then
			if (moho:CountSelectedBones(true) > 0) then
				moho.document:PrepUndo(moho.layer, true)
				moho.document:SetDirty()
				for i = 0, skel:CountBones() - 1 do
					local bone = skel:Bone(i)
					if (bone.fSelected) then
						bone.fAnimScale:SetValue(moho.layerFrame, bone.fAnimScale:GetValue(0))
					end
				end
				moho.layer:UpdateCurFrame()
				moho:NewKeyframe(CHANNEL_BONE_S)
				self:UpdateWidgets(moho)
			end
		end
	end	
end

function MR_PoseTool:CheckBone(moho, id)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return false
	end
	if id < 0 or not id then
		return false
	end
	local secondBone = skel:Bone(id)
	if secondBone then
		if secondBone.fParent > -1 and not secondBone:IsZeroLength() and not secondBone.fFixedAngle then
			local firstBoneID = secondBone.fParent
			local firstBone = skel:Bone(firstBoneID)
			local firstBoneChilds = skel:CountBoneChildren(firstBoneID, true)
			local secondBonePos = LM.Vector2:new_local()
			secondBonePos:Set(secondBone.fAnimPos:GetValue(moho.layerFrame))
			if firstBone.fIgnoredByIK == false and secondBone.fIgnoredByIK == false and firstBoneChilds == 1 and MR_Utilities:Round(secondBone.fPos.y) == 0 
			and not MR_Utilities:IsEqual(secondBonePos.x, 0, 0.0001) and not firstBone:IsZeroLength() and not firstBone.fFixedAngle then
				return true
			end
		end
	end	
	return false
end

function MR_PoseTool:TestMousePoint(moho, mouseEvent, id)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return 1
	end

	local markerR = self.markerR
	if self.additionHandles then
		markerR = self.markerR2
	end
	
	local v = LM.Vector2:new_local()
	local pt = LM.Point:new_local()
	local m = LM.Matrix:new_local()
	local center = LM.Vector2:new_local()
	local tip = LM.Vector2:new_local()
	local offset = LM.Vector2:new_local()
	local boneCenterPos = LM.Vector2:new_local()
	local boneHandlePos = LM.Vector2:new_local()
	local localV = LM.Vector2:new_local()
	local angle = 0
	local newAngle = 0
	local offsetAngle = 0
	local alignHandlesAdaptation = false
	local handlesZoomAdaptationVal = 1
	
	moho.layer:GetFullTransform(moho.frame, m, moho.document)
	local g = mouseEvent.view:Graphics()
	g:Push()
	g:ApplyMatrix(m)
	local height = g:Height() / moho.document:Height()
	height = g:Height() / self.height
	local markerMultiplier = 0.002

	local additionMarker1 = self.additionHandles
	local currentScale = g:CurrentScale(false)
	g:Pop()
	
	self.keepHandles = mouseEvent.ctrlKey

	local handlesDistance = self.handlesDistance
	if self.alignHandlesAlongBone then
		handlesDistance = 1
	end

	if self.mousePickedID > -1 then
		local bone = skel:Bone(self.mousePickedID)
		if bone ~= nil then
			if not bone.fHidden and bone:IsGroupVisible() then
				v:Set(bone.fLength * self.handlesDist, 0)
				bone.fMovedMatrix:Transform(v)
				
				if self.alignHandlesAlongBone then
					v:Set(bone.fLength - bone.fLength, 0)
					bone.fMovedMatrix:Transform(v)
				
					boneCenterPos:Set(bone.fLength - bone.fLength / 2, 0)
					bone.fMovedMatrix:Transform(boneCenterPos)
					
					center:Set(0, 0)
					tip:Set(1, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					
					offset:Set(v.x, v.y)
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					angle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, angle))
					
					offset:Set(v.x - ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					boneHandlePos:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					
					local layerMatrixNoCam = LM.Matrix:new_local()
					moho.layer:GetFullTransform(moho.frame, layerMatrixNoCam, nil)
					
					layerMatrixNoCam:Transform(boneHandlePos)
					
					local globalBoneCenterPos = LM.Vector2:new_local()
					globalBoneCenterPos:Set(boneCenterPos)
					layerMatrixNoCam:Transform(globalBoneCenterPos)
					
					if MR_Utilities:GetDistance(globalBoneCenterPos, boneHandlePos) * currentScale * height < 0.065 then
						alignHandlesAdaptation = true
					end
					
					v:Set(bone.fLength * self.handlesDist, 0)
					bone.fMovedMatrix:Transform(v)
					
					local distanceValue = MR_Utilities:GetDistance(center, v) * currentScale * height
					
					if distanceValue > self.handlesDistanceTreshhold then
						handlesZoomAdaptationVal = distanceValue / self.handlesDistanceTreshhold
					end
				else
					v:Set(bone.fLength * self.handlesDist, 0)
					bone.fMovedMatrix:Transform(v)
					center:Set(0, 0)
					bone.fMovedMatrix:Transform(center)
					local distanceValue = MR_Utilities:GetDistance(center, v) * currentScale * height
					
					if distanceValue > self.handlesDistanceTreshhold then
						handlesZoomAdaptationVal = distanceValue / self.handlesDistanceTreshhold
					end
				end
				
				v:Set(bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
				bone.fMovedMatrix:Transform(v)
				
				if additionMarker1 then
					center:Set(0, 0)
					tip:Set(1, 0)
					bone.fMovedMatrix:Transform(center)
					bone.fMovedMatrix:Transform(tip)
					if self.alignHandlesAlongBone then
						offset:Set(v.x, v.y)
						if alignHandlesAdaptation then
							offset:Set(boneCenterPos.x - (((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height) * 1.5), boneCenterPos.y)
						end
					else
						offset:Set(v.x, v.y - ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					if alignHandlesAdaptation then
						v:Set(MR_Utilities:RotateVector2(offset, boneCenterPos, newAngle))
					else
						v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					end
				end
				
				localV:Set(v)
				m:Transform(v)
				
				mouseEvent.view:Graphics():WorldToScreen(v, pt)
				if (math.abs(pt.x - mouseEvent.pt.x) < markerR and math.abs(pt.y - mouseEvent.pt.y) < markerR) then
					return 0
				end
				
				if additionMarker1 then	
					if self.alignHandlesAlongBone then
						v:Set(localV)
						offset:Set(v.x + ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					else
						v:Set(bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
						bone.fMovedMatrix:Transform(v)
						offset:Set(v.x, v.y + ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
				
					local testPos = LM.Vector2:new_local()
					testPos:Set(v)
					local layerMatrixNoCam = LM.Matrix:new_local()
					moho.layer:GetFullTransform(moho.frame, layerMatrixNoCam, nil)
					layerMatrixNoCam:Transform(testPos)
					
					m:Transform(v)
					mouseEvent.view:Graphics():WorldToScreen(v, pt)
					if (math.abs(pt.x - mouseEvent.pt.x) < markerR and math.abs(pt.y - mouseEvent.pt.y) < markerR) then
						return 3
					end
				end
			end	

			if not bone.fHidden and bone:IsGroupVisible() then
				v:Set(bone.fLength - bone.fLength * (self.handlesDist / handlesZoomAdaptationVal), 0)
				bone.fMovedMatrix:Transform(v)
				
				if additionMarker1 then
					if self.alignHandlesAlongBone then
						offset:Set(v.x, v.y)
						if alignHandlesAdaptation then
							offset:Set(boneCenterPos.x + (((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height) * 1.5), boneCenterPos.y)
						end
					else
						offset:Set(v.x, v.y - ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					angle = math.atan2(tip.y - center.y, tip.x - center.x)
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)

					if alignHandlesAdaptation then
						v:Set(MR_Utilities:RotateVector2(offset, boneCenterPos, newAngle))
					else
						v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					end
				end
				
				localV:Set(v)
				
				m:Transform(v)
				mouseEvent.view:Graphics():WorldToScreen(v, pt)
				if bone:IsZeroLength() and mouseEvent.ctrlKey then
					if (math.abs(pt.x - mouseEvent.pt.x) < markerR * 3 and math.abs(pt.y - mouseEvent.pt.y) < markerR * 3) then
						return 2
					end
				else
					if (self.ignoreZeroScaledBones and MR_Utilities:Round(bone.fAnimScale:GetValue(0), 1) == 1) or not self.ignoreZeroScaledBones then
						if (math.abs(pt.x - mouseEvent.pt.x) < markerR and math.abs(pt.y - mouseEvent.pt.y) < markerR) then
							return 2
						end
					end	
				end	
				
				if additionMarker1 then
					if self.alignHandlesAlongBone then
						v:Set(localV)
						offset:Set(v.x  - ((markerR * markerMultiplier * 2 * handlesDistance) / currentScale / height), v.y)
					else
						v:Set(bone.fLength - (bone.fLength * (self.handlesDist / handlesZoomAdaptationVal)), 0)
						bone.fMovedMatrix:Transform(v)
						offset:Set(v.x, v.y + ((markerR * markerMultiplier * handlesDistance) / currentScale / height))
					end
					offsetAngle = math.atan2(offset.y - center.y, offset.x - center.x)
					newAngle = offsetAngle + (angle - offsetAngle)
					v:Set(MR_Utilities:RotateVector2(offset, v, newAngle))
					m:Transform(v)

					mouseEvent.view:Graphics():WorldToScreen(v, pt)
					if (math.abs(pt.x - mouseEvent.pt.x) < markerR and math.abs(pt.y - mouseEvent.pt.y) < markerR) then
						return 4
					end
				end
			end
		end
	end

	if id then
		if id > -1 and self.showPath then
			local bone = skel:Bone(id)
			if bone ~= nil then
				local channelPos = bone.fAnimPos
				local translationWhen = -20000
				local g = mouseEvent.view:Graphics()
				local m = LM.Matrix:new_local()
				local vec = LM.Vector2:new_local()
				local pt = LM.Point:new_local()
				local totalTimingOffset = moho.layer:TotalTimingOffset()
				moho.layer:GetFullTransform(moho.frame, m, moho.document)
				-- First see if any keyframes were picked
				for i = 0, bone.fAnimPos:CountKeys() - 1 do
					local frame = bone.fAnimPos:GetKeyWhen(i)
					if frame > 0 then
						vec = bone.fAnimPos:GetValue(frame)
						m:Transform(vec)
						g:WorldToScreen(vec, pt)
						if (math.abs(pt.x - mouseEvent.pt.x) < self.TOLERANCE and math.abs(pt.y - mouseEvent.pt.y) < self.TOLERANCE) then
							translationWhen = frame
							self.trPathBone = bone
							break
						end
					end	
				end
				-- If no keyframes were picked, try picking a random point along the curve.
				if (translationWhen <= -10000) then
					local startFrame = channelPos:GetKeyWhen(0)
					local channelDuration = channelPos:Duration()
					local endFrame = channelDuration
					if self.range then
						startFrame = LM.Clamp(moho.layerFrame - self.rangeFrames, 1, channelDuration)
						endFrame = LM.Clamp(moho.layerFrame + self.rangeFrames, 1, channelDuration)
					end
					if (endFrame > startFrame) then
						local oldVec = LM.Vector2:new_local()
						g:Clear(0, 0, 0, 0)
						g:SetColor(255, 255, 255)
						g:BeginPicking(mouseEvent.pt, 4)
						for frame = startFrame, endFrame do
							vec = channelPos:GetValue(frame)
							m:Transform(vec)
							if (frame > startFrame) then
								g:DrawLine(oldVec.x, oldVec.y, vec.x, vec.y)
							end
							if (g:Pick()) then
								translationWhen = frame
								self.trPathBone = bone
								break
							end
							oldVec:Set(vec)
						end
					end
				end
				if (translationWhen > -10000) then
					self.translationFrame = translationWhen
					return 5
				end
			end	
		end
	end
	return 1
end

function MR_PoseTool:FlipBones(moho, horizontal)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return 1
	end
	
	if (moho:CountSelectedBones(true) < 1) then
		return
	end

	moho.document:PrepUndo(moho.layer, true)
	moho.document:SetDirty()
	for i = 0, skel:CountBones() - 1 do
		local bone = skel:Bone(i)
		if (bone.fSelected) then
			if (horizontal) then
				bone.fFlipH:SetValue(moho.layerFrame, not bone.fFlipH.value)
			else
				bone.fFlipV:SetValue(moho.layerFrame, not bone.fFlipV.value)
			end
		end
	end
	moho.layer:UpdateCurFrame()
	if (horizontal) then
		moho:NewKeyframe(CHANNEL_BONE_FLIPH)
	else
		moho:NewKeyframe(CHANNEL_BONE_FLIPV)
	end
end

function MR_PoseTool:BakeFrames(moho, secondBone, firstBone, angle, pos, scale)
	if moho.layerFrame - self.interval > 0 then
		if firstBone then
			if angle and self.boneFAngleP then
				firstBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.boneFAngleP)
			end	
			if pos and self.boneFPosP then
				local channel = firstBone.fAnimPos
				if channel:AreDimensionsSplit() then
					local channelX = channel:DimensionChannel(0)
					local channelY = channel:DimensionChannel(1)
					channelX:SetValue(moho.layerFrame - self.interval, self.boneFPosP.x)
					channelY:SetValue(moho.layerFrame - self.interval, self.boneFPosP.y)
				else
					firstBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.boneFPosP)
				end	
			end	
			if scale and self.boneFScaleP then
				firstBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.boneFScaleP)
			end	
		end
		if secondBone then
			if angle and self.boneSAngleP then
				secondBone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.boneSAngleP)
			end
			if pos and self.boneSPosP then
				local channel = secondBone.fAnimPos
				if channel:AreDimensionsSplit() then
					local channelX = channel:DimensionChannel(0)
					local channelY = channel:DimensionChannel(1)
					channelX:SetValue(moho.layerFrame - self.interval, self.boneSPosP.x)
					channelY:SetValue(moho.layerFrame - self.interval, self.boneSPosP.y)
				else
					secondBone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.boneSPosP)
				end
			end	
			if scale and self.boneSScaleP then
				secondBone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.boneSScaleP)
			end	
		end	
	end
	if moho.layerFrame + self.interval > 0 then
		if firstBone then
			if angle and self.boneFAngleN then
				firstBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.boneFAngleN)
			end	
			if pos and self.boneFPosN then
				local channel = firstBone.fAnimPos
				if channel:AreDimensionsSplit() then
					local channelX = channel:DimensionChannel(0)
					local channelY = channel:DimensionChannel(1)
					channelX:SetValue(moho.layerFrame + self.interval, self.boneFPosN.x)
					channelY:SetValue(moho.layerFrame + self.interval, self.boneFPosN.y)
				else
					firstBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.boneFPosN)
				end
			end
			if scale and self.boneFScaleN then
				firstBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.boneFScaleN)
			end	
		end
		if secondBone then
			if angle and self.boneSAngleN then
				secondBone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.boneSAngleN)
			end
			if pos and self.boneSPosN then
				local channel = secondBone.fAnimPos
				if channel:AreDimensionsSplit() then
					local channelX = channel:DimensionChannel(0)
					local channelY = channel:DimensionChannel(1)
					channelX:SetValue(moho.layerFrame + self.interval, self.boneSPosN.x)
					channelY:SetValue(moho.layerFrame + self.interval, self.boneSPosN.y)
				else
					secondBone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.boneSPosN)
				end	
			end	
			if scale and self.boneSScaleN then
				secondBone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.boneSScaleN)
			end	
		end	
	end
end

function MR_PoseTool:CountBoneChildren(skel, boneID, ignoreControlledBones)
	local n = 0
	for i = 0, skel:CountBones() - 1 do
		local bone = skel:Bone(i)
		if (bone.fParent == boneID) then
			n = n + 1
			if (ignoreControlledBones) then
				if self.mohoVersion >= 14 then
					if (bone.fAngleControlParent >= 0 or bone.fPosControlParent >= 0 or bone.fScaleControlParent >= 0 
					or (bone.fBoneDynamics.value and (bone.fAngleDynamics or bone.fPosDynamics or bone.fScaleDynamics)) or bone.fIgnoredByIK) then
						n = n - 1 -- ignore this bone, as it is not free to move by itself
					end
				else
					if (bone.fAngleControlParent >= 0 or bone.fPosControlParent >= 0 or bone.fScaleControlParent >= 0 or bone.fBoneDynamics.value or bone.fIgnoredByIK) then
						n = n - 1 -- ignore this bone, as it is not free to move by itself
					end
				end
			end
		end
	end
	return n
end

function MR_PoseTool:AddToFollowBonesChains(moho)
	local skel = moho:Skeleton()
	
	if skel == nil then
		return
	end

	local selectedBonesId = {}
	local selectedBonesNames = {}
	local isValid = true
	
	local scriptInfo = moho.layer:ScriptData()
	self.bonesDataActive = true
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
	
	self:LoadBonesData(moho.layer)
	self:ValidateFollowList(moho)
	
	local selectedBonesList = {}
	
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected and not bone:IsZeroLength() then
			table.insert(selectedBonesList, i)
		end
	end
	
	local followBonesChainsList = {}
	local boneParentMap = {}
	local multipleChildrenMap = {}
	local isInGroup = {}
	local selectedBonesSet = {}

	for _, id in ipairs(selectedBonesList) do
		selectedBonesSet[id] = true
	end

	for _, id in ipairs(selectedBonesList) do
		local bone = skel:Bone(id)
		local count = 0
		
		for _, childId in ipairs(selectedBonesList) do
			local childBone = skel:Bone(childId)
			if childBone then
				if childBone.fParent == id then
					count = count + 1
				end
			end
		end
		
		if count > 1 then
			multipleChildrenMap[id] = true
		end
		
		boneParentMap[id] = bone.fParent
	end
		for n, id in ipairs(multipleChildrenMap) do
			local bone = skel:Bone(id)
		end
	local function collectAncestors(boneId, group)
		local parentId = boneParentMap[boneId]
		while parentId and parentId ~= -1 and selectedBonesSet[parentId] and not isInGroup[parentId] do
			if not multipleChildrenMap[parentId] then
				table.insert(group, 1, parentId) 
				isInGroup[parentId] = true
			end
			parentId = boneParentMap[parentId]
		end
	end

	local function addDescendants(boneId, group)
		for _, childId in ipairs(selectedBonesList) do
			if boneParentMap[childId] == boneId and not isInGroup[childId] then
				if not multipleChildrenMap[boneId] then
					table.insert(group, childId)
					isInGroup[childId] = true
					addDescendants(childId, group)
				end
			end
		end
	end

	for _, boneId in ipairs(selectedBonesList) do
		if not isInGroup[boneId] then
			local group = {}

			collectAncestors(boneId, group)

			if not isInGroup[boneId] then
				table.insert(group, boneId)
				isInGroup[boneId] = true

				addDescendants(boneId, group)
			end

			if #group > 0 then
				table.insert(followBonesChainsList, group)
			end
		end
	end
	
	local followBonesChainsNamesList = {}
	
	for i, a in ipairs(followBonesChainsList) do
		local followBonesNamesList = {}
		for n, id in ipairs(followBonesChainsList[i]) do
			local bone = skel:Bone(id)
			table.insert(followBonesNamesList, bone:Name())
		end
		table.insert(followBonesChainsNamesList, followBonesNamesList)
	end
	self:RemoveSelectedBonesFromFollowList(moho)
	for c, a in ipairs(followBonesChainsList) do
		local startBone = followBonesChainsList[c][1]
		local endBone = followBonesChainsList[c][#followBonesChainsList[c]]
		
		table.insert(self.followBonesList.id, followBonesChainsList[c])
		table.insert(self.followBonesList.names, followBonesChainsNamesList[c])
		table.insert(self.followBonesList.startBone, startBone)
		table.insert(self.followBonesList.endBone, endBone)

		for _, id in ipairs(followBonesChainsList[c]) do
			local boneID = id
			local existInList = self:ValueExists(self.lockAngleList, boneID)
			if existInList then
				table.remove(self.lockAngleList, existInList)
				table.remove(self.lockAngleBoneNamesList, existInList)
			end
			existInList = self:ValueExists(self.lockPosList, boneID)
			if existInList then
				table.remove(self.lockPosList, existInList)
				table.remove(self.lockPosBoneNamesList, existInList)
			end
		end
	end

	self.forceFollowBonesGraphics = true
	
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:AddToFollowBones(moho)
	local skel = moho:Skeleton()
	
	if skel == nil then
		return
	end
	
	local scriptInfo = moho.layer:ScriptData()
	self.bonesDataActive = true
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
	
	self:LoadBonesData(moho.layer)
	self:ValidateFollowList(moho)
	
	self:RemoveSelectedBonesFromFollowList(moho)
	for i=0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected and not bone:IsZeroLength() then
			local followBonesIdList = {}
			table.insert(followBonesIdList, i)
			table.insert(self.followBonesList.id, followBonesIdList)
			
			local followBonesNameList = {}
			table.insert(followBonesNameList, bone:Name())
			table.insert(self.followBonesList.names, followBonesNameList)
		
			table.insert(self.followBonesList.startBone, i)
			table.insert(self.followBonesList.endBone, i)
			
			for _, id in ipairs(followBonesIdList) do
				local boneID = id
				local existInList = self:ValueExists(self.lockAngleList, boneID)
				if existInList then
					table.remove(self.lockAngleList, existInList)
					table.remove(self.lockAngleBoneNamesList, existInList)
				end
				existInList = self:ValueExists(self.lockPosList, boneID)
				if existInList then
					table.remove(self.lockPosList, existInList)
					table.remove(self.lockPosBoneNamesList, existInList)
				end
			end
		end
	end
	
	self.forceFollowBonesGraphics = true
	
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:AdjustFollowBones(moho, index)
	if not self.followBonesList.id or #self.followBonesList.id < 1 then
		return
	end

	local b = index
	local endFollowBoneId = self.followBonesList.endBone[b]
	
	if self.ignoreBonesList[endFollowBoneId + 1] == true then
		return
	end
	
	local skel = moho:Skeleton()
	
	if skel == nil then
		return
	end
	
	
	if self.followBonesDataList.block[b] then
		return
	end
	
	local startFollowBone = skel:Bone(self.followBonesList.startBone[b])
	local endFollowBone = skel:Bone(self.followBonesList.endBone[b])
	if not startFollowBone or not endFollowBone then
		return
	end
	
	moho.layer:UpdateCurFrame()

	local startBonePos = LM.Vector2:new_local()	
	startBonePos:Set(0, 0)
	
	if moho.frame == 0 then
		startFollowBone.fRestMatrix:Transform(startBonePos)
	else
		startFollowBone.fMovedMatrix:Transform(startBonePos)
	end

	if self.scaleFollowBones then
		local secondCursorDist = MR_Utilities:GetDistance(startBonePos, self.followBonesDataList.targetPos[b])
		local scaleFactor = (secondCursorDist / self.followBonesDataList.distance[b])
		
		for i=1, #self.followBonesList.id[b] do
			local bone = skel:Bone(self.followBonesList.id[b][i])
			local newScale = (bone.fTempScale * scaleFactor) - self.followBonesDataList.scaleDelta[b][i]
			bone.fAnimScale:SetValue(moho.layerFrame, newScale)
		end
		
		if self.bakeAdjacentFrames and not self.followBonesDataList.sBValuesBakedS[b] then
			for i, q in ipairs(self.followBonesList.id[b]) do
				local bone = skel:Bone(q)
				if moho.layerFrame - self.interval > 0 then
					bone.fAnimScale:SetValue(moho.layerFrame - self.interval, self.followBonesDataList.sBValuesP[b][i])
				end
				if moho.layerFrame + self.interval > 0 then
					bone.fAnimScale:SetValue(moho.layerFrame + self.interval, self.followBonesDataList.sBValuesN[b][i])
				end
			end	
			self.followBonesDataList.sBValuesBakedS[b] = true
		end
	end
	local bone = startFollowBone
	local center = LM.Vector2:new_local()

	center:Set(self.followBonesDataList.targetPos[b])
	local angle = self.followBonesDataList.startAngle[b]
	local v1 = self.followBonesDataList.lastVec[b] - center
	local v2 = startBonePos - center
	v2:Rotate(-math.atan2(v1.y, v1.x))
	angle = angle + math.atan2(v2.y, v2.x)
	self.followBonesDataList.startAngle[b] = angle
	self.followBonesDataList.lastVec[b] = startBonePos
	local angleSign = 1.0
	if (not bone.fFixedAngle) then
		angleSign = bone:ParentalFlipFactor()
	end

	local parentAngle = 0

	if startFollowBone.fParent > -1 then
		local parentBone = skel:Bone(startFollowBone.fParent)
		local startParentBonePos = LM.Vector2:new_local()	
		local startParentBoneTipPos = LM.Vector2:new_local()	
		startParentBonePos:Set(0, 0)
		
		if parentBone:IsZeroLength() then
			startParentBoneTipPos:Set(0.1, 0)
		else
			startParentBoneTipPos:Set(parentBone.fLength, 0)
		end
		if moho.frame == 0 then
			parentBone.fRestMatrix:Transform(startParentBonePos)
			parentBone.fRestMatrix:Transform(startParentBoneTipPos)
		else
			parentBone.fMovedMatrix:Transform(startParentBonePos)
			parentBone.fMovedMatrix:Transform(startParentBoneTipPos)
		end
		
		local basePosDelta = startParentBonePos - self.followBonesDataList.lastParentBaseVec[b]
		startParentBonePos = startParentBonePos - basePosDelta
		startParentBoneTipPos = startParentBoneTipPos - basePosDelta
		parentAngle = self.followBonesDataList.parentStartAngle[b]
		local v1 = self.followBonesDataList.lastParentTipVec[b] - startParentBonePos
		local v2 = startParentBoneTipPos - startParentBonePos
		v2:Rotate(-math.atan2(v1.y, v1.x))
		parentAngle = parentAngle + math.atan2(v2.y, v2.x)
		self.followBonesDataList.parentStartAngle[b] = parentAngle
		self.followBonesDataList.lastParentTipVec[b] = startParentBoneTipPos
	end

	local newAgle = (bone.fTempAngle + (angle * angleSign)) - (parentAngle * angleSign)

	if not bone.fFixedAngle then
		if bone.fConstraints then
			local min = bone.fAnimAngle:GetValue(0) - self.followBonesDataList.angleDelta[b]
			local max = min + bone.fMaxConstraint
			min = min + bone.fMinConstraint
			newAgle = LM.Clamp(newAgle, min, max)
		end
	end
	
	if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
		bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
		if self.bakeAdjacentFrames and not self.followBonesDataList.bakedA[b] then
			if moho.layerFrame - self.interval > 0 then
				bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.followBonesDataList.FAngleP[b])
			end
			if moho.layerFrame + self.interval > 0 then
				bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.followBonesDataList.FAngleN[b])
			end
			self.followBonesDataList.bakedA[b] = true
		end
	end
end

function MR_PoseTool:AdjustLockPos(moho, index)
	if not self.lockPosList or #self.lockPosList < 1 then
		return
	end
	
	local i = index
	local lockPosId = self.lockPosList[i]

	if self.ignoreBonesList[lockPosId + 1] == true then
		return
	end
	
	local skel = moho:Skeleton()
	if skel == nil then
		return
	end
	
	moho.layer:UpdateCurFrame()

	local bone = skel:Bone(self.lockPosList[i])
	if bone then
		if not bone.fSelected then
			local newPos 
			if bone.fParent >-1 then
				local matrix = LM.Matrix:new_local()
				local bonePos = LM.Vector2:new_local()
				bonePos:Set(self.lockedBonesPos[i])
				if moho.frame == 0 then
					matrix:Set(skel:Bone(bone.fParent).fRestMatrix)
				else
					matrix:Set(skel:Bone(bone.fParent).fMovedMatrix)
				end
				matrix:Invert()
				matrix:Transform(bonePos)
				newPos = bonePos - self.lockedBonesDeltaPos[i]
			else
				newPos = self.lockedBonesPos[i] - self.lockedBonesDeltaPos[i]
			end
			local originalPosVal = bone.fAnimPos:GetValue(moho.layerFrame)
			if not MR_Utilities:IsEqual(newPos.x, originalPosVal.x, 0.000001) or not MR_Utilities:IsEqual(newPos.y, originalPosVal.y, 0.000001) then
				bone.fAnimPos:SetValue(moho.layerFrame, newPos)
				if self.bakeAdjacentFrames and not self.lockPosBaked[i] then
					if moho.layerFrame - self.interval > 0 then
						bone.fAnimPos:SetValue(moho.layerFrame - self.interval, self.lockedBonesSBPosValuesP[i])
					end
					if moho.layerFrame + self.interval > 0 then
						bone.fAnimPos:SetValue(moho.layerFrame + self.interval, self.lockedBonesSBPosValuesN[i])
					end
					self.lockPosBaked[i] = true
				end
			end	
		end
	end
	moho.layer:UpdateCurFrame()
end

function MR_PoseTool:AdjustLockAngles(moho, index)
	if not self.lockAngleList or #self.lockAngleList < 1 then
		return
	end
	
	local i = index
	local lockAngleId = self.lockAngleList[i]

	if self.ignoreBonesList[lockAngleId + 1] == true then
		return
	end
	
	local skel = moho:Skeleton()
	if skel == nil then
		return
	end
	
	moho.layer:UpdateCurFrame()
	local bone = skel:Bone(self.lockAngleList[i])
	if bone then
		if not bone.fSelected and not bone.fFixedAngle then
			local parentAngle = 0
			if bone.fParent > -1 then
				local parentBone = skel:Bone(bone.fParent)
				local parentBonePos = LM.Vector2:new_local()	
				local parentBoneTipPos = LM.Vector2:new_local()	
				parentBonePos:Set(0, 0)
				
				if parentBone:IsZeroLength() then
					parentBoneTipPos:Set(0.1, 0)
				else
					if bone:IsZeroLength() then
						parentBoneTipPos:Set(0.1, 0)
					else
						parentBoneTipPos:Set(bone.fLength, 0)
					end
				end
				if moho.frame == 0 then
					parentBone.fRestMatrix:Transform(parentBonePos)
					parentBone.fRestMatrix:Transform(parentBoneTipPos)
				else
					parentBone.fMovedMatrix:Transform(parentBonePos)
					parentBone.fMovedMatrix:Transform(parentBoneTipPos)
				end
				local basePosDelta = parentBonePos - self.lockBonesLastParentBaseVec[i]
				parentBonePos = parentBonePos - basePosDelta
				parentBoneTipPos = parentBoneTipPos - basePosDelta
				parentAngle = self.lockBonesParentStartAngle[i]
				local v1 = self.lockBonesLastParentTipVec[i] - parentBonePos
				local v2 = parentBoneTipPos - parentBonePos
				v2:Rotate(-math.atan2(v1.y, v1.x))
				parentAngle = parentAngle + math.atan2(v2.y, v2.x)
				self.lockBonesParentStartAngle[i] = parentAngle
				self.lockBonesLastParentTipVec[i] = parentBoneTipPos
			end
			
			local angleSign = 1.0
			if (not bone.fFixedAngle) then
				angleSign = bone:ParentalFlipFactor()
			end
			
			local newAgle = (bone.fTempAngle - parentAngle * angleSign)
			if not bone.fFixedAngle then
				if bone.fConstraints then
					local min = bone.fAnimAngle:GetValue(0)
					local max = min + bone.fMaxConstraint
					min = min + bone.fMinConstraint
					newAgle = LM.Clamp(newAgle, min, max)
				end
			end

			if not MR_Utilities:IsEqual(newAgle, bone.fAnimAngle:GetValue(moho.layerFrame), 0.000001) then
				bone.fAnimAngle:SetValue(moho.layerFrame, newAgle)
				if self.bakeAdjacentFrames and not self.lockAngleBaked[i] then
					if moho.layerFrame - self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame - self.interval, self.lockedBonesSBAngleValuesP[i])
					end
					if moho.layerFrame + self.interval > 0 then
						bone.fAnimAngle:SetValue(moho.layerFrame + self.interval, self.lockedBonesSBAngleValuesN[i])
					end
					self.lockAngleBaked[i] = true
				end
			end	
		end
	end
	moho.layer:UpdateCurFrame()
end

function MR_PoseTool:TestMousePointGraphicMenu(moho, mouseEvent)
	local skel = moho:Skeleton()
	if (skel == nil) then
		return
	end
	local v = LM.Vector2:new_local()
	local pt = LM.Point:new_local()
	local m = LM.Matrix:new_local()
	local localV = LM.Vector2:new_local()
	
	local g = mouseEvent.view:Graphics()
	g:Push()

	local height = g:Height() / moho.document:Height()
	height = g:Height() / self.height

	local currentScale = g:CurrentScale(false)
	g:Pop()
	
	local offset = self.iconsDistance / currentScale / height
	local center = LM.Vector2:new_local()
	center:Set(self.graphicsMenuCenter)

	local radius = self.iconsRadius
	local shadowOffset = LM.Vector2:new_local()
	shadowOffset:Set(0.005 / currentScale / height, -0.01 / currentScale / height)
	local v = LM.Vector2:new_local()
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(30)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 1 -- set follow bones icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(90)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 2 -- scale follow bones icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-30)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 3 -- lock angle icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(-90)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 4 -- lock pos icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(210)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 5 -- clear pos icon
	end
	
	v:Set(center.x, center.y + offset)
	v:Set(MR_Utilities:RotateVector2(v, center, math.rad(150)))

	mouseEvent.view:Graphics():WorldToScreen(v, pt)
	if (math.abs(pt.x - mouseEvent.pt.x) < radius and math.abs(pt.y - mouseEvent.pt.y) < radius) then
		return 6 -- clear pos icon
	end
	return 0
end

function MR_PoseTool:AddToLockAngleList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	
	local scriptInfo = moho.layer:ScriptData()
	self.bonesDataActive = true
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
	
	self:LoadBonesData(moho.layer)
	self:RemoveSelectedBonesFromFollowList(moho)
	
	self:ValidateLockList(moho)
	for i = 0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected then
			local existInList = self:ValueExists(self.lockAngleList, i)
			if not existInList then
				table.insert(self.lockAngleList, i)
				table.insert(self.lockAngleBoneNamesList, bone:Name())
			else
				table.remove(self.lockAngleList, existInList)
				table.remove(self.lockAngleBoneNamesList, existInList)
			end
		end
	end
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:AddToLockPosList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	
	local scriptInfo = moho.layer:ScriptData()
	self.bonesDataActive = true
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Set(bonesDataActiveKey, self.bonesDataActive)
	
	self:LoadBonesData(moho.layer)
	self:RemoveSelectedBonesFromFollowList(moho)
	
	self:ValidateLockList(moho)
	for i = 0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected then
			local existInList = self:ValueExists(self.lockPosList, i)
			if not existInList then
				table.insert(self.lockPosList, i)
				table.insert(self.lockPosBoneNamesList, bone:Name())
			else
				table.remove(self.lockPosList, existInList)
				table.remove(self.lockPosBoneNamesList, existInList)
			end
		end
	end
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:RemoveFromLockList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	self:LoadBonesData(moho.layer)
	self:ValidateLockList(moho)
	for i = 0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected then
			local existInList
			if self.lockAngleList then
				existInList = self:ValueExists(self.lockAngleList, i)
				if existInList then
					table.remove(self.lockAngleList, existInList)
					table.remove(self.lockAngleBoneNamesList, existInList)
				end
			end
			if self.lockPosList then
				existInList = self:ValueExists(self.lockPosList, i)
				if existInList then
					table.remove(self.lockPosList, existInList)
					table.remove(self.lockPosBoneNamesList, existInList)
				end
			end
		end
	end
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:RemoveFromFollowist(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	self:LoadBonesData(moho.layer)
	self:ValidateLockList(moho)
	for i = 0, skel:CountBones()-1 do
		local bone = skel:Bone(i)
		if bone.fSelected then
			local existInList
			if self.lockAngleList then
				existInList = self:ValueExists(self.lockAngleList, i)
				if existInList then
					table.remove(self.lockAngleList, existInList)
					table.remove(self.lockAngleBoneNamesList, existInList)
				end
			end
			if self.lockPosList then
				existInList = self:ValueExists(self.lockPosList, i)
				if existInList then
					table.remove(self.lockPosList, existInList)
					table.remove(self.lockPosBoneNamesList, existInList)
				end
			end
		end
	end
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:ValidateLockList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	
	local removeList = {}
	for b=1, #self.lockAngleList do
		local tBone = skel:Bone(self.lockAngleList[b])
		if tBone then
			if tBone:Name() ~= self.lockAngleBoneNamesList[b] then
				table.insert(removeList, b)
			end
		else
			table.insert(removeList, b)
		end
	end

	if #removeList > 0 then
		table.sort(removeList, function(a, b) return a > b end)
		for i, v in ipairs(removeList) do
			table.remove(self.lockAngleList, v)
			table.remove(self.lockAngleBoneNamesList, v)
		end
	end
	
	removeList = {}
	
	for b=1, #self.lockPosList do
		local tBone = skel:Bone(self.lockPosList[b])
		if tBone then
			if tBone:Name() ~= self.lockPosBoneNamesList[b] then
				table.insert(removeList, b)
			end
		else
			table.insert(removeList, b)
		end
	end

	if #removeList > 0 then
		table.sort(removeList, function(a, b) return a > b end)
		for i, v in ipairs(removeList) do
			table.remove(self.lockPosList, v)
			table.remove(self.lockPosBoneNamesList, v)
		end
	end
end

function MR_PoseTool:ValidateFollowList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	local removeList = {}
	for b=1, #self.followBonesList.id do
		for i=1, #self.followBonesList.id[b] do
			local tBone = skel:Bone(self.followBonesList.id[b][i])
			if tBone then
				if tBone:Name() ~= self.followBonesList.names[b][i] or tBone:IsZeroLength() then
					table.insert(removeList, b)
					break
				end
			else
				table.insert(removeList, b)
				break
			end
		end
	end
	
	if #removeList > 0 then
		local function compare(a, b)
			return a > b 
		end
		table.sort(removeList, compare)
		for i, v in ipairs(removeList) do
			table.remove(self.followBonesList.id, v)
			table.remove(self.followBonesList.names, v)
			table.remove(self.followBonesList.startBone, v)
			table.remove(self.followBonesList.endBone, v)
		end
	end
end

function MR_PoseTool:AdjustFollowAndLockBones(moho)
	if self.bonesDataActive then
		for i=1, #self.followLockedBonesList.listIndex do
			if self.followLockedBonesList.list[i] == 1 then
				self:AdjustFollowBones(moho, self.followLockedBonesList.listIndex[i])
			elseif self.followLockedBonesList.list[i] == 2 then
				self:AdjustLockAngles(moho, self.followLockedBonesList.listIndex[i])
			elseif self.followLockedBonesList.list[i] == 3 then
				self:AdjustLockPos(moho, self.followLockedBonesList.listIndex[i])
			end
		end
	end
end

function MR_PoseTool:RemoveSelectedBonesFromFollowList(moho)
	local skel = moho:Skeleton()
	if not skel then
		return
	end
	
	self:LoadBonesData(moho.layer)
	local removeList = {}
	for b=1, #self.followBonesList.id do
		for i=1, #self.followBonesList.id[b] do
			local bone = skel:Bone(self.followBonesList.id[b][i])
			if bone.fSelected then
				table.insert(removeList, b)
				break
			end
		end
	end
	
	if #removeList > 0 then
		local function compare(a, b)
			return a > b 
		end
		table.sort(removeList, compare)
		for i, v in ipairs(removeList) do
			table.remove(self.followBonesList.id, v)
			table.remove(self.followBonesList.names, v)
			table.remove(self.followBonesList.startBone, v)
			table.remove(self.followBonesList.endBone, v)
		end
	end
	
	self:SaveBonesData(moho.layer)
end

function MR_PoseTool:ValueExists(tbl, value)
    for key, val in pairs(tbl) do
        if val == value then
            return key
        end
    end
    return false
end

function MR_PoseTool:LoadBonesData(layer)
	self.followBonesList = {}
	self.followBonesList.id = {}
	self.followBonesList.names = {}
	self.followBonesList.length = {}
	self.followBonesList.startBone = {}
	self.followBonesList.endBone = {}
	
	local scriptInfo = layer:ScriptData()
	
	local followBonesLengthKey = self.scriptDataName..'followBones_length '
	if scriptInfo:HasKey(followBonesLengthKey) then
		local keyValue = scriptInfo:GetString(followBonesLengthKey)
		MR_Utilities:StringToTable(keyValue, self.followBonesList.length, 'n')
	end
	
	local idList = {}
	local followBonesIdKey = self.scriptDataName..'followBones_id '
	if scriptInfo:HasKey(followBonesIdKey) then
		local keyValue = scriptInfo:GetString(followBonesIdKey)
	
		MR_Utilities:StringToTable(keyValue, idList, 'n')
	end
	MR_Utilities:DistributeValuesToTables(self.followBonesList.id, idList, self.followBonesList.length)
	
	local namesList = {}
	local followBonesNamesKey = self.scriptDataName..'followBones_names '
	if scriptInfo:HasKey(followBonesNamesKey) then
		local keyValue = scriptInfo:GetString(followBonesNamesKey)
	
		MR_Utilities:StringToTable(keyValue, namesList, 's')
	end
	MR_Utilities:DistributeValuesToTables(self.followBonesList.names, namesList, self.followBonesList.length)
	
	local followBonesStartBoneKey = self.scriptDataName..'followBones_startBone '
	if scriptInfo:HasKey(followBonesStartBoneKey) then
		local keyValue = scriptInfo:GetString(followBonesStartBoneKey)
		MR_Utilities:StringToTable(keyValue, self.followBonesList.startBone, 'n')
	end
	
	local followBonesEndBoneKey = self.scriptDataName..'followBones_endBone '
	if scriptInfo:HasKey(followBonesEndBoneKey) then
		local keyValue = scriptInfo:GetString(followBonesEndBoneKey)
		MR_Utilities:StringToTable(keyValue, self.followBonesList.endBone, 'n')
	end
	
	self.lockAngleList = {}
	self.lockAngleBoneNamesList = {}
	
	local lockAngleListKey = self.scriptDataName..'lockAngleList '
	if scriptInfo:HasKey(lockAngleListKey) then
		local keyValue = scriptInfo:GetString(lockAngleListKey)
		MR_Utilities:StringToTable(keyValue, self.lockAngleList, 'n')
	end
	
	local lockAngleBoneNamesListKey = self.scriptDataName..'lockAngleBoneNamesList '
	if scriptInfo:HasKey(lockAngleBoneNamesListKey) then
		local keyValue = scriptInfo:GetString(lockAngleBoneNamesListKey)
		MR_Utilities:StringToTable(keyValue, self.lockAngleBoneNamesList, 's')
	end
	
	self.lockPosList = {}
	self.lockPosBoneNamesList = {}
	
	local lockPosListKey = self.scriptDataName..'lockPosList '
	if scriptInfo:HasKey(lockPosListKey) then
		local keyValue = scriptInfo:GetString(lockPosListKey)
		MR_Utilities:StringToTable(keyValue, self.lockPosList, 'n')
	end
	
	local lockPosBoneNamesListKey = self.scriptDataName..'lockPosBoneNamesList '
	if scriptInfo:HasKey(lockPosBoneNamesListKey) then
		local keyValue = scriptInfo:GetString(lockPosBoneNamesListKey)
		MR_Utilities:StringToTable(keyValue, self.lockPosBoneNamesList, 's')
	end
end

function MR_PoseTool:SaveBonesData(layer)
	local scriptInfo = layer:ScriptData()
	local keyValue = ''
	local tblLength = ''
	local followBonesIdKey = self.scriptDataName..'followBones_id '
	local followBonesLengthKey = self.scriptDataName..'followBones_length '
	for i, tbl in ipairs(self.followBonesList.id) do
		keyValue = keyValue..MR_Utilities:TableToString(tbl)
		local length = #tbl
		tblLength = tblLength..#tbl..' '..length..','
	end
	scriptInfo:Set(followBonesIdKey, keyValue)
	scriptInfo:Set(followBonesLengthKey, tblLength)
	
	keyValue = ''
	local followBonesNamesKey = self.scriptDataName..'followBones_names '
	for i, tbl in ipairs(self.followBonesList.names) do
		keyValue = keyValue..MR_Utilities:TableToString(tbl)
	end
	scriptInfo:Set(followBonesNamesKey, keyValue)

	local followBonesStartBoneKey = self.scriptDataName..'followBones_startBone '
	keyValue = MR_Utilities:TableToString(self.followBonesList.startBone)
	scriptInfo:Set(followBonesStartBoneKey, keyValue)
	
	local followBonesEndBoneKey = self.scriptDataName..'followBones_endBone '
	keyValue = MR_Utilities:TableToString(self.followBonesList.endBone)
	scriptInfo:Set(followBonesEndBoneKey, keyValue)
	
	local lockAngleListKey = self.scriptDataName..'lockAngleList '
	keyValue = MR_Utilities:TableToString(self.lockAngleList)
	scriptInfo:Set(lockAngleListKey, keyValue)
	
	local lockAngleBoneNamesListKey = self.scriptDataName..'lockAngleBoneNamesList '
	keyValue = MR_Utilities:TableToString(self.lockAngleBoneNamesList)
	scriptInfo:Set(lockAngleBoneNamesListKey, keyValue)
	
	local lockPosListKey = self.scriptDataName..'lockPosList '
	keyValue = MR_Utilities:TableToString(self.lockPosList)
	scriptInfo:Set(lockPosListKey, keyValue)
	
	local lockPosBoneNamesListKey = self.scriptDataName..'lockPosBoneNamesList '
	keyValue = MR_Utilities:TableToString(self.lockPosBoneNamesList)
	scriptInfo:Set(lockPosBoneNamesListKey, keyValue)
end

function MR_PoseTool:CleanUpBonesData(layer)
	local scriptInfo = layer:ScriptData()

	local followBonesIdKey = self.scriptDataName..'followBones_id '
	scriptInfo:Remove(followBonesIdKey)
	
	local followBonesLengthKey = self.scriptDataName..'followBones_length '
	scriptInfo:Remove(followBonesLengthKey)
	
	local followBonesNamesKey = self.scriptDataName..'followBones_names '
	scriptInfo:Remove(followBonesNamesKey)
	
	local followBonesStartBoneKey = self.scriptDataName..'followBones_startBone '
	scriptInfo:Remove(followBonesStartBoneKey)
	
	local followBonesEndBoneKey = self.scriptDataName..'followBones_endBone '
	scriptInfo:Remove(followBonesEndBoneKey)
	
	local lockAngleListKey = self.scriptDataName..'lockAngleList '
	scriptInfo:Remove(lockAngleListKey)
	
	local lockAngleBoneNamesListKey = self.scriptDataName..'lockAngleBoneNamesList '
	scriptInfo:Remove(lockAngleBoneNamesListKey)
	
	local lockPosListKey = self.scriptDataName..'lockPosList '
	scriptInfo:Remove(lockPosListKey)
	
	local lockPosBoneNamesListKey = self.scriptDataName..'lockPosBoneNamesList '
	scriptInfo:Remove(lockPosBoneNamesListKey)
	
	local bonesDataActiveKey = self.scriptDataName..'bonesDataActive '
	scriptInfo:Remove(bonesDataActiveKey)
	
	self.lockAngleList = {}
	self.lockPosList = {}
	self.lockAngleBoneNamesList = {}
	self.lockPosBoneNamesList = {}
	self.followBonesList = {}
	self.followBonesList.id = {}
	self.followBonesList.names  = {}
	self.followBonesList.length  = {}
	self.followBonesList.startBone = {}
	self.followBonesList.endBone = {}
	self.bonesDataActive = true
end

-- **************************************************
-- Localization
-- **************************************************

function MR_PoseTool:Localize(text)
	local phrase = {}

	phrase['Description'] = 'Set up the pose of your character (hold <ctrl/cmd> or <ctrl/cmd> + <shift> to access the quick menu, <alt> for compensation of child bone transformation, <shift> for additional transformation variations)'
	phrase['UILabel'] = 'MR Pose Tool '..self:Version()
	
	phrase['Settings'] = 'Settings'
	phrase['Quick menu tooltips'] = 'Quick menu tooltips'
	phrase['Double-click to set keyframe'] = 'Double-click to set keyframe'
	phrase['Click and hold to reset'] = 'Click and hold to reset'
	phrase['Move target parent'] = 'Move target\'s parent'
	phrase['Block on even frames'] = 'Block on even frames'
	phrase['Block on odd frames'] = 'Block on odd frames'
	phrase['Highlight bones'] = 'Highlight bones'
	phrase['Highlight width:'] = 'Highlight width:'
	phrase['Highlight opacity:'] = 'Highlight opacity:'
	phrase['Custom'] = 'Use custom:'
	phrase['Align handles along bone'] = 'Align handles along bone'
	phrase['Handles distance:'] = 'Handles distance:'
	phrase['Handles stroke opacity:'] = 'Handles stroke opacity:'
	phrase['Handles fill opacity:'] = 'Handles fill opacity:'
	phrase['Use custom colors'] = 'Use custom colors'
	phrase['Translate handle stroke color Tooltip'] = 'Translate handle stroke color'
	phrase['Translate handle fill color Tooltip'] = 'Translate handle fill color'
	phrase['Scale handle stroke color Tooltip'] = 'Scale handle stroke color'
	phrase['Scale handle fill color Tooltip'] = 'Scale handle fill color'
	phrase['Move joint handle stroke color Tooltip'] = 'Move joint handle stroke color'
	phrase['Move joint handle fill color Tooltip'] = 'Move joint handle fill color'
	phrase['Manipulate handle stroke color Tooltip'] = 'Manipulate handle stroke color'
	phrase['Manipulate handle fill color Tooltip'] = 'Manipulate handle fill color'
	phrase['Reset colors'] = 'Reset colors'
	
	phrase['Twos mode'] = 'Twos mode'
	phrase['Keep selection'] = 'Keep selection'
	phrase['Multi transform'] = 'Multi transform'
	phrase['Lock handles'] = 'Lock handles'
	phrase['Hide bones while moving'] = 'Hide'
	phrase['Keep previous selection'] = 'Keep previous selection'
	phrase['Bake Adjacent Frames'] = 'Smart bake'
	phrase['Interval'] = 'Interval:'
	phrase['Show path'] = 'Show path'
	phrase['Range'] = 'Range'
	phrase['Range frames:'] = 'Range frames:'
	phrase['End flip'] = 'End flip'
	phrase['Side flip'] = 'Side flip'
	phrase['Reset:'] = 'Reset:'
	phrase['A'] = 'A'
	phrase['Reset angle'] = 'Reset angle'
	phrase['T'] = 'T'
	phrase['Reset translation'] = 'Reset translation'
	phrase['S'] = 'S'
	phrase['Reset scale'] = 'Reset scale'
	
	phrase['Set follow bones chains'] = 'Set follow bones chains'
	phrase['Set single follow bones'] = 'Set single follow bones'
	phrase['Scale follow bones'] = 'Scale follow bones'
	phrase['Lock angle'] = 'Lock angle'
	phrase['Lock position'] = 'Lock position'
	phrase['Clear selection'] = 'Clear selection'
	phrase['Clear all'] = 'Clear all'
	phrase['Enable'] = 'Enable'

	return phrase[text]
end

Icon
MR Pose Tool
Listed

Script type: Tool

Uploaded: Aug 14 2023, 06:38

Last modified: Jun 12 2024, 09:56

Plan and polish your animation with ease!
MR Pose Tool allows you to minimize the routine and spend more effort on creativity. This script combines the tools Transform Bone, Manipulate Bones, MR Move Targeted Joint, and even more.




To work correctly the lower bone (the shin or the forearm) must not have any Y-axis translation.

Update 1.2

Change List:
1. Improved Lock Handles mode, now there's no need to deselect the current bone to select another.
2. Enhanced Align Handles Along Bone mode, now the handles do not overlap each other when the bone on the screen is small in size. This works only when all four handles are active.
3. Added the ability to customize the color and transparency of the handles.
4. Added Highlight Bones option which draws a line along the bone under the cursor, making it easier to identify which bone you will select when you click.
5. Added Double-click to Reset option, allowing you to disable this feature if it interferes.

Update 1.3

Change List:
1. Added an option that allows blocking the script on even or odd frames. This is convenient if you work in twos, so as not to create keys outside the interval.

MR Pose Tool 2.0

1. Ability to select multiple bones at once.
2. Ability to transform multiple bones at once.
3. Quick access menu to options and functions of the tool.
4. Follow bone, Lock angle, and Lock Pos features, which allow you to find the pose faster by controlling only individual body parts of the character, while maintaining the position of other parts.
5. Added Twos mode option to the panel and in the quick menu.
6. In Lock handles mode, only handles for selected bones are displayed. Previously, this only worked with one bone.
7. The Keep selection option now retains selection only if there has been bone transformation. Meaning, now you can select bones without turning off this option.

Update 2.1

Change List:
1. All information about Follow bones and Lock bones is now stored in the character layer. This allows you to switch freely between characters without needing to reassign bones each time.
2. Added the ability to enable and disable Follow bones and Lock bones for quick access without the need to constantly reassign bones. This can be done via the quick menu or by double-clicking outside the bones.
3. Pressing Ctrl + Alt in the quick menu brings up additional options. For example, you can add individual bones as Follow bones instead of chains of bones.
4. Bug fixes.

Update 2.1.6

Change List:
1. Bug fixes.
This script, and all other scripts on this site are distributed as free software under the GNU General Public License 3.0 or later.
Downloads count: 2957