func (d *Delta) TransformPosition(index int, priority bool) int {
	thisIter := OpsIterator(d.Ops)
	offset := 0
	for thisIter.HasNext() && offset <= index {
		length := thisIter.PeekLength()
		nextType := thisIter.PeekType()
		thisIter.Next(math.MaxInt64)
		if nextType == "delete" {
			index -= int(math.Min(float64(length), float64(index-offset)))
			continue
		} else if nextType == "insert" && (offset < index || !priority) {
			index += length
		}
		offset += length
	}
	return index
}
TransformPosition returns the new index after applying a list of Ops
package delta
import (
	"encoding/json"
	"errors"
	"math"
	"reflect"
)
type Delta struct {
	Ops []Op `json:"ops"`
}
type Embed struct {
	Key   string
	Value interface{}
}
type Op struct {
	Insert      []rune                 `json:"insert,omitempty"`
	InsertEmbed *Embed                 `json:"-"`
	Retain      *int                   `json:"retain,omitempty"`
	Attributes  map[string]interface{} `json:"attributes,omitempty"`
	Delete      *int                   `json:"delete,omitempty"`
}
func (o *Op) IsNil() bool {
	return o.Attributes == nil &&
		o.Delete == nil &&
		o.Insert == nil &&
		o.Retain == nil
}
func (o *Op) Length() int {
	return OpsLength(*o)
}
func New(ops []Op) *Delta {
	return &Delta{
		Ops: ops,
	}
}
func FromJSON(in []byte) (*Delta, error) {
	var ret Delta
	if err := json.Unmarshal(in, &ret); err != nil {
		return nil, err
	}
	return &ret, nil
}
func (o *Op) UnmarshalJSON(data []byte) error {
	type Alias Op
	aux := &struct {
		Insert *json.RawMessage `json:"insert"`
		*Alias
	}{
		Alias: (*Alias)(o),
	}
	if err := json.Unmarshal(data, &aux); err != nil {
		return err
	}
	if aux.Insert != nil {
		if (*aux.Insert)[0] == '"' {
			var b string
			if err := json.Unmarshal(*aux.Insert, &b); err != nil {
				return err
			}
			o.Insert = []rune(b)
			o.InsertEmbed = nil
		} else {
			var m map[string]interface{}
			if err := json.Unmarshal(*aux.Insert, &m); err != nil {
				return err
			}
			if len(m) != 1 {
				return errors.New("invalid embed")
			}
			var embed Embed
			for k, v := range m {
				embed.Key = k
				embed.Value = v
			}
			o.InsertEmbed = &embed
			o.Insert = nil
		}
	}
	return nil
}
func (o *Op) MarshalJSON() ([]byte, error) {
	type Alias Op
	var message *json.RawMessage
	if o.Insert != nil {
		b, err := json.Marshal(string(o.Insert))
		if err != nil {
			return nil, err
		}
		message = (*json.RawMessage)(&b)
	} else if o.InsertEmbed != nil {
		m := make(map[string]interface{})
		m[o.InsertEmbed.Key] = o.InsertEmbed.Value
		b, err := json.Marshal(m)
		if err != nil {
			return nil, err
		}
		message = (*json.RawMessage)(&b)
	}
	return json.Marshal(&struct {
		Insert *json.RawMessage `json:"insert,omitempty"`
		*Alias
	}{
		Insert: message,
		Alias:  (*Alias)(o),
	})
}
func (d *Delta) Insert(text string, attrs map[string]interface{}) *Delta {
	if len([]rune(text)) == 0 {
		return d
	}
	newOp := Op{
		Insert:     []rune(text),
		Attributes: attrs,
	}
	d.Push(newOp)
	return d
}
func (d *Delta) InsertEmbed(embed Embed, attrs map[string]interface{}) *Delta {
	if len(embed.Key) == 0 || embed.Value == nil {
		return d
	}
	newOp := Op{
		InsertEmbed: &embed,
		Attributes:  attrs,
	}
	d.Push(newOp)
	return d
}
func (d *Delta) Delete(n int) *Delta {
	if n <= 0 {
		return d
	}
	d.Push(Op{Delete: &n})
	return d
}
func (d *Delta) Retain(n int, attrs map[string]interface{}) *Delta {
	if n <= 0 {
		return d
	}
	newOp := Op{
		Retain: &n,
	}
	if attrs != nil {
		newOp.Attributes = attrs
	}
	d.Push(newOp)
	return d
}
func (d *Delta) Push(newOp Op) *Delta {
	idx := len(d.Ops)
	var lastOp *Op
	if idx > 0 {
		lastOp = &d.Ops[idx-1]
	}
	if lastOp == nil {
		d.Ops = append(d.Ops, newOp)
		return d
	}
	if !newOp.IsNil() {
		if newOp.Delete != nil && lastOp.Delete != nil {
			sum := *lastOp.Delete + *newOp.Delete
			d.Ops[idx-1] = Op{Delete: &sum}
			return d
		}
		if lastOp.Delete != nil && newOp.Insert != nil {
			idx--
			if idx < 1 {
				d.Ops = append([]Op{newOp}, d.Ops...)
				return d
			}
			lastOp = &d.Ops[idx-1]
		}
		if reflect.DeepEqual(newOp.Attributes, lastOp.Attributes) {
			if newOp.Insert != nil && lastOp.Insert != nil {
				mergedText := append(lastOp.Insert, newOp.Insert...)
				d.Ops[idx-1] = Op{
					Insert: mergedText,
				}
				if newOp.Attributes != nil {
					d.Ops[idx-1].Attributes = newOp.Attributes
				}
				return d
			} else if newOp.Retain != nil && lastOp.Retain != nil {
				x := *lastOp.Retain + *newOp.Retain
				d.Ops[idx-1] = Op{
					Retain: &x,
				}
				if newOp.Attributes != nil {
					d.Ops[idx-1].Attributes = newOp.Attributes
				}
				return d
			}
		}
	}
	if idx == len(d.Ops) {
		d.Ops = append(d.Ops, newOp)
	} else {
		d.Ops = append(d.Ops, Op{})
		copy(d.Ops[idx+1:], d.Ops[idx:])
		d.Ops[idx] = newOp
	}
	return d
}
func (d *Delta) Chop() *Delta {
	x := len(d.Ops)
	if x == 0 {
		return d
	}
	lastOp := d.Ops[x-1]
	if lastOp.Retain != nil && lastOp.Attributes == nil {
		d.Ops = d.Ops[:x-1]
	}
	return d
}
func (d *Delta) Compose(other Delta) *Delta {
	thisIter := OpsIterator(d.Ops)
	otherIter := OpsIterator(other.Ops)
	delta := New(nil)
	for thisIter.HasNext() || otherIter.HasNext() {
		if otherIter.PeekType() == "insert" {
			delta.Push(otherIter.Next(math.MaxInt64))
		} else if thisIter.PeekType() == "delete" {
			delta.Push(thisIter.Next(math.MaxInt64))
		} else {
			length := int(math.Min(float64(thisIter.PeekLength()), float64(otherIter.PeekLength())))
			thisOp := thisIter.Next(length)
			otherOp := otherIter.Next(length)
			if otherOp.Retain != nil {
				newOp := Op{}
				if thisOp.Retain != nil {
					newOp.Retain = &length
				} else {
					newOp.Insert = append([]rune(nil), thisOp.Insert...)
					newOp.InsertEmbed = thisOp.InsertEmbed
				}
				attributes := AttrCompose(thisOp.Attributes, otherOp.Attributes, thisOp.Retain != nil)
				if attributes != nil {
					newOp.Attributes = attributes
				}
				delta.Push(newOp)
			} else if otherOp.Delete != nil && thisOp.Retain != nil {
				delta.Push(otherOp)
			}
		}
	}
	return delta.Chop()
}
func (d *Delta) Concat(other Delta) *Delta {
	delta := New(d.Ops)
	if len(other.Ops) > 0 {
		delta.Push(other.Ops[0])
		delta.Ops = append(delta.Ops, other.Ops[1:]...)
	}
	return delta
}