local f=function(f,S)return f.Time<S.Time end return function(S,v,h)local l={}local u={}for f,S in next,S.Keypoints do local N,P for f,v in next,v.Keypoints do if v.Time==S.Time then N,P=v,v break elseif v.Time<S.Time and(P==nil or v.Time>P.Time)then P=v elseif v.Time>S.Time and(N==nil or v.Time<N.Time)then N=v end end local s,m if N==P then s,m=N.Value,N.Envelope else local f=(S.Time-P.Time)/(N.Time-P.Time)s=(N.Value-P.Value)*f+P.Value m=(N.Envelope-P.Envelope)*f+P.Envelope end local i=(s-S.Value)*h+S.Value local Y=(m-S.Envelope)*h+S.Envelope local V=NumberSequenceKeypoint.new(S.Time,i,Y)table.insert(l,V)u[S.Time]=true end for f,v in next,v.Keypoints do if not u[v.Time]then local f,u for S,h in next,S.Keypoints do if h.Time==v.Time then f,u=h,h break elseif h.Time<v.Time and(u==nil or h.Time>u.Time)then u=h elseif h.Time>v.Time and(f==nil or h.Time<f.Time)then f=h end end local N,P if f==u then N,P=f.Value,f.Envelope else local S=(v.Time-u.Time)/(f.Time-u.Time)N=(f.Value-u.Value)*S+u.Value P=(f.Envelope-u.Envelope)*S+u.Envelope end local s=(v.Value-N)*h+N local m=(v.Envelope-P)*h+P local i=NumberSequenceKeypoint.new(v.Time,s,m)table.insert(l,i)end end table.sort(l,f)return NumberSequence.new(l)end


local sortByTime = function(a, b)
	return a.Time < b.Time
end

return function(a, b, t)
	local keypoints = {}
	local addedTimes = {}
	
	for i, ap in next, a.Keypoints do
		local closestAbove, closestBelow
		
		for i, bp in next, b.Keypoints do
			if bp.Time == ap.Time then
				closestAbove, closestBelow = bp, bp
				break
			elseif bp.Time < ap.Time and (closestBelow == nil or bp.Time > closestBelow.Time) then
				closestBelow = bp
			elseif bp.Time > ap.Time and (closestAbove == nil or bp.Time < closestAbove.Time) then
				closestAbove = bp
			end
		end
		
		local bValue, bEnvelope
		if closestAbove == closestBelow then
			bValue, bEnvelope = closestAbove.Value, closestAbove.Envelope
		else
			local p = (ap.Time - closestBelow.Time)/(closestAbove.Time - closestBelow.Time)
			bValue = (closestAbove.Value - closestBelow.Value)*p + closestBelow.Value
			bEnvelope = (closestAbove.Envelope - closestBelow.Envelope)*p + closestBelow.Envelope
		end
		local interValue = (bValue - ap.Value)*t + ap.Value
		local interEnvelope = (bEnvelope - ap.Envelope)*t + ap.Envelope
		local interp = NumberSequenceKeypoint.new(ap.Time, interValue, interEnvelope)
		
		table.insert(keypoints, interp)
		
		addedTimes[ap.Time] = true
	end
	for i, bp in next, b.Keypoints do
		if not addedTimes[bp.Time] then
			local closestAbove, closestBelow
			
			for i, ap in next, a.Keypoints do
				if ap.Time == bp.Time then
					closestAbove, closestBelow = ap, ap
					break
				elseif ap.Time < bp.Time and (closestBelow == nil or ap.Time > closestBelow.Time) then
					closestBelow = ap
				elseif ap.Time > bp.Time and (closestAbove == nil or ap.Time < closestAbove.Time) then
					closestAbove = ap
				end
			end
			
			local aValue, aEnvelope
			if closestAbove == closestBelow then
				aValue, aEnvelope = closestAbove.Value, closestAbove.Envelope
			else
				local p = (bp.Time - closestBelow.Time)/(closestAbove.Time - closestBelow.Time)
				aValue = (closestAbove.Value - closestBelow.Value)*p + closestBelow.Value
				aEnvelope = (closestAbove.Envelope - closestBelow.Envelope)*p + closestBelow.Envelope
			end
			local interValue = (bp.Value - aValue)*t + aValue
			local interEnvelope = (bp.Envelope - aEnvelope)*t + aEnvelope
			local interp = NumberSequenceKeypoint.new(bp.Time, interValue, interEnvelope)
			
			table.insert(keypoints, interp)
		end
	end
	
	table.sort(keypoints, sortByTime)
	
	return NumberSequence.new(keypoints)
end
