<fim-prefix><fim-middle>ameStr, removeCollectionProp, omit, isObject, parseHTML, removeTextChildNodes, escapeHTML, extend, concatWithoutDups, getUID, isNodeTag } from './parts/helpers'
import DEFAULTS from './parts/defaults'<fix-suffix>
import _dropdown, { initDropdown } from './parts/dropdown'
import { getPersistedData, setPersistedData, clearPersistedData } from './parts/persist'
import TEXTS from './parts/texts'
import templates from './parts/templates'
import EventDispatcher from './parts/EventDispatcher'
import events, { triggerChangeEvent } from './parts/events'

/**
 * @constructor
 * @param {Object} input    DOM element
 * @param {Object} settings settings object
 */
function Tagify( input, settings ){
    if( !input ){
        console.warn('Tagify:', 'input element not found', input)
        // return an empty mock of all methods, so the code using tagify will not break
        // because it might be calling methods even though the input element does not exists
        const mockInstance = new Proxy(this, { get(){ return () => mockInstance } })
        return mockInstance
    }


    if( input.previousElementSibling && input.previousElementSibling.classList.contains('tagify') ){
        console.warn('Tagify: ', 'input element is already Tagified', input)
        return this
    }

    extend(this, EventDispatcher(this))
    this.isFirefox = typeof InstallTrigger !== 'undefined'
    this.isIE = window.document.documentMode; // https://developer.mozilla.org/en-US/docs/Web/API/Document/compatMode#Browser_compatibility

    settings = settings || {};
    this.getPersistedData = getPersistedData(settings.id)
    this.setPersistedData = setPersistedData(settings.id)
    this.clearPersistedData = clearPer<|endoftext|>