import Block from '../models/block'
import Change from '../models/change'
import Decoration from '../models/decoration'
import Document from '../models/document'
import Editor from '../controllers/editor'
import Inline from '../models/inline'
import Leaf from '../models/leaf'
import Mark from '../models/mark'
import Node from '../models/node'
import Operation from '../models/operation'
import Point from '../models/point'
import Range from '../models/range'
import Selection from '../models/selection'
import Text from '../models/text'
import Value from '../models/value'
import isObject, { TYPES } from '../utils/is-object'
import mixin from '../utils/mixin'

/**
 * A factory for the interface that all Slate objects implement.
 *
 * @type {Function}
 */

function create(type) {
  const TYPE = TYPES[type]
  const camel = `${type.charAt(0).toUpperCase()}${type.slice(1)}`
  const is = `is${camel}`

  class ObjectInterface {
    /**
     * Return the type of the object.
     *
     * @return {String}
     */

    get object() {
      return type
    }
  }

  ObjectInterface[is] = isObject.bind(null, type)
  ObjectInterface.prototype[TYPE] = true
  return ObjectInterface
}

/**
 * Mix in the object interfaces.
 */

mixin(create('block'), [Block])
mixin(create('change'), [Change])
mixin(create('decoration'), [Decoration])
mixin(create('document'), [Document])
mixin(create('editor'), [Editor])
mixin(create('inline'), [Inline])
mixin(create('leaf'), [Leaf])
mixin(create('mark'), [Mark])
mixin(create('node'), [Node])
mixin(create('operation'), [Operation])
mixin(create('point'), [Point])
mixin(create('range'), [Range])
mixin(create('selection'), [Selection])
mixin(create('text'), [Text])
mixin(create('value'), [Value])

@@ -1223,514 +1223,243 @@
 */%0A%0A
-mixin(create('block'), %5BBlock%5D)%0Amixin(create('change'), %5BChange%5D)%0Amixin(create('decoration'), %5BDecoration%5D)%0Amixin(create('document'), %5BDocument%5D)%0Amixin(create('editor'), %5BEditor%5D)%0Amixin(create('inline'), %5BInline%5D)%0Amixin(create('leaf'), %5BLeaf%5D)%0Amixin(create('mark'), %5BMark%5D)%0Amixin(create('node'), %5BNode%5D)%0Amixin(create('operation'), %5BOperation%5D)%0Amixin(create('point'), %5BPoint%5D)%0Amixin(create('range'), %5BRange%5D)%0Amixin(create('selection'), %5BSelection%5D)%0Amixin(create('text'), %5BText%5D)%0Amixin(create('value'), %5BValue%5D
+Object.entries(%7B%0A  Block,%0A  Change,%0A  Decoration,%0A  Document,%0A  Editor,%0A  Inline,%0A  Leaf,%0A  Mark,%0A  Node,%0A  Operation,%0A  Point,%0A  Range,%0A  Selection,%0A  Text,%0A  Value,%0A%7D).forEach((%5Bcamel, obj%5D) =%3E mixin(create(camel.toLowerCase()), %5Bobj%5D)
 )%0A

Refactor duplicate code in mixin (#2529)