RegExp.escape = function(e) {
        return e.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")
    },
    function(e) {
        "use strict";
        e.csv = {
            defaults: {
                separator: ",",
                delimiter: '"',
                headers: !0
            },
            hooks: {
                castToScalar: function(e, r) {
                    if (isNaN(e)) return e;
                    if (/\./.test(e)) return parseFloat(e);
                    var a = parseInt(e);
                    return isNaN(a) ? null : a
                }
            },
            parsers: {
                parse: function(e, r) {
                    var a = r.separator,
                        t = r.delimiter;
                    r.state.rowNum || (r.state.rowNum = 1), r.state.colNum || (r.state.colNum = 1);
                    var s = [],
                        o = [],
                        l = 0,
                        n = "",
                        c = !1;

                    function u() {
                        if (l = 0, n = "", r.start && r.state.rowNum < r.start) {
                            o = [], r.state.rowNum++, r.state.colNum = 1;
                            return
                        }
                        if (void 0 === r.onParseEntry) s.push(o);
                        else {
                            var e = r.onParseEntry(o, r.state);
                            !1 !== e && s.push(e)
                        }
                        o = [], r.end && r.state.rowNum >= r.end && (c = !0), r.state.rowNum++, r.state.colNum = 1
                    }

                    function m() {
                        if (void 0 === r.onParseValue) o.push(n);
                        else {
                            var e = r.onParseValue(n, r.state);
                            !1 !== e && o.push(e)
                        }
                        n = "", l = 0, r.state.colNum++
                    }
                    var f = RegExp.escape(a),
                        p = RegExp.escape(t),
                        d = /(D|S|\n|\r|[^DS\r\n]+)/,
                        v = d.source;
                    return d = RegExp(v = (v = v.replace(/S/g, f)).replace(/D/g, p), "gm"), e.replace(d, function(e) {
                        if (!c) switch (l) {
                            case 0:
                                if (e === a) {
                                    n += "", m();
                                    break
                                }
                                if (e === t) {
                                    l = 1;
                                    break
                                }
                                if ("\n" === e) {
                                    m(), u();
                                    break
                                }
                                if (/^\r$/.test(e)) break;
                                n += e, l = 3;
                                break;
                            case 1:
                                if (e === t) {
                                    l = 2;
                                    break
                                }
                                n += e, l = 1;
                                break;
                            case 2:
                                if (e === t) {
                                    n += e, l = 1;
                                    break
                                }
                                if (e === a) {
                                    m();
                                    break
                                }
                                if ("\n" === e) {
                                    m(), u();
                                    break
                                }
                                if (/^\r$/.test(e)) break;
                                throw Error("CSVDataError: Illegal State [Row:" + r.state.rowNum + "][Col:" + r.state.colNum + "]");
                            case 3:
                                if (e === a) {
                                    m();
                                    break
                                }
                                if ("\n" === e) {
                                    m(), u();
                                    break
                                }
                                if (/^\r$/.test(e)) break;
                                if (e === t) throw Error("CSVDataError: Illegal Quote [Row:" + r.state.rowNum + "][Col:" + r.state.colNum + "]");
                                throw Error("CSVDataError: Illegal Data [Row:" + r.state.rowNum + "][Col:" + r.state.colNum + "]");
                            default:
                                throw Error("CSVDataError: Unknown State [Row:" + r.state.rowNum + "][Col:" + r.state.colNum + "]")
                        }
                    }), 0 !== o.length && (m(), u()), s
                },
                splitLines: function(e, r) {
                    var a = r.separator,
                        t = r.delimiter;
                    r.state.rowNum || (r.state.rowNum = 1);
                    var s = [],
                        o = 0,
                        l = "",
                        n = !1;

                    function c() {
                        if (o = 0, r.start && r.state.rowNum < r.start) {
                            l = "", r.state.rowNum++;
                            return
                        }
                        if (void 0 === r.onParseEntry) s.push(l);
                        else {
                            var e = r.onParseEntry(l, r.state);
                            !1 !== e && s.push(e)
                        }
                        l = "", r.end && r.state.rowNum >= r.end && (n = !0), r.state.rowNum++
                    }
                    var u = RegExp.escape(a),
                        m = RegExp.escape(t),
                        f = /(D|S|\n|\r|[^DS\r\n]+)/,
                        p = f.source;
                    return f = RegExp(p = (p = p.replace(/S/g, u)).replace(/D/g, m), "gm"), e.replace(f, function(e) {
                        if (!n) switch (o) {
                            case 0:
                                if (e === a) {
                                    l += e, o = 0;
                                    break
                                }
                                if (e === t) {
                                    l += e, o = 1;
                                    break
                                }
                                if ("\n" === e) {
                                    c();
                                    break
                                }
                                if (/^\r$/.test(e)) break;
                                l += e, o = 3;
                                break;
                            case 1:
                                if (e === t) {
                                    l += e, o = 2;
                                    break
                                }
                                l += e, o = 1;
                                break;
                            case 2:
                                var s = l.substr(l.length - 1);
                                if (e === t && s === t) {
                                    l += e, o = 1;
                                    break
                                }
                                if (e === a) {
                                    l += e, o = 0;
                                    break
                                }
                                if ("\n" === e) {
                                    c();
                                    break
                                }
                                if ("\r" === e) break;
                                throw Error("CSVDataError: Illegal state [Row:" + r.state.rowNum + "]");
                            case 3:
                                if (e === a) {
                                    l += e, o = 0;
                                    break
                                }
                                if ("\n" === e) {
                                    c();
                                    break
                                }
                                if ("\r" === e) break;
                                if (e === t) throw Error("CSVDataError: Illegal quote [Row:" + r.state.rowNum + "]");
                                throw Error("CSVDataError: Illegal state [Row:" + r.state.rowNum + "]");
                            default:
                                throw Error("CSVDataError: Unknown state [Row:" + r.state.rowNum + "]")
                        }
                    }), "" !== l && c(), s
                },
                parseEntry: function(e, r) {
                    var a = r.separator,
                        t = r.delimiter;
                    r.state.rowNum || (r.state.rowNum = 1), r.state.colNum || (r.state.colNum = 1);
                    var s = [],
                        o = 0,
                        l = "";

                    function n() {
                        if (void 0 === r.onParseValue) s.push(l);
                        else {
                            var e = r.onParseValue(l, r.state);
                            !1 !== e && s.push(e)
                        }
                        l = "", o = 0, r.state.colNum++
                    }
                    if (!r.match) {
                        var c = RegExp.escape(a),
                            u = RegExp.escape(t),
                            m = /(D|S|\n|\r|[^DS\r\n]+)/.source;
                        m = (m = m.replace(/S/g, c)).replace(/D/g, u), r.match = RegExp(m, "gm")
                    }
                    return e.replace(r.match, function(e) {
                        switch (o) {
                            case 0:
                                if (e === a) {
                                    l += "", n();
                                    break
                                }
                                if (e === t) {
                                    o = 1;
                                    break
                                }
                                if ("\n" === e || "\r" === e) break;
                                l += e, o = 3;
                                break;
                            case 1:
                                if (e === t) {
                                    o = 2;
                                    break
                                }
                                l += e, o = 1;
                                break;
                            case 2:
                                if (e === t) {
                                    l += e, o = 1;
                                    break
                                }
                                if (e === a) {
                                    n();
                                    break
                                }
                                if ("\n" === e || "\r" === e) break;
                                throw Error("CSVDataError: Illegal State [Row:" + r.state.rowNum + "][Col:" + r.state.colNum + "]");
                            case 3:
                                if (e === a) {
                                    n();
                                    break
                                }
                                if ("\n" === e || "\r" === e) break;
                                if (e === t) throw Error("CSVDataError: Illegal Quote [Row:" + r.state.rowNum + "][Col:" + r.state.colNum + "]");
                                throw Error("CSVDataError: Illegal Data [Row:" + r.state.rowNum + "][Col:" + r.state.colNum + "]");
                            default:
                                throw Error("CSVDataError: Unknown State [Row:" + r.state.rowNum + "][Col:" + r.state.colNum + "]")
                        }
                    }), n(), s
                }
            },
            toArray: function(r, a, t) {
                var a = void 0 !== a ? a : {},
                    s = {};
                s.callback = void 0 !== t && "function" == typeof t && t, s.separator = "separator" in a ? a.separator : e.csv.defaults.separator, s.delimiter = "delimiter" in a ? a.delimiter : e.csv.defaults.delimiter;
                var o = void 0 !== a.state ? a.state : {},
                    a = {
                        delimiter: s.delimiter,
                        separator: s.separator,
                        onParseEntry: a.onParseEntry,
                        onParseValue: a.onParseValue,
                        state: o
                    },
                    l = e.csv.parsers.parseEntry(r, a);
                if (!s.callback) return l;
                s.callback("", l)
            },
            toArrays: function(r, a, t) {
                var a = void 0 !== a ? a : {},
                    s = {};
                s.callback = void 0 !== t && "function" == typeof t && t, s.separator = "separator" in a ? a.separator : e.csv.defaults.separator, s.delimiter = "delimiter" in a ? a.delimiter : e.csv.defaults.delimiter;
                var o = [],
                    a = {
                        delimiter: s.delimiter,
                        separator: s.separator,
                        onParseEntry: a.onParseEntry,
                        onParseValue: a.onParseValue,
                        start: a.start,
                        end: a.end,
                        state: {
                            rowNum: 1,
                            colNum: 1
                        }
                    };
                if (o = e.csv.parsers.parse(r, a), !s.callback) return o;
                s.callback("", o)
            },
            toObjects: function(r, a, t) {
                var a = void 0 !== a ? a : {},
                    s = {};
                s.callback = void 0 !== t && "function" == typeof t && t, s.separator = "separator" in a ? a.separator : e.csv.defaults.separator, s.delimiter = "delimiter" in a ? a.delimiter : e.csv.defaults.delimiter, s.headers = "headers" in a ? a.headers : e.csv.defaults.headers, a.start = "start" in a ? a.start : 1, s.headers && a.start++, a.end && s.headers && a.end++;
                var o = [],
                    l = [],
                    a = {
                        delimiter: s.delimiter,
                        separator: s.separator,
                        onParseEntry: a.onParseEntry,
                        onParseValue: a.onParseValue,
                        start: a.start,
                        end: a.end,
                        state: {
                            rowNum: 1,
                            colNum: 1
                        },
                        match: !1
                    },
                    n = {
                        delimiter: s.delimiter,
                        separator: s.separator,
                        start: 1,
                        end: 1,
                        state: {
                            rowNum: 1,
                            colNum: 1
                        }
                    },
                    c = e.csv.parsers.splitLines(r, n),
                    u = e.csv.toArray(c[0], a),
                    o = e.csv.parsers.splitLines(r, a);
                a.state.colNum = 1, u ? a.state.rowNum = 2 : a.state.rowNum = 1;
                for (var m = 0, f = o.length; m < f; m++) {
                    var p = e.csv.toArray(o[m], a),
                        d = {};
                    for (var v in u) d[u[v]] = p[v];
                    l.push(d), a.state.rowNum++
                }
                if (!s.callback) return l;
                s.callback("", l)
            },
            fromArrays: function(r, a, t) {
                var a = void 0 !== a ? a : {},
                    s = {};
                if (s.callback = void 0 !== t && "function" == typeof t && t, s.separator = "separator" in a ? a.separator : e.csv.defaults.separator, s.delimiter = "delimiter" in a ? a.delimiter : e.csv.defaults.delimiter, s.escaper = "escaper" in a ? a.escaper : e.csv.defaults.escaper, s.experimental = "experimental" in a && a.experimental, !s.experimental) throw Error("not implemented");
                var o = [];
                for (i in r) o.push(r[i]);
                if (!s.callback) return o;
                s.callback("", o)
            },
            fromObjects2CSV: function(r, a, t) {
                var a = void 0 !== a ? a : {},
                    s = {};
                if (s.callback = void 0 !== t && "function" == typeof t && t, s.separator = "separator" in a ? a.separator : e.csv.defaults.separator, s.delimiter = "delimiter" in a ? a.delimiter : e.csv.defaults.delimiter, s.experimental = "experimental" in a && a.experimental, !s.experimental) throw Error("not implemented");
                var o = [];
                for (i in r) o.push(arrays[i]);
                if (!s.callback) return o;
                s.callback("", o)
            }
        }, e.csvEntry2Array = e.csv.toArray, e.csv2Array = e.csv.toArrays, e.csv2Dictionary = e.csv.toObjects
    }(jQuery);