/* Minification failed. Returning unminified contents.
(2065,69-70): run-time error JS1014: Invalid character: `
(2065,70-71): run-time error JS1195: Expected expression: <
(2065,79-80): run-time error JS1005: Expected '(': =
(2065,102-107): run-time error JS1195: Expected expression: class
(2065,183-184): run-time error JS1195: Expected expression: <
(2065,190-191): run-time error JS1014: Invalid character: `
(2068,22-23): run-time error JS1100: Expected ',': )
(2071,9-10): run-time error JS1002: Syntax error: }
(2072,40-41): run-time error JS1195: Expected expression: )
(2072,42-43): run-time error JS1004: Expected ';': {
(2089,10-11): run-time error JS1195: Expected expression: )
(2095,26-27): run-time error JS1004: Expected ';': {
(2169,1-2): run-time error JS1002: Syntax error: }
 */
/*_/^\_I_/^\_N_/^\_F_/^\_I_/^\_N_/^\_I_/^\_T_/^\_E_/^\_

 (c) Copyright Infinite Talent 2021  

`\V/'I`\V/'N`\V/'F`\V/'I`\V/'N`\V/'I`\V/'T`\V/'E`\V/'*/




/*
// NoComment PRESERVE START
*/

window.initFormsMethods = function () {

    var isMobile = false;
    var errormsgs = "";
    var draftMode = false;
    var calcFailed = false;
    var confirmCalc = false;
    var reroutefields = {};
    var reroutecompfields = {};
    var rerouteconf = false;
    var btnClicked = false;
    var bdg;
    var ajaxresponse;
    var applyMode = false;
    var msgs = {};
    var where = $("input[name='where']").val();
    var hidQBFields = [];
    var faxmlObj = null;
    var formulaFields = [];
    var hasCalcFields = false;
    var prevFAParent = "";
    var faFields = {};

    if ($("input[type='reset']").length > 0) {

        $("input[type='reset']").trigger("click");
    }
    msgs = eval('(' + $("#msgs").val() + ')');



    // QUESTION BRANCHING OBJECT START
    var QBObj = {
        checkQBFA: function () {
            $.each($("[enableparent='1']"), function (index, value) {

                if ($(value).attr("qbparent") == "1") {
                    QBObj.showChild(value);
                }


            });

            $.each($("[qbparent='1'][enableparent='0']"), function (index, value) {

                QBObj.showChild(value);

            });
        },
        displayQBChildren: function (obj, type, hide) {

            if (type == "select") {
                var qbchildren = "";
                $(obj).find("option:selected").each(function () { if (qbchildren.indexOf("," + $(this).attr("qbchildren") + ",") == -1) qbchildren += ("," + $(this).attr("qbchildren") + ",") });

                var prevqbchildren = "";
                if ($(obj).attr("prevval") && $(obj).attr("prevval") != "") {
                    $.each($(obj).attr("prevval").split(","), function (index, value) { var qbopt = $(obj).find("option[value='" + value.replace(/'/g,"\\'") + "']").first().attr("qbchildren"); if (prevqbchildren.indexOf("," + qbopt + ",") == -1) prevqbchildren += ("," + qbopt + ",") })
                }

                qbchildren = typeof qbchildren != "undefined" && !hide ? qbchildren.split(',') : [];
                prevqbchildren = typeof prevqbchildren != "undefined" ? prevqbchildren.split(',') : [];
                $(obj).attr("prevval", $(obj).val());

                this.executeQB(prevqbchildren, qbchildren);

            }
            else {

                var qbchildren = "";
                var controlVal = "";
                $("input[name='" + $(obj).attr("name").replace(/'/g, "\\'") + "']:checked").each(function () { if (qbchildren.indexOf("," + $(this).attr("qbchildren") + ",") == -1) qbchildren += ("," + $(this).attr("qbchildren") + ","); controlVal += ("," + $(this).val()); });

                var prevqbchildren = "";
                if ($(obj).attr("prevval") && $(obj).attr("prevval") != "") {
                    $.each($(obj).attr("prevval").split(","), function (index, value) { if (value != "") { var qbopt = $("[name=" + $(obj).attr('name') + "][value='" + value.replace(/'/g, "\\'") + "']").first().attr("qbchildren"); if (prevqbchildren.indexOf("," + qbopt + ",") == -1) prevqbchildren += ("," + qbopt + ","); } })
                }

                qbchildren = typeof qbchildren != "undefined" && !hide ? qbchildren.split(',') : [];
                prevqbchildren = typeof prevqbchildren != "undefined" ? prevqbchildren.split(',') : [];


                $("[name='" + $(obj).attr("name").replace(/'/g, "\\'") + "']").each(function (index, value) {
                    $(value).attr("prevval", controlVal);


                });

                this.executeQB(prevqbchildren, qbchildren);
            }


        },
        executeQB: function (prevqbchildren, qbchildren) {

            $.each(prevqbchildren, function (index, value) {
                if (value != "" && value != "undefined") {
                    if ($("[name*='" + value + "']").length == 0) return;
                    var $childControl;
                    if ($("[name*='" + value + "']").attr("name").match(/jsq/g))
                        $childControl = $("[name*='jsq-" + value + "_']");
                    else if ($("[name*='profile_" + value + "']").length > 0) {
                        $childControl = $("[name*='profile_" + value + "_']");
                        if ($childControl.attr("name").match(/profile_-5_/g)) {
                            $("[name*='profile_-3_']").val($childControl.val());
                        }
                        else if ($childControl.attr("name").match(/profile_-3_/g)) {
                            $("[name*='profile_-5_']").val($childControl.val());
                        }
                    }
                    else
                        $childControl = $("[name*='custom_" + value + "_']");

                    if ($childControl.attr("name").match(/lbl/g)) {
                        $childControl.parent().addClass("hiddenQB");

                    }
                    else {
                        $childControl.closest(".fieldcontain").addClass("hiddenQB");
                    }                   
                    QBObj.updateQBArr($childControl, "hide");
                    if ($childControl.attr("qbparent") == "1")
                        QBObj.displayQBChildren($childControl, $childControl.prop("tagName").toLowerCase(), true);
                }
            });
            $.each(qbchildren, function (index, value) {
                if (value != "" && value != "undefined") {
                    if ($("[name*='" + value + "']").length == 0) return;
                    var $childControl;
                    if ($("[name*='" + value + "']").attr("name").match(/jsq/g))
                        $childControl = $("[name*='jsq-" + value + "_']");
                    else if ($("[name*='profile_" + value + "']").length > 0) {
                        $childControl = $("[name*='profile_" + value + "_']");
                        if ($childControl.attr("name").match(/profile_-5_/g)) {
                            $("[name*='profile_-3_']").val($childControl.val());
                        }
                        else if ($childControl.attr("name").match(/profile_-3_/g)) {
                            $("[name*='profile_-5_']").val($childControl.val());
                        }
                    }
                    else
                        $childControl = $("[name*='custom_" + value + "_']");

                    if ($childControl.attr("name").match(/lbl/g)) {
                        $childControl.parent().removeClass("hiddenQB");
                    }
                    else {

                        $childControl.closest(".fieldcontain").removeClass("hiddenQB");
                    }

                    if (typeof $childControl.closest(".fieldcontain").css("background-color") != "undefined" && !$childControl.closest(".fieldcontain").css("background-color").match(/255/gi)) {
                        $childControl.closest(".fieldcontain").effect("highlight", {}, 0);
                    }
                    QBObj.updateQBArr($childControl, "show");
                    if ($childControl.attr("qbparent") == "1")
                        QBObj.displayQBChildren($childControl, $childControl.prop("tagName").toLowerCase(), false);
                }
            });

        },
        loadQBSections: function () {
            $.each($("#hidSections").val().split(","), function (index, value) {
                if (value != "") {
                    $("#" + value).css({ "display": "none" });
                }
            });
            if ($("#hidQB").length > 0) {
                hidQBFields = $("#hidQB").val().split(",");
            }

        },
        updateQBArr: function (obj, mode) {
            var qid = obj.attr("name").split("_")[1];
            var qindex = $.inArray(qid, hidQBFields);
            if (qindex != -1 && mode == "show") {
                hidQBFields.splice(qindex, 1);
            }
            else if (qindex == -1 && mode == "hide") {
                hidQBFields.push(qid);
            }
          
        },
        ClearChildren: function (obj) {

            $.each(obj, function (index, element) {
                switch (element.type) {
                    case 'radio':
                        if ($(element.nextSibling) != '' && $(element.nextSibling) != null) {
                            $(element.nextSibling).removeClass("checked");
                        }
                        break;

                    case 'text':
                        $(element).val("");
                        break;
                    case 'textarea':
                        $(element).val("");
                        break;

                    case 'email':
                        $(element).val("");
                        break;

                    case 'search':
                        $(element).val("");
                        break;

                    case 'number':
                        $(element).val("");
                        break;

                    case 'checkbox':
                        if ($(element.nextSibling) != '' && $(element.nextSibling) != null) {
                            $(element.nextSibling).removeClass("checked")
                        }
                        break;

                    case 'select-one':
                        angular.element(element).scope().aoSelections = [];
                        $("#" + element.id + "-button_text ")[0].textContent = "";
                        $("#" + element.id)[0].options.selectedIndex = 0;
                        break;

                    case 'select-multiple':
                        angular.element(element).scope().aoSelections = [];
                        $("#" + element.id + "-menu span.checked").removeClass("checked");
                        break;

                }

            });
        },
        showQBSections: function () {
            $.each($("div[id*='ls_']"), function (index, value) {
                var show = false;

                $(value).find("div.fieldcontain,h3").each(function (i, v) {

                    var $vobj = $(v).parent().hasClass("ui-bar-d") ? $(v).parent() : $(v);
                    if ($vobj.css("display") == "block" || $vobj.css("display") == "inline-block" || $vobj.css("display") == "inline") {
                        $(value).css({ "display": "block" });
                        show = true;
                        return false;
                    }

                });


                if (!show) {
                    $(value).css({ "display": "none" });
                }

            });
        },
        showChild: function (obj) {

            if ($(obj).prop("tagName").toLowerCase() == "select") {
                $(obj).attr("prevval", $(obj).val());
                $(obj).on("change",function () {

                    QBObj.displayQBChildren(obj, "select");
                });
            } else {
                var controlVal = "";
                $("input[name='" + $(obj).attr("name") + "']:checked").each(function () { controlVal += ("," + $(this).val()); });
                $(obj).attr("prevval", controlVal);
                $(obj).on("click",function () {
                    QBObj.displayQBChildren(obj, "radiocheckbox");
                   
                });

            }


        }
    }
    // QUESTION BRANCHING OBJECT END

    QBObj.checkQBFA();

    //FA OBJECT START
    var FAObj = {
        serialize: function () {
            var result = "";

            for (var k in faFields) {

                if (typeof k.query != "undefined" && k.query != "") {
                    result += ("&" + k + "-query=" + k.query);
                }
                result += ("&" + k + "=");
                if (typeof k.responses != "undefined" && k.responses.length > 0) {
                    result += ("&" + k + "-query=" + k.query);
                }

            }
        },

        makeFACall: function (fieldData) {
            var fieldDel = '~|~';
            var nmValDel = '_|_';
            var pval = "";
            var mselval = "";
            var aqid = "";

            $.each($("[enableparent='1']"), function (index, value) {
                if ($(value).attr("type") == "radio" || $(value).attr("type") == "checkbox") {

                    if (pval.indexOf($(value).attr("name")) == -1) {
                        pval += fieldDel + $(value).attr("name") + nmValDel;
                        if ($(value).is(":checked")) {
                            pval += $(value).val();
                        }
                        aqid += fieldDel + $(value).attr("name");
                    }
                    else if ($(value).is(":checked")) {
                        pval += $(value).val();

                    }
                }
                else {
                    var fieldVal = "";
                    $(value).find("option:selected").each(function (index, value) { fieldVal += ($(this).val()) });
                    pval += fieldDel + $(value).attr("name") + nmValDel + fieldVal;
                    aqid += fieldDel + $(value).attr("name");
                }
            });

            $.each($("[enablechild='1']"), function (index, value) {
                if ($(value).attr("type") == "radio" || $(value).attr("type") == "checkbox") {

                    if (mselval.indexOf($(value).attr("name")) == -1) {
                        mselval += fieldDel + $(value).attr("name") + nmValDel;
                        if ($(value).is(":checked")) {
                            mselval += $(value).val();

                        }
                        aqid += fieldDel + $(value).attr("name");
                    }
                    else if ($(value).is(":checked")) {
                        mselval += $(value).val();

                    }
                }
                else {
                    var fieldVal = "";
                    $(value).find("option:selected").each(function (index, value) { fieldVal += ($(this).val()) });
                    mselval += fieldDel + $(value).attr("name") + nmValDel + fieldVal;
                    aqid += fieldDel + $(value).attr("name");
                }
            });

            fieldData.pval = pval;
            fieldData.mselval = mselval;
            fieldData.aqid = aqid;
            fieldData.pnval = fieldData.pnval.replace("&", "^amp^");
            var $pnobj = $("[name='" + fieldData.pnm + "']");
            if ($("#loadingajax").length == 0) {
                if ($pnobj.prop("tagName").toLowerCase() == "select") {
                    $pnobj.before('<span id="loadingajax" class="ui-autocomplete-loading"></span>');
                }
                else if ($pnobj.prop("tagName").toLowerCase() == "input") {
                    $pnobj.closest(".ui-controlgroup-controls").after('<span id="loadingajax" class="ui-autocomplete-loading"></span>');
                }
            }
            $.ajax({
                type: "POST",
                url: "/FieldAssociations.UserInterface/FieldAssocGateway.aspx",
                data: fieldData,
                crossdomain: true
            }).then(function (response) {
                if (prevFAParent == fieldData.pnm) {
                    faxmlObj = response;
                }
                $("#save").css({ "visibility": "hidden" });
                $(response).children("faquestions").attr("pnm", fieldData.pnm);

                processFAResponse(response, "useract");
                $("#save").css({ "visibility": "visible" });
                $("#loadingajax").remove();
            });

        },


        faResponse: function processFAResponse(response, mode) {
            hasCalcFields = false;
            var pageMode = document.location.href.match(/add/gi) && mode == "load" ? "add" : "";
            $(response).children("faquestions").children("question").each(function () {

                var questionid = $(this).attr("QuestionID");
                var seltype = $(this).attr("selecttype");
                var type = $(this).attr("fieldtype");

                if ((mode == "load" && (type != "text" && type != "numeric" && pageMode != "add")) || ($("[name*='_" + questionid + "_']").length == 0)) {
                    return;
                }

                var $control = $("[name*='_" + questionid + "_']").first();
                var controltype = $control.attr("type") ? $control.attr("type") : "";
                type = (controltype == "hidden" ? controltype : type);
                var name = $control.attr("name");
                var qbparent = typeof $control.attr("qbparent") != "undefined" ? " qbparent='" + $control.attr("qbparent") + "'" : "";
                var enableparent = typeof $control.attr("enableparent") != "undefined" ? " enableparent='" + $control.attr("enableparent") + "'" : "";
                var enablechild = typeof $control.attr("enablechild") != "undefined" ? " enablechild='" + $control.attr("enablechild") + "'" : "";
                var $container = $control.closest(".fieldcontain");
                var html = "";
                faFields[name] = {};
                faFields[name].responses = [];
                switch (type) {
                    case "single-select":
                    case "multi-select":
                    case "query-select":
                        html += "<option value=''>Choose..</option>";
                        if ($(this).find("query1").length > 0) {


                            var qbchildren = $(this).find("qbchildren").text().length > 0 ? " qbchildren='" + $(this).find("qbchildren").text() + "'" : [];
                            var selectedvalues = $(this).find("selectedvalues").text().split(",");
                            var selecteddescriptions = $(this).find("selecteddescriptions").length > 0 ? $(this).find("selecteddescriptions").text().split(",") : selectedvalues;
                            var keyval = {};
                            $.each(selecteddescriptions, function (index, value) {
                                var arrvals = value.split("^|^");
                                var val = (arrvals.length > 1 ? arrvals[1] : arrvals[0]).replace("#@#", "");
                                var key = arrvals[0];
                                keyval[key] = val;
                            });
                            if (typeof selectedvalues != "undefined") {

                                $.each(selectedvalues, function (index, value) {

                                    if (value != "") {
                                        var selected = " selected";
                                        var desc = keyval[$.trim(value.replace("#@#", ""))];

                                        html += "<option value='" + $.trim(value).replace(/'/g, "&#39;") + "'" + selected + qbchildren + ">" + desc + "</value>";
                                        var $searchControl = $("#" + $control.attr("name") + "-input");
                                        if ($searchControl.length > 0) {

                                            if (seltype != "multi-select" && type != "multi-select") {
                                                $searchControl.val(desc);
                                            }
                                        }
                                        faFields[name].respones.push(value);
                                    }
                                });
                            }

                        }
                        else {
                            if (pageMode == "add") {

                                $(this).children("option[selected='true']").each(function (index, value) {

                                    var $controlopt = $control.find("option[value='" + $(value).attr("code").replace(/'/g,"\\'") + "']");
                                    if ($controlopt.length > 0) {
                                        $controlopt.prop("selected", true);
                                    }
                                });
                            }
                            else {
                                $(this).children("option").each(function (index, value) {

                                    var selected = $(value).attr("selected") == "true" ? " selected" : "";
                                    var qbchildren = typeof $(value).attr("qbchildren") != "undefined" ? " qbchildren='" + $(value).attr("qbchildren") + "'" : "";
                                    html += "<option value='" + $(value).attr("code").replace(/'/g, "&#39;") + "'" + selected + qbchildren + ">" + $(value).attr("optiondesc") + "</option>";
                                });

                            }
                        }
                        if (pageMode != "add" || $(this).find("query1").length > 0) {
                            $control.html(html);
                        }
                        if (seltype != "multi-select" && type != "multi-select" && $(this).find("query1").length == 0 && isMobile) {

                            $control.selectmenu().selectmenu("refresh");;

                        }


                        if (typeof $control.attr("multiple") != "undefined") {
                            if (!isMobile) {
                                var $group = $control.closest(".fieldcontain").find("fieldset");

                                if ($group.length > 0) {
                                    updateMultiSS($group, $control);
                                }
                            }
                            else {
                                $control.selectmenu().selectmenu("refresh");
                            }
                        }


                        if ($control.parent().css('display') == "block")
                            displayQBChildren($control, "select");


                        break;
                    case "checkbox":
                    case "radio":
                        var $group = $control.parent().parent().parent();
                        if (pageMode != "add") {
                            if ($control.attr("qbparent") == "1") {
                                $("input[name='" + name + "']:checked").each(function () { $(this).prop('checked', false); });
                                displayQBChildren($control, "checkboxradio");
                            }
                            $control.parent().parent().empty();
                        }
                        if (pageMode == "add") {
                            $(this).children("option[selected='true']").each(function (index, value) {
                                var $controlopt = $group.find("input[value='" + $(value).attr("code") + "']");
                                if ($controlopt.length > 0) {
                                    $controlopt.prop("checked", true).checkboxradio().checkboxradio('refresh');
                                }
                            });
                        }
                        else {
                            $(this).children("option").each(function (index, value) {

                                var checked = $(value).attr("selected") == "true" ? " checked" : "";
                                var qbchildren = typeof $(value).attr("qbchildren") != "undefined" ? " qbchildren='" + $(value).attr("qbchildren") + "'" : "";

                                html += "<input type='" + type + "' value='" + $(value).attr("code") + "'" + checked + qbchildren + qbparent + enableparent + enablechild + " name='" + name + "' id='" + name + "-" + $(value).attr("code") + "' crb='true'>";
                                html += "<label for='" + name + "-" + $(value).attr("code") + "'>" + $(value).attr("optiondesc") + "</label>";
                            });
                        }

                        if (pageMode != "add") {

                            $group.controlgroup().controlgroup("container").append(html);
                        }
                        $group.controlgroup().enhanceWithin().controlgroup("refresh");


                        if ($control.attr("enableparent") == "1") {

                            $($group).find("input").each(function (index, value) {
                                if (pageMode != "add") {

                                    if ($control.attr("qbparent") == "1") {
                                        showChild(value);
                                    }
                                    $(value).on("click",function () {
                                        var data = { pnm: $(value).attr("name"), pnval: $(value).val(), src: "usract", pval: "", aqid: "", ftid: $("input[name='formtypeid']").val(), lang: $("input[name='flanguage']").val(), mselval: "" };
                                        makeFACall(data);

                                    });
                                }
                                if ($control.attr("qbparent") == "1" && $(value).is(":checked") && $group.parent().css('display') == "block") {
                                    displayQBChildren($(value), "checkboxradio");
                                    $(value).prop('checked', true).checkboxradio('refresh');
                                }

                            });


                        }
                        else if ($control.attr("qbparent") == "1") {
                            $($group).find("input").each(function (index, value) {
                                if (pageMode != "add") {
                                    showChild(value);
                                }
                                if ($(value).is(":checked") && $group.parent().css('display') == "block") {
                                    displayQBChildren($(value), "checkboxradio");
                                    $(value).prop('checked', true).checkboxradio('refresh');
                                }

                            });
                        }


                        break;
                    case "text":
                    case "textarea":
                    case "numeric":
                    case "email":
                    case "ssn":
                        $(this).children("option").each(function (index, value) {
                            var $opt = $(response).children("faquestions").children("option[questionid='" + questionid + "']");
                            if ($opt.length > 0) {
                                $opt.attr("dbfieldname", $(value).parent().attr("dbfieldname"));
                                $opt.attr("fieldtype", $(value).parent().attr("fieldtype"));
                            }
                            var res = calculate($opt.length > 0 ? $opt : value, response, "load");

                            $control.val(res);
                            if ($control.prop("tagName").toLowerCase() == "textarea" && $("#" + $control.attr("id") + "-input").length > 0) {
                                $("#" + $control.attr("id") + "-input").html(res);
                            }
                            $control.valid();


                        });
                        if ($(this).children("option").length == 0 && mode != "load") {
                            $control.val("");
                            if ($control.prop("tagName").toLowerCase() == "textarea" && $("#" + $control.attr("id") + "-input").length > 0) {
                                $("#" + $control.attr("id") + "-input").html("");
                            }
                            $control.rules("remove", "calcvalidation");
                            $control.valid();
                        }
                        break;
                    case "hidden":

                        $(this).children("option").each(function (index, value) {

                            if (typeof $(value).attr("code") != "undefined" && typeof $(value).attr("selected") != "undefined" && $(value).attr("selected") == "true") {
                                if ($control.length > 0) {
                                    $control.parent().find('.lblview').html((index > 0 ? ($control.parent().find('.lblview').html() + "<br/>") : "") + $(value).attr("optiondesc"));
                                    $control.val((index > 0 ? ($control.val()) : "") + $(value).attr("code"));
                                }
                                else
                                    faFields[name].responses.push($(value).attr("code"));
                            }
                            else {
                                var $opt = $(response).children("faquestions").children("option[questionid='" + questionid + "']");
                                if ($opt.length > 0) {
                                    $opt.attr("dbfieldname", $(value).parent().attr("dbfieldname"));
                                    $opt.attr("fieldtype", $(value).parent().attr("fieldtype"));
                                }
                                var res = calculate($opt.length > 0 ? $opt : value, response, "load");
                                if ($control.length > 0) {
                                    $control.parent().find('.lblview').html(res);
                                    $control.val(res);
                                    $control.valid();
                                }
                                else
                                    faFields[name].responses.push(res);
                            }
                        });
                        if ($(this).children("option").length == 0 && mode != "load") {
                            $control.val("");
                            $control.parent().find('.lblview').html("");
                            $control.rules("remove", "calcvalidation");
                            $control.valid();
                        }
                        break;

                }
                if (($container.css("display") == "block" || $container.css("display") == "inline-block") && typeof $container.css("background-color") != "undefined" && !$container.css("background-color").match(/255/gi)) {
                    $container.effect("highlight", {}, 2000);
                }
            });

            processCalculatedFields(response);

        },

        calculateXml: function updateCalcFAXml(response) {
            $(response).find("option[formula]").each(function (index, value) {
                $(value).text($(value).attr("formula"));
            });
        },
        calculate: function calculate(value, response, mode) {
            var res = "";

            if ($(value).text().match(/@[\w]*@/gi) || $(value).text().match(/#\[/gi)) {
                $("#recalculate").css({ "display": "inline" });
                if (!hasCalcFields) {
                    hasCalcFields = true;
                    faxmlObj = response;
                    prevFAParent = $(response).children("faquestions").attr("pnm");
                }
                if (mode == "load") {
                    $(value).attr("formula", $(value).text());
                }
                var matches = $(value).text().match(/@[\w]*@/gi);
                var fo = {};
                fo.formula = $(value).text().replace("#[", "").replace("]#", "");
                fo.fields = [];
                fo.dbfieldname = $(value).attr("dbfieldname") ? $(value).attr("dbfieldname") : $(value).parent().attr("dbfieldname");
                fo.questionid = $(value).attr("questionid");
                var flg = false;
                var $ff;
                var $opt;

                if (matches != null) {
                    $.each(matches, function (i, v) {
                        v = v.replace(/@/g, "");
                        if ($(response).find("question[dbfieldname='" + v + "']").length > 0) {
                            $ff = $(response).find("question[dbfieldname='" + v + "']");
                            $opt = $(response).children("faquestions").children("option[questionid='" + $ff.attr("QuestionID") + "']");

                            $ff = $opt.length > 0 ? $opt : $ff.children("option").first();
                            if ($ff.text().match(/@[\w]*@/gi)) {
                                fo.fields.push({ field: v, type: "1" });
                                flg = true;
                            }
                            else {
                                var fieldres = $("[dbfieldname='" + v + "']").length > 0 ? $("[dbfieldname='" + v + "']").first().val() : "";
                                var fares = fieldres != "" || $ff.text().match(/#\[/gi) ? fieldres : $ff.text();
                                if (fares != "") {
                                    fo.formula = fo.formula.replace("@" + v + "@", fares);
                                    fo.fields.push({ field: v, type: "2" });
                                }
                                else
                                    flg = true;
                            }

                        }
                        else {
                            var fieldres = $("[dbfieldname='" + v + "']").length > 0 ? $("[dbfieldname='" + v + "']").first().val() : "";

                            if (fieldres != "") {

                                fo.formula = fo.formula.replace("@" + v + "@", fieldres);
                                fo.fields.push({ field: v, type: "3" });

                            }
                            else
                                flg = true;
                        }
                    });
                }

                if (!flg) {
                    var mt = fo.formula.match(/\d*%/gi);

                    if (mt != null && mt.length > 0) {
                        $.each(mt, function (mi, mv) {
                            fo.formula = fo.formula.replace(new RegExp(mv, "gi"), "(" + mv + ")");
                        });
                    }

                    res = fo.formula.replace("%", "/100");
                    var comparefield = "";

                    var fv = "";
                    var fvarr = [];
                    var $field;
                    if (res.match(/max|min|between/gi)) {
                        fvarr = res.split(":");
                        fv = fvarr[0];
                        comparefield = fv.substring(fv.indexOf("(") + 1, fv.indexOf(")"));

                        if (fvarr.length > 1) {
                            res = res.split(":")[1];
                        }
                        else {
                            $field = $("[dbfieldname='" + fo.dbfieldname + "']").first();
                            res = $field.val();
                        }

                    }
                    try {

                        if (res != "") {
                            if ($(value).parent().attr("fieldtype") == "numeric" || $(value).attr("fieldtype") == "numeric") {
                                res = Math.round(eval('(' + res + ')'));
                            }
                            else {
                                res = eval('(' + res + ')');
                            }
                        }
                        if (fv.match(/max/gi)) {
                            if ((parseFloat(res) > parseFloat(comparefield)) || $.trim(res) == "") {
                                flg = true;
                                fo.formula = "#[" + fo.formula + "]#";
                                formulaFields.push(fo);
                                if (fvarr.length > 1 || $.trim(res) == "") {
                                    res = "";
                                }
                                else {
                                    $field.attr("maxcalc", comparefield);
                                }
                            }
                            else {
                                if ($field != null && $field.attr("maxcalc"))
                                    $field.attr("maxcalc", comparefield);
                            }

                        }
                        else if (fv.match(/min/gi)) {
                            if ((parseFloat(res) < parseFloat(comparefield)) || $.trim(res) == "") {
                                flg = true;
                                fo.formula = "#[" + fo.formula + "]#";
                                formulaFields.push(fo);
                                if (fvarr.length > 1 || $.trim(res) == "") {
                                    res = "";
                                }
                                else {
                                    $field.attr("mincalc", comparefield);
                                }
                            }
                            else {
                                if ($field != null && $field.attr("maxcalc"))
                                    $field.attr("mincalc", comparefield);
                            }
                        }
                        else if (fv.match(/between/gi)) {
                            if (!comparefield.match(/,/) || !(parseFloat(res) >= parseFloat(comparefield.split(",")[0]) && parseFloat(res) <= parseFloat(comparefield.split(",")[1])) || $.trim(res) == "") {
                                flg = true;
                                fo.formula = "#[" + fo.formula + "]#";
                                formulaFields.push(fo);
                                if (fvarr.length > 1 || $.trim(res) == "") {
                                    res = "";
                                }
                                else {
                                    $field.attr("betweencalc", comparefield);
                                }
                            }
                            else {
                                if ($field != null && $field.attr("betweencalc"))
                                    $field.attr("betweencalc", comparefield);
                            }
                        }

                    }
                    catch (ex) { res = ""; }
                    if (fv != "" && flg) {
                        $(value).text(fo.formula);
                    }
                    else {
                        $(value).text(res);
                    }

                }
                else {
                    fo.formula = fo.formula.replace("%", "/100");
                    $(value).text(fo.formula);
                    formulaFields.push(fo);
                }

            }
            else {
                res = $(value).text();
            }


            return res;

        },

        processCalculatedFields: function processCalculatedFields(response) {
            var res = "";
            var finalArr = formulaFields.concat([]);
            formulaFields = [];
            $.each(finalArr, function (index, value) {
                var $field = $("[dbfieldname='" + finalArr[index].dbfieldname + "']").first()
                var $opt = $(response).children("faquestions").children("option[questionid='" + finalArr[index].questionid + "']");
                var $question = $opt.length > 0 ? $opt : $(response).find("question[dbfieldname='" + finalArr[index].dbfieldname + "']");

                if ($opt.length > 0 || $question.length > 0) {
                    var $value = $opt.length > 0 ? $opt : $question.children("option");
                    var res = calculate($value, response, "check");
                    if (res != "") {
                        $field.val(res);
                        $field.valid();
                    }
                }
            });

            if (formulaFields.length > 0 && finalArr.length != formulaFields.length) {
                processCalculatedFields(response);
            }
            else {

                if (formulaFields.length > 0) {

                    $.validator.addMethod("calcvalidation", function (value, element, param) {
                        if (value != "" || confirmCalc) {

                            if (!confirmCalc) {
                                var fieldatt = $(element).attr("mincalc") ? "min:" + $(element).attr("mincalc") : ($(element).attr("betweencalc") ? "between:" + $(element).attr("betweencalc") : ($(element).attr("maxcalc") ? "max:" + $(element).attr("maxcalc") : ""));

                                if (fieldatt.match(/min/gi)) {
                                    if (parseFloat(value) < parseFloat(fieldatt.split(":")[1])) {
                                        calcFailed = true;
                                        return false;
                                    }
                                }
                                else if (fieldatt.match(/max/gi)) {

                                    if (parseFloat(value) > parseFloat(fieldatt.split(":")[1])) {
                                        calcFailed = true;
                                        return false;
                                    }
                                }
                                else if (fieldatt.match(/between/gi)) {
                                    var bw = fieldatt.split(":")[1];
                                    var minval = bw.split(",")[0];
                                    var maxval = bw.split(",")[1];
                                    if (!(parseFloat(value) >= minval && parseFloat(value <= maxval))) {
                                        calcFailed = true;
                                        return false;
                                    }
                                }
                            }

                            return true;
                        }
                        else {
                            calcFailed = true;
                            return false;
                        }

                    }, "Calculation/Validation failed");


                    $.each(formulaFields, function (index, value) {
                        var $field = $("[dbfieldname='" + formulaFields[index].dbfieldname + "']").first();
                        $field.rules("add", {
                            calcvalidation: ""
                        });

                        $field.valid();
                    });


                    formulaFields = [];
                }

            }

            if (hasCalcFields)
                updateCalcFAXml(response);
        },
        processFATextFields: function processFATextFields() {
            processFAResponse(faxmlObj != null ? faxmlObj : $.parseXML($("input[name='hidfaxml']").val()), "load");
        }
    }
    //FA OBJECT END


    // PAGE NAVIGATION OBJECT START
    var navigationFn = {

        visiblePage: function getVisiblePage() {

            var $pageObj = {};
            $("div[id*='page_']").each(function (index, value) {

                $pageObj = $(value);
                return false;

            });
            return $pageObj;
        },
        visiblePageWithId: function getVisiblePageWithId(pageId) {
            var $pageObj = {};
            $pageObj = $("div#page_" + pageId);
            return $pageObj;
        }
    }

    // PAGE NAVIGATION OBJECT END



    // GENERAL DOM MANIPULATION START
    var DomFunc = {
        setLabels: function setLabels() {
            try {
                var lblarr = document.querySelectorAll("label,legend,h3,span.lblview");
                var stop = lblarr.length;
                for (var k = 0; k < stop; k++) {
                    if (lblarr[k].className.indexOf("checkbox") != 0) {
                        lblarr[k].innerHTML = lblarr[k].innerHTML.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
                        applyScope.compileInnerHtml(lblarr[k]);
                    }

                }

                if (document.getElementById("rDiv")) {
                    document.getElementById("rDiv").innerHTML = document.getElementById("rDiv").innerHTML.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
                    applyScope.compileInnerHtml(rDiv);
                }
            }
            catch (e) { }
        },
        showCollapsibleSections: function showCollapsibleSections(flg) {

            if (flg == "hide") {
                $.each($(".ui-accordion-content"), function (index, value) {
                    if (!$(value).hasClass("ui-accordion-content-active")) {
                        $(value).attr("show-hidden", "true");
                        $(value).css({ "display": "block" });

                    }
                });
            }
            else {

                $.each($(".ui-accordion-content"), function (index, value) {

                    if (typeof $(value).attr("show-hidden") != "undefined" && $(value).attr("show-hidden") == "true") {
                        $(value).css({ "display": "none" });
                        $(value).removeAttr("show-hidden");
                    }
                });

            }
        },
        upateTextArea: function upateTextArea() {
            $.each($(".ui-text-editor"), function (index, value) {
                if (typeof CKEDITOR.instances[$(this).attr("id")] != "undefined") {
                    $("#" + $(value).attr("id").replace("-input", "")).val(CKEDITOR.instances[$(value).attr("id")].getData());
                }
            }
        );
        },
        enhanceSelects: function enhanceSelects() {

            $.each($("select"), function (index, value) {

                if ($("#" + $(value).attr("name") + "-input").length == 0 && typeof $(value).attr("multiple") != "undefined") {

                    //$(value).multiselect({placeholder: ' Choose...'});
                }
                else if ($("#" + $(value).attr("name") + "-input").length > 0) {

                    $(value).closest(".fieldcontain").addClass("autocomplete");

                    $(value).attr("tabindex", "-1");
                    if (typeof $(value).attr("multiple") != "undefined") {
                        $(value).closest(".fieldcontain").addClass("multiple");


                        $(value).closest(".fieldcontain").find("[name*='-sscheck']").each(function () {

                            var $select = $("#" + $(this).attr("name").replace("-sscheck", ""));
                            $(this).on("click",function () {

                                if ($(this).is(":checked")) {
                                    $select.find("option[value='" + $(this).val().replace(/'/g, "\\'") + "']").prop("selected", "selected");
                                }
                                else {
                                    $select.find("option[value='" + $(this).val().replace(/'/g, "\\'") + "']").removeAttr("selected");
                                }
                                $select.trigger("change");

                            });
                        });
                    }
                }
            });

        },
        selectItem: function selectItem(ui, select) {

            // this is needed to deal with '.' used by adp in the wotc flow
            select = select.split(".").join("\\."); //.replace('.', "\\.");
            var $selectControl = $(select);
            var $clearbtn = $("#" + $selectControl.attr("name") + "-input").parent().find("a");

            if (typeof $selectControl.attr("multiple") == "undefined") {
                $selectControl.find("option:selected").each(function () { $(this).removeAttr("selected"); $(this).prop("selected", false); });
                $selectControl.find("option[value='" + ui.item.value.replace(/'/g, "\\'") + "']").first().prop("selected", "selected");
            } else {
                if ($selectControl.find("option[value='" + ui.item.value.replace(/'/g, "\\'") + "']").first().prop("selected"))
                    $selectControl.find("option[value='" + ui.item.value.replace(/'/g, "\\'") + "']").first().prop("selected", false);
                else
                    $selectControl.find("option[value='" + ui.item.value.replace(/'/g, "\\'") + "']").first().prop("selected", "selected");
            }
            $selectControl.trigger("change");

            if ($selectControl.attr("name").indexOf("profile") == 0 && $selectControl.attr("name").indexOf("_country_") > 0) {
                var $stateSelector = $(document.querySelector('.profile select[id*="_state_"]'));
                var $stateClearbtn = $("#" + $stateSelector.attr("name") + "-input").parent().find("a");
                $("#" + $stateSelector.attr("name")).val("");
                $("#" + $stateSelector.attr("name") + "-input").val("");
                //$("#" + $stateSelector.attr("name") + "-input").attr("placeholder", msgs.msgplaceholder);
                $stateSelector.find("option:selected").each(function () { $(this).removeAttr("selected"); $(this).prop("selected", false); });
                $stateClearbtn.removeClass("icon-remove");
            }
            if ($selectControl.attr("name").indexOf("education") == 0 && $selectControl.attr("name").indexOf("_schoolname_") > 0) {
                angular.element($("#" + $selectControl.attr("name") + "-input")).triggerHandler("change");
                $("#" + $selectControl.attr("name") + "-hidden").val(ui.item.value);
            }
            if ($selectControl.attr("name").indexOf("education") == 0 && $selectControl.attr("name").indexOf("_degree") > 0) {
                angular.element($("#" + $selectControl.attr("name") + "-input")).triggerHandler("change");
                $("#" + $selectControl.attr("name") + "-hidden").val(ui.item.value);
            }

            if (typeof $selectControl.attr("multiple") != "undefined") {

                var $group = $selectControl.closest(".fieldcontain").find("fieldset");
                this.updateMultiSS($group, $selectControl);
            }
            else {
                $clearbtn.removeClass("custom-icon-angle-down");
                $clearbtn.addClass("icon-remove");
            }
            $selectControl.closest(".fieldcontain").find("input.ui-search-widget").removeClass("error");
            $selectControl.valid();


        },
        updateMultiSS: function updateMultiSS(controlgroup, control) {
            return;
            var $group = $(controlgroup);
            var $selectControl = $(control);
            $group.find(".ui-controlgroup-controls").empty();

            var html = "";
            $selectControl.find("option:selected").each(function (index, value) {

                var checked = " checked";
                if ($(value).attr("value") != "") {
                    html += "<div class='ui-checkbox'>";
                    html += "<input type='checkbox' value='" + ($(value).attr("value")) + "'" + checked + "  name='" + ($selectControl.attr("name") + "-sscheck") + "' id='" + ($selectControl.attr("name") + "-sscheck") + "-" + $(value).attr("value") + "' crb='true'>";
                    html += "<label for='" + ($selectControl.attr("name") + "-sscheck") + "-" + $(value).attr("value") + "'>" + $(value).text() + "</label>";
                    html += "</div>";
                }

            });

            $group.find(".ui-controlgroup-controls").html(html);


            $group.find("input").each(function () {

                $(this).on("click",function () {
                    if ($(this).is(":checked")) {
                        $selectControl.find("option[value='" + $(this).val() + "']").prop("selected", "selected");
                    }
                    else {
                        $selectControl.find("option[value='" + $(this).val() + "']").removeAttr("selected");
                    }
                    $selectControl.trigger("change");

                });
            });
        },
        updateTA: function updateTA(objname, mode) {

            var $editorObj = $("#" + objname);
            var $txtareaObj = $("#" + $editorObj.attr("id").replace("-input", ""));

            if (mode == "update") {
                $editorObj.html((CKEDITOR.instances[objname + "-popup"].getData()));
            }

            if ($.trim($editorObj.html().replace("<br>", "")) == "") {
                $editorObj.addClass("errorauto");
                $txtareaObj.val("");
                $txtareaObj.valid();
            }
            else {
                $editorObj.removeClass("errorauto");
                $txtareaObj.val((CKEDITOR.instances[objname + "-popup"].getData()).replace(/>/g, "&gt;").replace(/</g, "&lt;"));
                $txtareaObj.valid();
            }

            CKEDITOR.instances[objname + "-popup"].destroy();
        }


    }
    // GENERAL DOM MANIPULATION END


    // FORM VALIDATION OBJECT START

    var validationObj = {

        setFormValidation: function () {
            $("form[name='applyForm']").validate({
                errorClass: 'error',
                validClass: 'success',
                errorElement: 'span',
                ignore: ".noValidate,div.hiddenQB input,div.hiddenQB select,div.hiddenQB textarea",
                onfocusout: false,
                highlight: function (element, errorClass, validClass) {
                    $(element).closest(".fieldcontain").addClass("invalid");
                    $(element).attr("aria-invalid", "true");
                },
                unhighlight: function (element, errorClass, validClass) {
                    var $parentElem = $(element).removeAttr("aria-describedby").closest(".fieldcontain");

                    if (element.getAttribute("type") == "search")
                        return;

                    $parentElem.removeClass("invalid");
                    $(element).removeAttr("aria-invalid");
                },
                errorPlacement: function (error, element) {

                    error.insertAfter(element.closest(".fieldcontain").children().last());

                },
                invalidHandler: function (form, validator) {
                    var validerrors = validator.numberOfInvalids();

                    if (validerrors) {

                        window.applyScope.page.errormsgs = [];
                        if (validator.errorList.length > 0) {
                            var fobj, fcontainer, $errorLabel, $errorSpan, $control;
                            for (x = 0; x < validator.errorList.length; x++) {
                                $control = $(validator.errorList[x].element);
                                fcontainer = $control.closest(".fieldcontain");
                                if (fcontainer.length > 0) {
                                    fobj = fcontainer.find("legend").length > 0 && !fcontainer.hasClass("autocomplete") ? fcontainer.find("legend").first() : $control.prev().is("label") ? $control.prev() : fcontainer.find("label").first();
                                    var errorLabel = "";
                                    //If its a Resumewidget change the label of the error
                                    if (fobj.hasClass('buildResumePad')) {
                                        errorLabel = $.trim($("#pagecontent").find("#resumeHeading").text());
                                    }
                                    else {
                                        if (fobj.closest("ul").hasClass("AddtoError") && typeof fobj.closest("ul").attr('aria-label') != "undefined" && fobj.closest("ul").attr('aria-label').length > 0)
                                            errorLabel = $.trim(fobj.closest("ul").attr('aria-label').replace(/(?:^|\s)\S/g, function (a) { return a.toUpperCase(); })) + " : " + $.trim(fobj.text().replace("*", "").replace("Click for tool tip.", ""));
                                        else
                                            errorLabel = $.trim(fobj.text().replace("*", "").replace("Click for tool tip.", ""));
                                    }
                                    window.applyScope.page.errormsgs.push({ label: errorLabel, error: validator.errorList[x].message });
                                }
                            }
                        }

                    }

                    _.delay(function () {
                        $(".errorContainer").scrollAndFocus();
                        $.pinToFold();
                    });
                }

            });
        },
        getDefaultDateFormat: function (inputDate) {
            var dateFormatSetting = "1";
            if (typeof appScope != "undefined" && typeof appScope.tgSettings != "undefined" && typeof appScope.tgSettings.DateFormat != "undefined") {
                dateFormatSetting = appScope.tgSettings.DateFormat;
            }
            var separatedBy = "/";
            var monthIndex = 0;
            var dayIndex = 1;
            var yearIndex = 2;
            if (dateFormatSetting == "1" || dateFormatSetting == "6" || dateFormatSetting == "7" || dateFormatSetting == "8") {
                monthIndex = 0;
                dayIndex = 1;
                yearIndex = 2;
            }
            else if (dateFormatSetting == "2" || dateFormatSetting == "3" || dateFormatSetting == "4" || dateFormatSetting == "5") {
                monthIndex = 1;
                dayIndex = 0;
                yearIndex = 2;
            }
            else if (dateFormatSetting == "9" || dateFormatSetting == "10" || dateFormatSetting == "11" || dateFormatSetting == "12") {
                monthIndex = 1;
                dayIndex = 2;
                yearIndex = 0;
            }
            //Get Month, Day and Year Indexes
            if (dateFormatSetting == "1" || dateFormatSetting == "2" || dateFormatSetting == "3" || dateFormatSetting == "6" || dateFormatSetting == "9") {
                separatedBy = "/";
            }
            else if (dateFormatSetting == "4" || dateFormatSetting == "7" || dateFormatSetting == "10" || dateFormatSetting == "12") {
                separatedBy = "-";
            }
            else if (dateFormatSetting == "5" || dateFormatSetting == "8" || dateFormatSetting == "11") {
                separatedBy = ".";
            }
            var dateInputs = inputDate.split(separatedBy);
            var defaultDateFormat = dateInputs[monthIndex] + "/" + dateInputs[dayIndex] + "/" + dateInputs[yearIndex];
            return defaultDateFormat;
        },
        addValidatorMethods: function () {
            $.validator.addMethod("daterange", function (value, element, param) {
                if (value === "")
                    return true;

                var $element = $(element),
                    inst = $element.data().datepicker;

                if (typeof $element.attr("dateReqex") !== "undefined") {
                    return ValidateDateConfiguration(value, $element.attr("dateReqex"), appScope.dynamicStrings.DateFormat);
                } else {
                    var minDate = $.datepicker._getMinMaxDate(inst, "min"),
                        maxDate = $.datepicker._getMinMaxDate(inst, "max");
                    var date;
                    if ($element.hasClass("monthyear")) {
                        date = moment(value, appScope.tgSettings.MonthYearFormat.trim(), true);
                    } else {
                        date = new Date(validationObj.getDefaultDateFormat(value));
                    }

                    return date < maxDate && date > minDate;
                }
            }, function (params, element) {
                var $element = $(element);
                var str;
                if (typeof $element.attr("dateReqex") !== "undefined") {
                    str = msgs.msgsInvalidNewDate;
                } else {
                    str = msgs.msgdaterange;
                    str = str.replace("[MINDATE]", $element.data().minDate);
                    str = str.replace("[MAXDATE]", $element.data().maxDate);
                }
                return str;
            }
            );

            $.validator.addMethod("notEqual", function (value, element, param) {
                return (value == "" || value.match(/^(\d{3}-\d{2}-\d{4})$/) ? true : false);
            }, msgs.msgssn);

            $.validator.addMethod("notInData", function (value, element, param) {
                return (element.getAttribute("inputTextNotInData") != "true");
            }, function (bValid, element) {
                return msgs.msgnomatches.replace("[search-term]", element.value);
            });

            $.validator.addMethod("datrequired", function (value, element, param) {
                var vdate = $("#" + $(element).attr("name").replace("year", "day")).val();
                var vmon = $("#" + $(element).attr("name").replace("year", "mon")).val();
                var dateval = (vdate + "-" + vmon + "-" + value);
                var datarr = dateval.split("-");
                return (dateval.length > 2 && (datarr[0] == "" || datarr[1] == "" || datarr[2] == "") ? false : true);

            }, msgs.msgrequired);

            $.validator.addMethod("dateformat", function (value, element, param) {

                var vdate = $("#" + $(element).attr("name").replace("year", "day")).val();
                var vmon = $("#" + $(element).attr("name").replace("year", "mon")).val();
                var dateval = new Date(value, vmon - 1, vdate);
                var convertedDate = "" + dateval.getFullYear() + (dateval.getMonth() + 1) + dateval.getDate();
                var givenDate = "" + value + vmon + vdate;
                return (givenDate == convertedDate || value == "") ? true : false;


            }, msgs.msgInValidDate);

            $.validator.addMethod("datestring", function (value, element, param) {
                if (!value)
                    return true;

                if ($(element).hasClass("monthyear")) {
                    return true;
                }

                var aDate = validationObj.getDefaultDateFormat(value).split("/"),
                    nMonth, dDate, dLast;

                if (aDate.length != 3)
                    return false;

                /*
                TODO:  Localize date order
                */

                if (aDate[0] < 1 || aDate[0] > 12)
                    return false;

                dDate = new Date(aDate[2], aDate[0] - 1, aDate[1]);

                if (isNaN(dDate.getTime()))
                    return false;

                dLast = new Date(aDate[2], aDate[0], 0);

                if (isNaN(dLast.getTime()))
                    return false;

                if (aDate[1] < 1 || aDate[1] > dLast.getDate())
                    return false;

                if (aDate[2] < 0 || aDate[2] > 2100)
                    return false;

                return true;
            }, msgs.msgInValidDate);

            $.validator.addMethod("customvalidation", function (value, element, param) {
                var regexp = new RegExp($(element).attr("validationregex"));
                return (value == "" || (regexp.test(value) ? true : false));
            }, function (bValid, element) {
                if (typeof ($(element).attr("message")) == "undefined" || (typeof ($(element).attr("message")) != "undefined" && $(element).attr("message").trim() == "")) { return msgs.msgvalidval }
                else {
                    return $(element).attr("message");
                }
            });
            const currentDate = new Date();
            const currentYear = currentDate.getFullYear();
            const currentMonth = currentDate.getMonth();
            const startYearLimit = currentYear - 100;
            moment.locale(appScope.tgSettings.LocaleCode);
           

            $.validator.addMethod("monthYear", function (value, element) {
                if (appScope.tgSettings.LocaleCode === "tw-TW") {
                    moment.locale("zh-tw");
                }
                if (value.trim() === "") return true; 
                const date = moment(value, appScope.tgSettings.MonthYearFormat.trim(), true);
                if (!date.isValid()) return false;
                return true;
            }, function () {
                return msgs.mgMonthFormat.replace("[format]", getPlaceholderMonthFormat());
            });
            $.validator.addMethod("monthandYearminmax", function (value) {
                if (!value.trim()) return true;
                const date = moment(value, appScope.tgSettings.MonthYearFormat.trim(), true);
                return date.isValid() && (date.year() > startYearLimit || (date.year() === startYearLimit && date.month() >= currentMonth));
            }, function () {
                return msgs.startyearmonthpicker.replace("[currentMonth]", moment().subtract(100, 'years').format(appScope.tgSettings.MonthYearFormat));
            });

            $.validator.addMethod("endMonthYearRange", function (value, element) {
                if (!value.trim()) return true;
                const endDate = moment(value.trim(), appScope.tgSettings.MonthYearFormat.trim(), true);
                if (!endDate.isValid()) return false;
                const startValue = $(element).closest("form").find(".startmonthYear").val().trim();
                const startDate = moment(startValue, appScope.tgSettings.MonthYearFormat.trim(), true);
                return startDate.isValid() && endDate.isSameOrAfter(startDate);
            }, function () {
                return msgs.MgEndyear
            });

            $.validator.addMethod("endyearmustin", function (value) {
                if (!value.trim()) return true;
                const endDate = moment(value, appScope.tgSettings.MonthYearFormat.trim(), true);
                const maxDate = moment().startOf('month').add(1, 'year');
                return endDate.isSameOrBefore(maxDate);
            }, function () {
                return msgs.endyearin.replace("[endyearin]", moment().startOf('month').add(1, 'year').format(appScope.tgSettings.MonthYearFormat));
            });


            $.validator.addClassRules("startmonthYear", {
                monthYear: true,
                required: true,
                monthandYearminmax: true,
            });

            $.validator.addClassRules("endmonthYear", {
                monthYear: true,
                endMonthYearRange: true,
                monthandYearminmax: true,
                endyearmustin:true,
            });

            $.validator.addMethod("phoneformat", function (value, element, param) {
                return (value == "" || value.match(/^(?:\+?\(?\d+)(?:[0-9]|[-,. ()+])+\d+$/) ? true : false);
            }, msgs.msgvalidphone);

            $.validator.addMethod("nameformat", function (value, element, param) {
                return (value == "" || !value.match(/[!#\$%&\"\*\+/:;<=>_\?@\[\\\]\^\{\|\}~]+/gi) ? true : false);
            }, msgs.msgname);

            $.validator.addMethod("bulletpointsrestriction", function (value, element, param) {
                return (value == "" || !value.match(/[\u2022\u25AA\u25AB\uF0AB\u2192\u002B\u2212\u2666\uF0E0\u2756\u27A2\u2713\uF0FB\u2751]+/gi) ? true : false);
            }, msgs.msgvalidval);

            $.validator.addMethod("maxselect", function (value, element, param) {
                if (value != null && typeof value != 'undefined')
                    return param >= value.length ? true : false;
                else
                    return true;
            }, msgs.msgmaxselect);

            $.validator.addMethod("restricted", function (value, element, param) {
                return (value.match(/<\/?[\s\S]*?(script|applet|iframe|object).*?>/gmi) ? false : true);
            }, msgs.msgvalidval);


            $.validator.addMethod("urlformat", function (value, element, param) {
                return (value == "" || value.match(/((?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+)/i) ? true : false);
            }, msgs.msgvalidurl);

            function customMessageForZipFormat() {
                var customMessage = msgs.msgzip;
                if ($("select[name*='country']").first().find(':selected').val() == "223") {
                    customMessage = msgs.msgInvalidZipCode;
                }
                return customMessage;
            }
            function validateYearRangeandGetErrorMessage(typeofyear, yearvalue, doValidate) {
                var minyear = 0, maxyear = 0, thisyear = (new Date()).getFullYear();

                if (doValidate && yearvalue == '')
                    return true;

                switch (typeofyear) {
                    case 'gradyear':
                        minyear = thisyear - 100;
                        maxyear = thisyear + 10;
                        break;

                    case 'startyear':
                        minyear = thisyear - 100;
                        maxyear = thisyear
                        break;

                    case 'endyear':
                        minyear = thisyear - 100;
                        maxyear = thisyear + 1;
                        break;
                }
                if (doValidate) {
                    return yearvalue >= minyear && yearvalue <= maxyear;
                }
                else {
                    var errormsg = msgs.msgInvalidYearRange
                    return (errormsg.replace("[MINYEAR]", minyear - 1).replace("[MAXYEAR]", maxyear + 1));
                }
            }

            $.validator.addMethod("zipformat", function (value, element, param) {
                //United States Country Code is 223, Ensuring that Zip Code matches the specified format When United States is Selected
                if ($("select[name*='country']").first().find(':selected').val() == "223") {
                    return (value == "" || value.match(/(^[0-9]{5}$)|(^[0-9]{5}-[0-9]{4}$)/) ? true : false);
                }
                else
                    return (value == "" || value.match(/^(.{0,10})$/) ? true : false);
            }, customMessageForZipFormat);

            $.validator.addMethod("year", function (value, element, param) {

                return (value == "" || value.match(/^\d{4}$/) ? true : false);
            }, msgs.msgyear);


            $.validator.addMethod("gpa", function (value, element, param) {

                return (value == "" || (value <= 100 && value.match(/^[0-9]+\.?[[0-9]{0,3}]?$/)) ? true : false);
            }, msgs.msggpa);

            $.validator.addMethod("yearranges", function (value, element, param) {
                return validateYearRangeandGetErrorMessage(param, value, true);
            }, function (param, element) { return validateYearRangeandGetErrorMessage(param, element.value, false) });

            $.validator.addClassRules("ssnfield", {
                notEqual: "___-__-____"
            }
            );

            $.validator.addClassRules("required", {
                required: function (element) {
                    return !draftMode;
                }
            });
            $.validator.addClassRules("year", {
                year: ""

            });
            $.validator.addClassRules("endYear", {
                endYear: function (element) {
                    var endyearID = $(element).attr('id');
                    return $("#startyear" + endyearID[7]).val();
                }
            });
            $.validator.addClassRules("gpa", {
                gpa: ""

            });

            $.validator.addClassRules("nohtml", {
                nohtml: ""

            });

            $.validator.addClassRules("yearranges", {
                yearranges: function (element) {

                    var typeofyear_id = $(element).attr('id');
                    var typeofyear = '';

                    if (typeofyear_id.indexOf('gradyear') >= 0)
                        typeofyear = 'gradyear';
                    else if (typeofyear_id.indexOf('startyear') >= 0)
                        typeofyear = 'startyear';
                    else if (typeofyear_id.indexOf('endyear') >= 0)
                        typeofyear = 'endyear';

                    return typeofyear;
                }
            });

            $.validator.addMethod("emailformat", function (value, element, param) {
                // RTC 89472 changes - Reverted code changes done for RTC 79642 in order to resolve the 89472 issue.
                return (value == "" || value.match(/^[a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ!#$%&'\/*\/+-\/\/\/=\/?\/^_`{|}~]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,15}$/) ? true : false);

            }, msgs.msgemail);

            $.validator.addMethod("nohtml", function (value, element, param) {
                return (value == "" || value.match(/^(?!.*<.*>)/) ? true : false);
            }, msgs.msgInvalidInputHTMLTag);

            $.validator.addMethod("endYear", function (value, element, param) {
                if (value == "")
                    return true;
                if (param == "")
                    return false;
                else return (value >= param)
            }, msgs.msgInvalidEndYear);
        },
        validationMsgs: function () {
            jQuery.extend(jQuery.validator.messages, {
                required: msgs.msgrequired,
                email: msgs.msgemail,
                number: msgs.msgnumber,
                equalTo: msgs.msgconfirmfield,
                max: jQuery.validator.format(msgs.msgmax),
                min: jQuery.validator.format(msgs.msgmin)
            });

        },
        setFieldValidations: function () {
            $("#pagecontent").find("input[role=combobox]").each(function () {
                $(this).rules("add", { notInData: true });
            })


            $.each($("#pagecontent").find("input[inputvalidation='1']"), function (index, value) {

                if ($(value).attr("name").match(/num/gi)) {
                    $(value).on("blur",function () { $(value).val($(value).val()); });

                }

                $(value).rules("add", {
                    customvalidation: ""

                });
            });

            $("#pagecontent").find("[name*='candidatestackingfield']:not('span')").each(function () {
                $(this).rules("add", {
                    customvalidation: true,
                });

            });

            $("#pagecontent").find("[name*='phone']:not('span'),[name*='fax']:not('span')").each(function () {
                $(this).rules("add", {
                    phoneformat: "",

                });

            });

            $("#pagecontent").find("[name*='homepage']:not('span')").each(function () {
                $(this).rules("add", {
                    urlformat: "",

                });

            });

            $("#pagecontent").find("[name*='zip']:not('span')").each(function () {
                $(this).rules("add", {
                    zipformat: "",

                });

            });

            $("#pagecontent").find("input[type='text'][name*='firstname'],input[type='text'][name*='lastname'],input[type='text'][name*='middlename'],input[type='text'][name*='pronunciationkey']").each(function () {
                $(this).rules("add", {
                    nameformat: "",
                    bulletpointsrestriction: "",
                });

            });

            $("#pagecontent").find("input[type='text'][name*='address1'],input[type='text'][name*='address2'],input[type='text'][name*='city']").each(function () {
                $(this).rules("add", {
                    bulletpointsrestriction: "",
                });

            });

            $("#pagecontent").find("input[type='email']").each(function () {
                $(this).rules("add", {
                    emailformat: true,

                });

            });

            $("#pagecontent").find("input[type='text'],input[type='search'],input[type='email'],input[type='number'],input[type='ssn'],textarea").each(function () {
                $(this).rules("add", {
                    restricted: "",

                });

            });

            $("#pagecontent").find("input[type='number']").each(function () {
                var elementName = $(this).attr('name');
                if (typeof elementName == "undefined" || elementName == null)
                    elementName = "";
                var fieldType = elementName.split("_")[0];
                if (fieldType.toLowerCase() != "wotc" && !($(this).attr('min') == 0 && $(this).attr('max') == 0)) {
                    $(this).rules("add", {
                        min: parseInt($(this).attr('min')),
                        max: parseInt($(this).attr('max'))
                    });
                }
            });

            $("#pagecontent").find("[name*='_txa_']:not('span')").each(function (index, value) {

                if ($(this).attr("maxlength")) {

                    $(value).on("keypress",function () {

                        if (this.length > parseInt($(this).attr("maxlength"))) {
                            return false;
                        }

                    });
                }

            });


            $.each($("input.dattxt"), function (index, value) {



                $(value).datepicker({
                    beforeShow: function () { readSelected($(value).attr("name").replace("dattxt", "")); }, onSelect: updateSelected,
                    minDate: ($(value).attr("downyears") == "0") ? new Date(new Date().getFullYear(), "0", "1") : ("-" + $(value).attr("downyears") + "Y"), maxDate: ($(value).attr("upyears") == "0") ? new Date(new Date().getFullYear(), "11", "31") : ("+" + $(value).attr("upyears") + "Y"),
                    showOn: 'both', buttonImageOnly: true, buttonImage: '/submission/img/calendar.gif',
                    changeYear: true
                });


                $('#' + $(value).attr("name").replace("dattxt", "year")).on("change",function () { readSelected($(value).attr("name").replace("dattxt", "")); });
                $('#' + $(value).attr("name").replace("dattxt", "mon")).on("change",function () { readSelected($(value).attr("name").replace("dattxt", "")); });
                $('#' + $(value).attr("name").replace("dattxt", "day")).on("change",function () { readSelected($(value).attr("name").replace("dattxt", "")); });


            });


            setTimeout(function () {
                $("#pagecontent").find(".confirmInput").each(function () {

                    $(this).rules("add", {

                        equalTo: '#' + $(this).attr('id').replace('-confirm', '')
                    });
                });
            }, 800);


        }
    }


    // Prepare to show a date picker linked to three select controls
    var readSelected = function (datename) {
        $('#' + datename + 'dattxt').val($('#' + datename + 'mon').val() + '/' +
    $('#' + datename + 'day').val() + '/' + $('#' + datename + 'year').val());
        return {};
    }

    // Update three select controls to match a date picker selection
    var updateSelected = function () {
        var date1 = $(this).val();
        var datecontrol = $(this).attr("name").replace("dattxt", "");
        $('#' + datecontrol + 'mon').val(date1.substring(0, 2).indexOf("0") == 0 ? date1.substring(1, 2) : date1.substring(0, 2));
        if (isMobile)
            $('#' + datecontrol + 'mon').selectmenu().selectmenu("refresh");
        $('#' + datecontrol + 'day').val(date1.substring(3, 5).indexOf("0") == 0 ? date1.substring(4, 5) : date1.substring(3, 5));
        if (isMobile)
            $('#' + datecontrol + 'day').selectmenu().selectmenu("refresh");
        $('#' + datecontrol + 'year').val(date1.substring(6, 10));
        if (isMobile)
            $('#' + datecontrol + 'year').selectmenu().selectmenu("refresh");
    }
    // FORM VALIDATION OBJECT END



    validationObj.setFormValidation();
    validationObj.addValidatorMethods();
    validationObj.setFieldValidations();
    validationObj.validationMsgs();

    // EVENT DELEGATES START

    $(document).on('mouseover click', 'h3.sectionhead', function () {

        $(this).parent().accordion({
            collapsible: true,
            heightStyle: "content"
        });
        $(this).removeClass("sectionhead");


    });

    $(document).on("click", ".my-tooltip-btn", function (event) {

        if (!isMobile) {
            $(this).href = "#";
            event.preventDefault();
            $(this).popover({ content: $("#" + $(this).attr("aria-owns")).html().replace("&lt;", "<").replace("&gt;", ">"), title: "", html: true, trigger: "focus", placement: "top" });
            $(this).on("focusout", function () {
                try {
                    $(this).popover("destroy");
                } catch (Error) {
                }
            });
            $(this).trigger("focus");

        }

    });

    function createFormAutocomplete(event) {

        var $autoinput = $(this).closest(".fieldcontain").find("input[id*='-input']");

        var ss = $autoinput.attr('id').replace('-input', '');
        var fieldParams = ss.split("_");
        var questionId = fieldParams[1];
        var questionType = fieldParams[0];
        var fieldName = fieldParams[3];
        var fieldType = fieldParams[4];
        var optQuestionId = questionId;
        if (fieldParams.length > 6 && fieldParams[6] != 0 && fieldParams[6] != null && fieldParams[6] != "") {
            optQuestionId = fieldParams[6];
        }
        window.pageSize = 15;
        this.pageIndex = 0;
        window.isBlanketSearch = 0;
        $(this).removeClass("ui-complete");

        var pageData = applyScope.page;
        var tgSettings = applyScope.page.tgSettings;

        $autoinput.autocomplete({
            minLength: 1,
            position: {
                my: "left top",
                at: "left bottom",
                collision: "fit flip"
            },
            select: function (event, ui) {
                if (typeof $(this).attr('multiselect') == 'undefined') {
                    $(this).val(ui.item.label);
                    this.pageIndex = 0;
                }
                if ($(this).attr('id').indexOf('_mbcountry_') > -1 && $("#MobileCountryCode").length > 0) {
                    $("#MobileCountryCode").text(ui.item.countryCode);
                }
                DomFunc.selectItem(ui, "#" + ss);
                if (fieldType == "mslt") angular.element($autoinput).scope().toggleSelection(event, ui);
                return false;
            },
            focus: function (event, ui) {
                this.pageIndex = 0;
                return false;
            },
            close: function (event, ui) {
                this.pageIndex = 0;
                this.requestIndex = 0;
            },
            source: function (request, response) {
                $("#skills_0_0_genskills_mslt_0_0-input").closest(".fieldcontain").find(".error.invalidContentLabel").remove();
                $("#skills_0_0_genskills_mslt_0_0-input").closest(".fieldcontain").removeClass("invalid");
                $("#skills_0_0_genskills_mslt_0_0-input").removeAttr("aria-invalid");
                $(".addbutton").css("pointer-events", '').removeAttr("disabled");

                if (request.term == -1) {
                    window.isBlanketSearch = 1;
                }

                $autoinput.data("autocompleteRequestData", {
                    TQRenderingID: pageData.tqrenderingid, QuestionType: questionType, QuestionId: questionId, FieldName: fieldName, LanguageId: tgSettings.deflanguageid, LocaleId: tgSettings.deflocaleid, ClientID: pageData.partnerid, Criteria: (request.term == "-1" ? "" : request.term) + ($autoinput.attr("dependantfield") ? "^" + ($("[name*='_" + $autoinput.attr("dependantfield") + "_']:not('meta,span')").val()) : ""), LanguageISOLetter: tgSettings.languageisoletter, PageSize: window.pageSize, PageIndex: this.pageIndex, OptQuestionId: optQuestionId, SiteId: pageData.siteid
                });
                $autoinput.autocomplete("option", "minLength", 0);
                var prevQB = "", prevchildren = [], qbchildren = [], itemChanged = false;
                if (document.getElementById("autocomplete_" + questionId) != null) {
                    var optionsJson = jQuery.parseJSON(document.getElementById("autocomplete_" + questionId).value);
                    var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
                    var filteredOptionsJson = $.grep(optionsJson, function (item, index) {
                        // return matcher.test(item.Description);
                        if (request.term != "-1")
                            return (item.Description.toLowerCase().indexOf(request.term.toLowerCase()) >= 0)
                        else
                            return true;
                    });
                    var listCount = filteredOptionsJson.length;
                    var $ss = $("#" + ss);

                    this.pageIndex = this.pageIndex || 0;

                    filteredOptionsJson = filteredOptionsJson.slice(this.pageIndex * window.pageSize, this.pageIndex * window.pageSize + window.pageSize);
                    response($.map(filteredOptionsJson, function (v, i) {
                        return {
                            label: v.Description,
                            value: v.Code
                        };
                    }), listCount);
                    var opts = "";
                    var alreadyPresentoptions = $ss.html();
                    $.each($("#" + ss + " option:selected"), function (i, val) {
                        var qbchild = $(val).attr("qbchildren") ? $(val).attr("qbchildren") : "";
                        if ($(val).attr("selected") != "selected") {
                            var Score = $(val).attr("score") ? $(val).attr("score") : "";
                            var knockout = $(val).attr("knockout") ? $(val).attr("knockout") : "false";
                            var nextPageId = $(val).attr("nextpageid") ? $(val).attr("nextpageid") : "0";
                            if (alreadyPresentoptions.indexOf(">" + $(val).html() + "</option>") != -1 && alreadyPresentoptions.indexOf(" selected='selected'>" + $(val).html() + "</option>") == -1)
                                alreadyPresentoptions = alreadyPresentoptions.replace(">" + $(val).html() + "</option>", " selected='selected'>" + $(val).html() + "</option>");
                        }
                        if ($(val).attr("selected") == "selected" && fieldType != "mslt") {
                            if (qbchild != "0") {
                                prevQB += "," + qbchild + ",";
                            }
                            if (request.term != "-1" && $(val).html() != request.term) {
                                itemChanged = true;
                            }
                        }
                    });
                    //Handling QB's when single select dropdown refreshed.
                    if (itemChanged && fieldType != "mslt") {
                        prevchildren = prevQB.split(",");
                        QBObj.executeQB(prevchildren, qbchildren);
                    }

                    if (request.append)
                        $ss.html(alreadyPresentoptions);
                    else
                        opts += alreadyPresentoptions;

                    $.each(filteredOptionsJson, function (i, val) {

                        if ($("#" + ss + " option[value='" + val.Code.replace(/'/g, "\\'") + "']:selected").length == 0) {
                            var qbchild = val.QBChildren ? val.QBChildren : "";
                            var score = val.Score ? val.Score : "0";
                            var knockout = val.KnockOut ? val.KnockOut : "false";
                            var nextPageId = val.KnockOutPageId ? val.KnockOutPageId : "0";
                            var optionId = val.OptionId ? val.OptionId : "0";
                            opts += "<option score='" + score + "' value='" + val.Code.replace(/'/g, "&#39;") + "' qbchildren='" + qbchild + "' knockout='" + knockout + "' nextpageid='" + nextPageId + "' optionid='" + optionId + "'>" + val.Description + "</option>";
                        }
                    });

                    if (request.append)
                        $ss.append($(opts));
                    else {
                        if (opts.indexOf(appScope.dynamicStrings.PlaceHolder_Choose) < 0)
                            opts = "<option value=\"\">" + appScope.dynamicStrings.PlaceHolder_Choose + "</option>" + opts; 
                        $ss.html(opts);
                    }


                    $autoinput.removeAttr("placeholder");
                }
                else {
                    $.ajax({
                        url: "/GQWeb/GetAutoCompleteResults?partnerid=" + pageData.partnerid + "&siteid=" + pageData.siteid,
                        dataType: "json",
                        data: angular.toJson($autoinput.data("autocompleteRequestData")),
                        type: "post",
                        cache: false,
                        contentType: "application/json",
                        success: function (data) {
                            this.fullCount = data.totalcount;
                            var opts = "";

                            //JSQ Autocomplete Case. Mapping Scores
                            var jsqAutoRequest = angular.fromJson(this.data);
                            if (jsqAutoRequest.QuestionType.toLowerCase().indexOf("jsq") > -1 && data.results.length > 0) {
                                var mapElement = $('#autocompletemap_' + jsqAutoRequest.QuestionId)
                                if (typeof mapElement != 'undefined' && mapElement.length > 0) {
                                    var mapArray = angular.fromJson(mapElement.val());
                                    mapArray.forEach(function (i) {
                                        data.results.forEach(function (result) {
                                            if (result.code == i.Code) {
                                                result.score = i.Score;
                                            }
                                        });
                                    });
                                }
                            }
                            if (!request.append) {
                                $.each($("#" + ss + " option:selected"), function (i, val) {
                                    var qbchild = $(val).attr("qbchildren") ? $(val).attr("qbchildren") : "";
                                    var score = $(val).attr("score") ? $(val).attr("score") : "0";
                                    var knockout = $(val).attr("knockout") ? $(val).attr("knockout") : "false";
                                    var nextPageId = $(val).attr("nextpageid") ? $(val).attr("nextpageid") : "0";
                                    var optionId = $(val).attr("optionid") ? $(val).attr("optionid") : "0";
                                    opts += "<option score='" + score + "' value='" + $(val).attr("value").replace(/'/g, "&#39;") + "' selected='selected'  qbchildren='" + qbchild + "' knockout='" + knockout + "' nextpageid='" + nextPageId + "' optionid='" + optionId + "'>" + $(val).text() + "</option>";

                                    if ($(val).attr("selected") == "selected" && fieldType != "mslt") {
                                        if (qbchild != "0") {
                                            prevQB += "," + qbchild + ",";
                                        }
                                        if (request.term != "-1" && $(val).html() != request.term) {
                                            itemChanged = true;
                                        }
                                    }
                                });
                            }

                            //Handling QB's when single select dropdown refreshed.
                            if (itemChanged && fieldType != "mslt") {
                                prevchildren = prevQB.split(",");
                                QBObj.executeQB(prevchildren, qbchildren);
                            }

                            $.each(data.results, function (i, val) {

                                if ($("#" + ss + " option[value='" + val.code.replace(/'/g, "\\'") + "']:selected").length == 0) {
                                    var qbchild = val.qbchildren ? val.qbchildren : "";
                                    var score = val.score ? val.score : "0";
                                    var knockout = val.knockout ? val.knockout : "false";
                                    var nextPageId = val.knockoutPageId ? val.knockoutPageId : "0";
                                    var optionId = val.optionId ? val.optionId : "0";
                                    opts += "<option score='" + score + "' value='" + val.code.replace(/'/g, "&#39;") + "' qbchildren='" + qbchild + "' knockout='" + knockout + "' nextpageid='" + nextPageId + "' optionid='" + optionId + "'>" + val.description + "</option>";
                                }
                            });

                            response($.map(data.results, function (v, i) {

                                return {
                                    label: v.description,
                                    value: v.code,
                                    countryCode: v.mobileCountryCode
                                };

                            }
                                ), data.totalcount);

                            if (request.append)
                                $("#" + ss).append($(opts));
                            else
                            {
                                if (window.navigator.userAgent.indexOf("MSIE ") >= 0 || window.navigator.userAgent.indexOf("Trident/") >= 0)
                                {
                                    if (applyScope.page.autocompletefieldoptions)
                                    {
                                        if (applyScope.page.autocompletefieldoptions.hasOwnProperty(ss))
                                        {
                                            var str = applyScope.page.autocompletefieldoptions[ss] + opts;
                                            opts = str;
                                        }
                                    }
                                }
                                $("#" + ss).html(opts);
                            }

                            $autoinput.removeAttr("placeholder");
                            $("#skills_0_0_genskills_mslt_0_0-input").removeClass("ui-autocomplete-loading");
                        },
                        error: function (err) {
                            $("#skills_0_0_genskills_mslt_0_0-input").removeClass("ui-autocomplete-loading");
                            var element = $("#skills_0_0_genskills_mslt_0_0-input");
                            
                            element.closest(".fieldcontain").addClass("invalid");
                            element.attr("aria-invalid", "true");
                            element.closest(".fieldcontain").append(`<span for=${element.attr("id")} class="error invalidContentLabel">${appScope.dynamicStrings.Lbl_Validation_Error}</span>`);
                            $(".addbutton").css("pointer-events", "none").attr("disabled", true);
                        }
                    });
                }
            }
        });
        $autoinput.on("blur",function () {
            if (!$autoinput[0].attributes.hasOwnProperty("multiselect") && $autoinput.val() == "") {
                //Handling delete control to hide the respective QB
                var prevchildren = [], qbchildren = [];
                prevchildren.push($($('#' + ss).find("option:selected")[0]).attr("qbchildren"));
                QBObj.executeQB(prevchildren, qbchildren);
                $('#' + ss).find('option').remove().end();
                if (window.navigator.userAgent.indexOf("MSIE ") >= 0 || window.navigator.userAgent.indexOf("Trident/") >= 0)
                {
                    if (applyScope.page.autocompletefieldoptions && applyScope.page.autocompletefieldoptions.hasOwnProperty(ss)) {
                        applyScope.page.autocompletefieldoptions = {};
                    }

                }
            }
            //$autoinput.attr("placeholder", msgs.msgplaceholder);
            $autoinput.autocomplete("option", "minLength", 1);
        });

    }

    $(document).on("focus", ".ui-complete", createFormAutocomplete);

    if (window.appScope) {
        appScope.utils.createFormAutocomplete = function (elInput) {
            createFormAutocomplete.apply(elInput);
        }
    }

    $(document).on('click', '.autoclear', function () {

        var $clearButton = $(this),
            $inputctr = $clearButton.parent().find("input");

        if ($clearButton.hasClass("custom-icon-angle-down")) {

            $inputctr.autocomplete("search", "-1");

        }
        else {
            var $selectControl = $("#" + $clearButton.parent().find("input").attr("id").replace("-input", ""));

            if (typeof $selectControl.attr("multiple") == "undefined") {
                $selectControl.find("option:selected").each(function () { $clearButton.removeAttr("selected"); $clearButton.prop("selected", false); });
                if ($selectControl.find("option[value='']").length == 0) {
                    $selectControl.append($("<option value='' selected>Choose..</option>"));
                    $clearButton.addClass("custom-icon-angle-down");
                    $clearButton.removeClass("icon-remove");
                }
                else {
                    $selectControl.find("option[value='']").prop("selected", true);
                }
                $selectControl.trigger("change");
                $inputctr.val("");
                $inputctr.autocomplete("search", "-1");

            }
        }
    });

    // EVENT DELEGATES END


    // DOM READY
    $(document).ready(function () {

        if (navigator.userAgent.indexOf("MSIE 8.0") != -1 || navigator.userAgent.indexOf("MSIE 7.0") != -1) {
            var head = document.getElementsByTagName('head')[0],
                    style = document.createElement('style');
            style.type = 'text/css';
            style.styleSheet.cssText = ':before,.ui-btn-icon-notext:after{content:none !important}';
            head.appendChild(style);
            setTimeout(function () {
                head.removeChild(style);
            }, 0);
        }


    });



    //processFATextFields();



    DomFunc.setLabels();

    $("body").css({ "visibility": "visible" });


    window.QBObj = QBObj;
    //window.FAObj = FaObj;
    window.validationObj = validationObj;
    window.hidQBFields = hidQBFields;
    window.navigationFn = navigationFn;
    window.DomFunc = DomFunc;
};
var ValidateDateConfiguration = function (Value, DateConfiguration, DateFormat) {
    console.log("New Configuration Validations");
    DateConfiguration = JSON.parse(DateConfiguration);
    var Disabledaysofweek = DateConfiguration.Disabledaysofweek;
    var calculatedMinMax = new calculateMinMaxDates(DateConfiguration);
    var TodayDate = moment(moment().toDate().setHours(0, 0, 0, 0));
    var SelectedDate = moment(moment(ConvertToStandardDate(DateFormat, Value)).toDate().setHours(0, 0, 0, 0));
    var isInfiniteMinDate = calculatedMinMax.Mindate == "" ? true : false;
    var isInfiniteMaxDate = calculatedMinMax.Maxdate == "" ? true : false;
    //If selected Date is in disabled days of week, then return false
    if (Disabledaysofweek.indexOf(SelectedDate.day()) > -1) {
        return false;
    }

    var isMinDateViolated = isInfiniteMinDate ? false : new Date(SelectedDate) < new Date(new Date(calculatedMinMax.Mindate).setHours(0, 0, 0, 0));
    var isMaxDateViolated = isInfiniteMaxDate ? false : new Date(SelectedDate) > new Date(new Date(calculatedMinMax.Maxdate).setHours(0, 0, 0, 0));
    //If selected Date is less than Minimum Date or selected Date is greater than Maximum Date, Then Return False
    if (isMinDateViolated || isMaxDateViolated) {
        console.log("SelectedDate: " + new Date(SelectedDate) + ", MinimumDate: " + new Date(new Date(calculatedMinMax.Mindate).setHours(0, 0, 0, 0)) + ", MaximumDate: " + new Date(new Date(calculatedMinMax.Maxdate).setHours(0, 0, 0, 0)));
        return false;
    }
    return true;
}
var ConvertToStandardDate = function (format, value) {

    var dateVal;
    try {
        dateVal = $.datepicker.parseDate(ConvertToDatePickerFormat(format), value);
    } catch (e) {
        return null;
    }

    return $.datepicker.formatDate("m/d/yy", dateVal);
}
var ConvertToDatePickerFormat = function (format) {

    return format.toLowerCase().replace("yyyy", "yy");

}

/*
// NoComment PRESERVE END
*/






;
/*_/^\_I_/^\_N_/^\_F_/^\_I_/^\_N_/^\_I_/^\_T_/^\_E_/^\_

 (c) Copyright Infinite Talent 2021  

`\V/'I`\V/'N`\V/'F`\V/'I`\V/'N`\V/'I`\V/'T`\V/'E`\V/'*/




/*** Directives and services for responding to idle users in AngularJS
* @author Mike Grabski <me@mikegrabski.com>
* @version v1.2.2
* @link https://github.com/HackedByChinese/ng-idle.git
* @license MIT
*/
(function(window, angular, undefined) {
'use strict';
angular.module('ngIdle', ['ngIdle.keepalive', 'ngIdle.idle', 'ngIdle.countdown', 'ngIdle.title', 'ngIdle.localStorage']);
angular.module('ngIdle.keepalive', [])
  .provider('Keepalive', function() {
    var options = {
      http: null,
      interval: 10 * 60
    };

    this.http = function(value) {
      if (!value) throw new Error('Argument must be a string containing a URL, or an object containing the HTTP request configuration.');
      if (angular.isString(value)) {
        value = {
          url: value,
          method: 'GET'
        };
      }

      value.cache = false;

      options.http = value;
    };

    var setInterval = this.interval = function(seconds) {
      seconds = parseInt(seconds);

      if (isNaN(seconds) || seconds <= 0) throw new Error('Interval must be expressed in seconds and be greater than 0.');
      options.interval = seconds;
    };

    this.$get = ['$rootScope', '$log', '$interval', '$http',
      function($rootScope, $log, $interval, $http) {

        var state = {
          ping: null
        };

        function handleResponse(data, status) {
          $rootScope.$broadcast('KeepaliveResponse', data, status);
        }

        function ping() {
          $rootScope.$broadcast('Keepalive');

          if (angular.isObject(options.http)) {
            $http(options.http)
              .success(handleResponse)
              .error(handleResponse);
          }
        }

        return {
          _options: function() {
            return options;
          },
          setInterval: setInterval,
          start: function() {
            $interval.cancel(state.ping);

            state.ping = $interval(ping, options.interval * 1000);
            return state.ping;
          },
          stop: function() {
            $interval.cancel(state.ping);
          },
          ping: function() {
            ping();
          }
        };
      }
    ];
  });

angular.module('ngIdle.idle', ['ngIdle.keepalive', 'ngIdle.localStorage'])
  .provider('Idle', function() {
    var options = {
      idle: 24 * 60 * 60, // in seconds (default is 20min)
      timeout: 30, // in seconds (default is 30sec)
      autoResume: 'idle', // lets events automatically resume (unsets idle state/resets warning)
      interrupt: 'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove scroll',
      windowInterrupt: null,
      keepalive: true
    };

    /**
     *  Sets the number of seconds a user can be idle before they are considered timed out.
     *  @param {Number|Boolean} seconds A positive number representing seconds OR 0 or false to disable this feature.
     */
    var setTimeout = this.timeout = function(seconds) {
      if (seconds === false) options.timeout = 0;
      else if (angular.isNumber(seconds) && seconds >= 0) options.timeout = seconds;
      else throw new Error('Timeout must be zero or false to disable the feature, or a positive integer (in seconds) to enable it.');
    };

    this.interrupt = function(events) {
      options.interrupt = events;
    };

    this.windowInterrupt = function(events) {
      options.windowInterrupt = events;
    };

    var setIdle = this.idle = function(seconds) {
      if (seconds <= 0) throw new Error('Idle must be a value in seconds, greater than 0.');

      options.idle = seconds;
    };

    this.autoResume = function(value) {
      if (value === true) options.autoResume = 'idle';
      else if (value === false) options.autoResume = 'off';
      else options.autoResume = value;
    };

    this.keepalive = function(enabled) {
      options.keepalive = enabled === true;
    };

    this.$get = ['$interval', '$log', '$rootScope', '$document', 'Keepalive', 'IdleLocalStorage', '$window',
      function($interval, $log, $rootScope, $document, Keepalive, LocalStorage, $window) {
        var state = {
          idle: null,
          timeout: null,
          idling: false,
          running: false,
          countdown: null
        };

        var id = new Date().getTime();

        function startKeepalive() {
          if (!options.keepalive) return;

          if (state.running) Keepalive.ping();

          Keepalive.start();
        }

        function stopKeepalive() {
          if (!options.keepalive) return;

          Keepalive.stop();
        }

        function toggleState() {
          state.idling = !state.idling;
          var name = state.idling ? 'IdleStart' : 'IdleEnd';

          if (state.idling) {
            $rootScope.$broadcast(name);
            stopKeepalive();
            if (options.timeout) {
              state.countdown = options.timeout;
              countdown();
              state.timeout = $interval(countdown, 1000, options.timeout, false);
            }
          } else {
            startKeepalive();
            $rootScope.$broadcast(name);
          }

          $interval.cancel(state.idle);
        }

        function countdown() {

          // check not called when no longer idling
          // possible with multiple tabs
          if(!state.idling){
            return;
          }

          // countdown has expired, so signal timeout
          if (state.countdown <= 0) {
            timeout();
            return;
          }

          // countdown hasn't reached zero, so warn and decrement
          $rootScope.$broadcast('IdleWarn', state.countdown);
          state.countdown--;
        }

        function timeout() {
          stopKeepalive();
          $interval.cancel(state.idle);
          $interval.cancel(state.timeout);

          state.idling = true;
          state.running = false;
          state.countdown = 0;

          $rootScope.$broadcast('IdleTimeout');
        }

        function changeOption(self, fn, value) {
          var reset = self.running();

          self.unwatch();
          fn(value);
          if (reset) self.watch();
        }

        function getExpiry() {
          var obj = LocalStorage.get('expiry');

          return obj && obj.time ? new Date(obj.time) : null;
        }

        function setExpiry(date) {
          if (!date) LocalStorage.remove('expiry');
          else LocalStorage.set('expiry', {id: id, time: date});
        }

        var svc = {
          _options: function() {
            return options;
          },
          _getNow: function() {
            return new Date();
          },
          getIdle: function(){
            return options.idle;
          },
          getTimeout: function(){
            return options.timeout;
          },
          setIdle: function(seconds) {
            changeOption(this, setIdle, seconds);
          },
          setTimeout: function(seconds) {
            changeOption(this, setTimeout, seconds);
          },
          isExpired: function() {
            var expiry = getExpiry();
            return expiry !== null && expiry <= this._getNow();
          },
          running: function() {
            return state.running;
          },
          idling: function() {
            return state.idling;
          },
          watch: function(noExpiryUpdate) {
            $interval.cancel(state.idle);
            $interval.cancel(state.timeout);

            // calculate the absolute expiry date, as added insurance against a browser sleeping or paused in the background
            var timeout = !options.timeout ? 0 : options.timeout;
            if (!noExpiryUpdate) setExpiry(new Date(new Date().getTime() + ((options.idle + timeout) * 1000)));


            if (state.idling) toggleState(); // clears the idle state if currently idling
            else if (!state.running) startKeepalive(); // if about to run, start keep alive

            state.running = true;

            state.idle = $interval(toggleState, options.idle * 1000, 0, false);
          },
          unwatch: function() {
            $interval.cancel(state.idle);
            $interval.cancel(state.timeout);

            state.idling = false;
            state.running = false;
            setExpiry(null);

            stopKeepalive();
          },
          interrupt: function(anotherTab) {
            if (!state.running) return;

            if (options.timeout && this.isExpired()) {
              timeout();
              return;
            }

            // note: you can no longer auto resume once we exceed the expiry; you will reset state by calling watch() manually
            if (anotherTab || options.autoResume === 'idle' || (options.autoResume === 'notIdle' && !state.idling)) this.watch(anotherTab);
          }
        };

        var lastMove = {
          clientX: null,
          clientY: null,
          swap: function(event) {
            var last = {clientX: this.clientX, clientY: this.clientY};
            this.clientX = event.clientX;
            this.clientY = event.clientY;
            return last;
          },
          hasMoved: function(event) {
            var last = this.swap(event);
            if (this.clientX === null || event.movementX || event.movementY) return true;
            else if (last.clientX != event.clientX || last.clientY != event.clientY) return true;
            else return false;
          }
        };

        $document.find('html').on(options.interrupt, function(event) {
          if (event.type === 'mousemove' && event.originalEvent && event.originalEvent.movementX === 0 && event.originalEvent.movementY === 0) {
            return; // Fix for Chrome desktop notifications, triggering mousemove event.
          }

          if (event.type !== 'mousemove' || lastMove.hasMoved(event)) {
            svc.interrupt();
          }
        });

        if(options.windowInterrupt) {
          var eventList = options.windowInterrupt.split(' ');
          var fn = function() {
            svc.interrupt();
          };

          for(var i=0; i<eventList.length; i++) {
            if ($window.addEventListener) $window.addEventListener(eventList[i], fn, false);
            else $window.attachEvent(eventList[i], fn)
          }
        }

        var wrap = function(event) {
          if (event.key === 'ngIdle.expiry' && event.newValue && event.newValue !== event.oldValue) {
            var val = angular.fromJson(event.newValue);
            if (val.id === id) return;
            svc.interrupt(true);
          }
        };

        if ($window.addEventListener) $window.addEventListener('storage', wrap, false);
        else $window.attachEvent('onstorage', wrap);

        return svc;
      }
    ];
  });

angular.module('ngIdle.countdown', ['ngIdle.idle'])
  .directive('idleCountdown', ['Idle', function(Idle) {
    return {
      restrict: 'A',
      scope: {
        value: '=idleCountdown'
      },
      link: function($scope) {
        // Initialize the scope's value to the configured timeout.
        $scope.value = Idle.getTimeout();

        $scope.$on('IdleWarn', function(e, countdown) {
          $scope.$evalAsync(function() {
            $scope.value = countdown;
          });
        });

        $scope.$on('IdleTimeout', function() {
          $scope.$evalAsync(function() {
            $scope.value = 0;
          });
        });
      }
    };
  }]);

angular.module('ngIdle.title', [])
  .provider('Title', function() {
    var options = {
      enabled: true
    };

    var setEnabled = this.enabled = function(enabled) {
      options.enabled = enabled === true;
    };

    function padLeft(nr, n, str){
      return new Array(n-String(nr).length+1).join(str||'0')+nr;
    }

    this.$get = ['$document', '$interpolate', function($document, $interpolate) {
      var state = {
        original: null,
        idle: '{{minutes}}:{{seconds}} until your session times out!',
        timedout: 'Your session has expired.'
      };

      return {
        setEnabled: setEnabled,
        isEnabled: function() {
          return options.enabled;
        },
        original: function(val) {
          if (angular.isUndefined(val)) return state.original;

          state.original = val;
        },
        store: function(overwrite) {
          if (overwrite || !state.original) state.original = this.value();
        },
        value: function(val) {
          if (angular.isUndefined(val)) return $document[0].title;

          $document[0].title = val;
        },
        idleMessage: function(val) {
          if (angular.isUndefined(val)) return state.idle;

          state.idle = val;
        },
        timedOutMessage: function(val) {
          if (angular.isUndefined(val)) return state.timedout;

          state.timedout = val;
        },
        setAsIdle: function(countdown) {
          this.store();

          var remaining = { totalSeconds: countdown };
          remaining.minutes = Math.floor(countdown/60);
          remaining.seconds = padLeft(countdown - remaining.minutes * 60, 2);

          this.value($interpolate(this.idleMessage())(remaining));
        },
        setAsTimedOut: function() {
          this.store();

          this.value(this.timedOutMessage());
        },
        restore: function() {
          if (this.original()) this.value(this.original());
        }
      };
    }];
  })
  .directive('title', ['Title', function(Title) {
      return {
        restrict: 'E',
        link: function($scope, $element, $attr) {
          if (!Title.isEnabled() || $attr.idleDisabled) return;

          Title.store(true);

          $scope.$on('IdleStart', function() {
            Title.original($element[0].innerText);
          });

          $scope.$on('IdleWarn', function(e, countdown) {
            Title.setAsIdle(countdown);
          });

          $scope.$on('IdleEnd', function() {
            Title.restore();
          });

          $scope.$on('IdleTimeout', function() {
            Title.setAsTimedOut();
          });
        }
      };
  }]);

angular.module('ngIdle.localStorage', [])
  .service('IdleStorageAccessor', ['$window', function($window) {
    return {
      get: function() {
        return $window.localStorage;
      }
    }
  }])
  .service('IdleLocalStorage', ['IdleStorageAccessor', function(IdleStorageAccessor) {
    function AlternativeStorage() {
      var storageMap = {};

      this.setItem = function (key, value) {
          storageMap[key] = value;
      };

      this.getItem = function (key) {
          if(typeof storageMap[key] !== 'undefined' ) {
              return storageMap[key];
          }
          return null;
      };

      this.removeItem = function (key) {
          storageMap[key] = undefined;
      };
    }

    function getStorage() {
       try {
          var s = IdleStorageAccessor.get();
          s.setItem('ngIdleStorage', '');
          s.removeItem('ngIdleStorage');

          return s;
       } catch(err) {
          return new AlternativeStorage();
       }
    }

    // Safari, in Private Browsing Mode, looks like it supports localStorage but all calls to setItem
    // throw QuotaExceededError. We're going to detect this and just silently drop any calls to setItem
    // to avoid the entire page breaking, without having to do a check at each usage of Storage.
    var storage = getStorage();

    return {
      set: function(key, value) {
        storage.setItem('ngIdle.'+key, angular.toJson(value));
      },
      get: function(key) {
        return angular.fromJson(storage.getItem('ngIdle.'+key));
      },
      remove: function(key) {
        storage.removeItem('ngIdle.'+key);
      },
      _wrapped: function() {
        return storage;
      }
    };
}]);

})(window, window.angular);




;
/*_/^\_I_/^\_N_/^\_F_/^\_I_/^\_N_/^\_I_/^\_T_/^\_E_/^\_

 (c) Copyright Infinite Talent 2021  

`\V/'I`\V/'N`\V/'F`\V/'I`\V/'N`\V/'I`\V/'T`\V/'E`\V/'*/
/*
 AngularJS v1.8.2
 (c) 2010-2020 Google LLC. http://angularjs.org
 License: MIT
*/
(function(Y,z){'use strict';function Fa(a,b,c){if(!a)throw Pa("areq",b||"?",c||"required");return a}function Ga(a,b){if(!a&&!b)return"";if(!a)return b;if(!b)return a;Z(a)&&(a=a.join(" "));Z(b)&&(b=b.join(" "));return a+" "+b}function Qa(a){var b={};a&&(a.to||a.from)&&(b.to=a.to,b.from=a.from);return b}function $(a,b,c){var d="";a=Z(a)?a:a&&G(a)&&a.length?a.split(/\s+/):[];s(a,function(a,k){a&&0<a.length&&(d+=0<k?" ":"",d+=c?b+a:a+b)});return d}function Ha(a){if(a instanceof A)switch(a.length){case 0:return a;
case 1:if(1===a[0].nodeType)return a;break;default:return A(va(a))}if(1===a.nodeType)return A(a)}function va(a){if(!a[0])return a;for(var b=0;b<a.length;b++){var c=a[b];if(1===c.nodeType)return c}}function Ra(a,b,c){s(b,function(b){a.addClass(b,c)})}function Sa(a,b,c){s(b,function(b){a.removeClass(b,c)})}function aa(a){return function(b,c){c.addClass&&(Ra(a,b,c.addClass),c.addClass=null);c.removeClass&&(Sa(a,b,c.removeClass),c.removeClass=null)}}function pa(a){a=a||{};if(!a.$$prepared){var b=a.domOperation||
N;a.domOperation=function(){a.$$domOperationFired=!0;b();b=N};a.$$prepared=!0}return a}function ha(a,b){Ia(a,b);Ja(a,b)}function Ia(a,b){b.from&&(a.css(b.from),b.from=null)}function Ja(a,b){b.to&&(a.css(b.to),b.to=null)}function T(a,b,c){var d=b.options||{};c=c.options||{};var f=(d.addClass||"")+" "+(c.addClass||""),k=(d.removeClass||"")+" "+(c.removeClass||"");a=Ta(a.attr("class"),f,k);c.preparationClasses&&(d.preparationClasses=ba(c.preparationClasses,d.preparationClasses),delete c.preparationClasses);
f=d.domOperation!==N?d.domOperation:null;wa(d,c);f&&(d.domOperation=f);d.addClass=a.addClass?a.addClass:null;d.removeClass=a.removeClass?a.removeClass:null;b.addClass=d.addClass;b.removeClass=d.removeClass;return d}function Ta(a,b,c){function d(a){G(a)&&(a=a.split(" "));var c={};s(a,function(a){a.length&&(c[a]=!0)});return c}var f={};a=d(a);b=d(b);s(b,function(a,c){f[c]=1});c=d(c);s(c,function(a,c){f[c]=1===f[c]?null:-1});var k={addClass:"",removeClass:""};s(f,function(c,b){var d,f;1===c?(d="addClass",
f=!a[b]||a[b+"-remove"]):-1===c&&(d="removeClass",f=a[b]||a[b+"-add"]);f&&(k[d].length&&(k[d]+=" "),k[d]+=b)});return k}function K(a){return a instanceof A?a[0]:a}function Ua(a,b,c,d){a="";c&&(a=$(c,"ng-",!0));d.addClass&&(a=ba(a,$(d.addClass,"-add")));d.removeClass&&(a=ba(a,$(d.removeClass,"-remove")));a.length&&(d.preparationClasses=a,b.addClass(a))}function xa(a,b){var c=b?"paused":"",d=ca+"PlayState";ma(a,[d,c]);return[d,c]}function ma(a,b){a.style[b[0]]=b[1]}function ba(a,b){return a?b?a+" "+
b:a:b}function Ka(a,b,c){var d=Object.create(null),f=a.getComputedStyle(b)||{};s(c,function(a,c){var b=f[a];if(b){var L=b.charAt(0);if("-"===L||"+"===L||0<=L)b=Va(b);0===b&&(b=null);d[c]=b}});return d}function Va(a){var b=0;a=a.split(/\s*,\s*/);s(a,function(a){"s"===a.charAt(a.length-1)&&(a=a.substring(0,a.length-1));a=parseFloat(a)||0;b=b?Math.max(a,b):a});return b}function ya(a){return 0===a||null!=a}function La(a,b){var c=M,d=a+"s";b?c+="Duration":d+=" linear all";return[c,d]}function Ma(a,b,c){s(c,
function(c){a[c]=za(a[c])?a[c]:b.style.getPropertyValue(c)})}var M,Aa,ca,Ba;void 0===Y.ontransitionend&&void 0!==Y.onwebkittransitionend?(M="WebkitTransition",Aa="webkitTransitionEnd transitionend"):(M="transition",Aa="transitionend");void 0===Y.onanimationend&&void 0!==Y.onwebkitanimationend?(ca="WebkitAnimation",Ba="webkitAnimationEnd animationend"):(ca="animation",Ba="animationend");var qa=ca+"Delay",Ca=ca+"Duration",na=M+"Delay",Na=M+"Duration",Pa=z.$$minErr("ng"),ra={blockTransitions:function(a,
b){var c=b?"-"+b+"s":"";ma(a,[na,c]);return[na,c]}},Wa={transitionDuration:Na,transitionDelay:na,transitionProperty:M+"Property",animationDuration:Ca,animationDelay:qa,animationIterationCount:ca+"IterationCount"},Xa={transitionDuration:Na,transitionDelay:na,animationDuration:Ca,animationDelay:qa},Da,wa,s,Z,za,sa,Ea,ta,G,R,A,N;z.module("ngAnimate",[],function(){N=z.noop;Da=z.copy;wa=z.extend;A=z.element;s=z.forEach;Z=z.isArray;G=z.isString;ta=z.isObject;R=z.isUndefined;za=z.isDefined;Ea=z.isFunction;
sa=z.isElement}).info({angularVersion:"1.8.2"}).directive("ngAnimateSwap",["$animate",function(a){return{restrict:"A",transclude:"element",terminal:!0,priority:550,link:function(b,c,d,f,k){var e,Q;b.$watchCollection(d.ngAnimateSwap||d["for"],function(b){e&&a.leave(e);Q&&(Q.$destroy(),Q=null);(b||0===b)&&k(function(b,d){e=b;Q=d;a.enter(b,null,c)})})}}}]).directive("ngAnimateChildren",["$interpolate",function(a){return{link:function(b,c,d){function f(a){c.data("$$ngAnimateChildren","on"===a||"true"===
a)}var k=d.ngAnimateChildren;G(k)&&0===k.length?c.data("$$ngAnimateChildren",!0):(f(a(k)(b)),d.$observe("ngAnimateChildren",f))}}}]).factory("$$rAFScheduler",["$$rAF",function(a){function b(a){d=d.concat(a);c()}function c(){if(d.length){for(var b=d.shift(),e=0;e<b.length;e++)b[e]();f||a(function(){f||c()})}}var d,f;d=b.queue=[];b.waitUntilQuiet=function(b){f&&f();f=a(function(){f=null;b();c()})};return b}]).provider("$$animateQueue",["$animateProvider",function(a){function b(a){return{addClass:a.addClass,
removeClass:a.removeClass,from:a.from,to:a.to}}function c(a){if(!a)return null;a=a.split(" ");var b=Object.create(null);s(a,function(a){b[a]=!0});return b}function d(a,b){if(a&&b){var d=c(b);return a.split(" ").some(function(a){return d[a]})}}function f(a,b,c){return e[a].some(function(a){return a(b,c)})}function k(a,b){var c=0<(a.addClass||"").length,d=0<(a.removeClass||"").length;return b?c&&d:c||d}var e=this.rules={skip:[],cancel:[],join:[]};e.join.push(function(a,b){return!a.structural&&k(a)});
e.skip.push(function(a,b){return!a.structural&&!k(a)});e.skip.push(function(a,b){return"leave"===b.event&&a.structural});e.skip.push(function(a,b){return b.structural&&2===b.state&&!a.structural});e.cancel.push(function(a,b){return b.structural&&a.structural});e.cancel.push(function(a,b){return 2===b.state&&a.structural});e.cancel.push(function(a,b){if(b.structural)return!1;var c=a.addClass,f=a.removeClass,k=b.addClass,e=b.removeClass;return R(c)&&R(f)||R(k)&&R(e)?!1:d(c,e)||d(f,k)});this.$get=["$$rAF",
"$rootScope","$rootElement","$document","$$Map","$$animation","$$AnimateRunner","$templateRequest","$$jqLite","$$forceReflow","$$isDocumentHidden",function(c,d,e,C,U,oa,H,u,t,I,da){function ia(a){O.delete(a.target)}function v(){var a=!1;return function(b){a?b():d.$$postDigest(function(){a=!0;b()})}}function ua(a,b,c){var g=[],l=m[c];l&&s(l,function(l){Oa.call(l.node,b)?g.push(l.callback):"leave"===c&&Oa.call(l.node,a)&&g.push(l.callback)});return g}function h(a,b,c){var l=va(b);return a.filter(function(a){return!(a.node===
l&&(!c||a.callback===c))})}function q(a,J,w){function e(a,b,l,g){u(function(){var a=ua(ia,m,b);a.length?c(function(){s(a,function(a){a(h,l,g)});"close"!==l||m.parentNode||D.off(m)}):"close"!==l||m.parentNode||D.off(m)});a.progress(b,l,g)}function I(a){var b=h,c=n;c.preparationClasses&&(b.removeClass(c.preparationClasses),c.preparationClasses=null);c.activeClasses&&(b.removeClass(c.activeClasses),c.activeClasses=null);W(h,n);ha(h,n);n.domOperation();q.complete(!a)}var n=Da(w),h=Ha(a),m=K(h),ia=m&&
m.parentNode,n=pa(n),q=new H,u=v();Z(n.addClass)&&(n.addClass=n.addClass.join(" "));n.addClass&&!G(n.addClass)&&(n.addClass=null);Z(n.removeClass)&&(n.removeClass=n.removeClass.join(" "));n.removeClass&&!G(n.removeClass)&&(n.removeClass=null);n.from&&!ta(n.from)&&(n.from=null);n.to&&!ta(n.to)&&(n.to=null);if(!(B&&m&&fa(m,J,w)&&Ya(m,n)))return I(),q;var x=0<=["enter","move","leave"].indexOf(J),r=da(),P=r||O.get(m);w=!P&&y.get(m)||{};var p=!!w.state;P||p&&1===w.state||(P=!E(m,ia,J));if(P)return r&&
e(q,J,"start",b(n)),I(),r&&e(q,J,"close",b(n)),q;x&&F(m);r={structural:x,element:h,event:J,addClass:n.addClass,removeClass:n.removeClass,close:I,options:n,runner:q};if(p){if(f("skip",r,w)){if(2===w.state)return I(),q;T(h,w,r);return w.runner}if(f("cancel",r,w))if(2===w.state)w.runner.end();else if(w.structural)w.close();else return T(h,w,r),w.runner;else if(f("join",r,w))if(2===w.state)T(h,r,{});else return Ua(t,h,x?J:null,n),J=r.event=w.event,n=T(h,w,r),w.runner}else T(h,r,{});(p=r.structural)||
(p="animate"===r.event&&0<Object.keys(r.options.to||{}).length||k(r));if(!p)return I(),g(m),q;var C=(w.counter||0)+1;r.counter=C;l(m,1,r);d.$$postDigest(function(){h=Ha(a);var c=y.get(m),d=!c,c=c||{},t=0<(h.parent()||[]).length&&("animate"===c.event||c.structural||k(c));if(d||c.counter!==C||!t){d&&(W(h,n),ha(h,n));if(d||x&&c.event!==J)n.domOperation(),q.end();t||g(m)}else J=!c.structural&&k(c,!0)?"setClass":c.event,l(m,2),c=oa(h,J,c.options),q.setHost(c),e(q,J,"start",b(n)),c.done(function(a){I(!a);
(a=y.get(m))&&a.counter===C&&g(m);e(q,J,"close",b(n))})});return q}function F(a){a=a.querySelectorAll("[data-ng-animate]");s(a,function(a){var b=parseInt(a.getAttribute("data-ng-animate"),10),c=y.get(a);if(c)switch(b){case 2:c.runner.end();case 1:y.delete(a)}})}function g(a){a.removeAttribute("data-ng-animate");y.delete(a)}function E(a,b,c){c=C[0].body;var l=K(e),g=a===c||"HTML"===a.nodeName,d=a===l,t=!1,m=O.get(a),h;for((a=A.data(a,"$ngAnimatePin"))&&(b=K(a));b;){d||(d=b===l);if(1!==b.nodeType)break;
a=y.get(b)||{};if(!t){var f=O.get(b);if(!0===f&&!1!==m){m=!0;break}else!1===f&&(m=!1);t=a.structural}if(R(h)||!0===h)a=A.data(b,"$$ngAnimateChildren"),za(a)&&(h=a);if(t&&!1===h)break;g||(g=b===c);if(g&&d)break;if(!d&&(a=A.data(b,"$ngAnimatePin"))){b=K(a);continue}b=b.parentNode}return(!t||h)&&!0!==m&&d&&g}function l(a,b,c){c=c||{};c.state=b;a.setAttribute("data-ng-animate",b);c=(b=y.get(a))?wa(b,c):c;y.set(a,c)}var y=new U,O=new U,B=null,P=d.$watch(function(){return 0===u.totalPendingRequests},function(a){a&&
(P(),d.$$postDigest(function(){d.$$postDigest(function(){null===B&&(B=!0)})}))}),m=Object.create(null);U=a.customFilter();var la=a.classNameFilter();I=function(){return!0};var fa=U||I,Ya=la?function(a,b){var c=[a.getAttribute("class"),b.addClass,b.removeClass].join(" ");return la.test(c)}:I,W=aa(t),Oa=Y.Node.prototype.contains||function(a){return this===a||!!(this.compareDocumentPosition(a)&16)},D={on:function(a,b,c){var l=va(b);m[a]=m[a]||[];m[a].push({node:l,callback:c});A(b).on("$destroy",function(){y.get(l)||
D.off(a,b,c)})},off:function(a,b,c){if(1!==arguments.length||G(arguments[0])){var l=m[a];l&&(m[a]=1===arguments.length?null:h(l,b,c))}else for(l in b=arguments[0],m)m[l]=h(m[l],b)},pin:function(a,b){Fa(sa(a),"element","not an element");Fa(sa(b),"parentElement","not an element");a.data("$ngAnimatePin",b)},push:function(a,b,c,l){c=c||{};c.domOperation=l;return q(a,b,c)},enabled:function(a,b){var c=arguments.length;if(0===c)b=!!B;else if(sa(a)){var l=K(a);if(1===c)b=!O.get(l);else{if(!O.has(l))A(a).on("$destroy",
ia);O.set(l,!b)}}else b=B=!!a;return b}};return D}]}]).provider("$$animateCache",function(){var a=0,b=Object.create(null);this.$get=[function(){return{cacheKey:function(b,d,f,k){var e=b.parentNode;b=[e.$$ngAnimateParentKey||(e.$$ngAnimateParentKey=++a),d,b.getAttribute("class")];f&&b.push(f);k&&b.push(k);return b.join(" ")},containsCachedAnimationWithoutDuration:function(a){return(a=b[a])&&!a.isValid||!1},flush:function(){b=Object.create(null)},count:function(a){return(a=b[a])?a.total:0},get:function(a){return(a=
b[a])&&a.value},put:function(a,d,f){b[a]?(b[a].total++,b[a].value=d):b[a]={total:1,value:d,isValid:f}}}}]}).provider("$$animation",["$animateProvider",function(a){var b=this.drivers=[];this.$get=["$$jqLite","$rootScope","$injector","$$AnimateRunner","$$Map","$$rAFScheduler","$$animateCache",function(a,d,f,k,e,Q,L){function x(a){function b(a){if(a.processed)return a;a.processed=!0;var d=a.domNode,t=d.parentNode;f.set(d,a);for(var h;t;){if(h=f.get(t)){h.processed||(h=b(h));break}t=t.parentNode}(h||
c).children.push(a);return a}var c={children:[]},d,f=new e;for(d=0;d<a.length;d++){var da=a[d];f.set(da.domNode,a[d]={domNode:da.domNode,element:da.element,fn:da.fn,children:[]})}for(d=0;d<a.length;d++)b(a[d]);return function(a){var b=[],c=[],d;for(d=0;d<a.children.length;d++)c.push(a.children[d]);a=c.length;var t=0,f=[];for(d=0;d<c.length;d++){var g=c[d];0>=a&&(a=t,t=0,b.push(f),f=[]);f.push(g);g.children.forEach(function(a){t++;c.push(a)});a--}f.length&&b.push(f);return b}(c)}var C=[],U=aa(a);return function(e,
H,u){function t(a){a=a.hasAttribute("ng-animate-ref")?[a]:a.querySelectorAll("[ng-animate-ref]");var b=[];s(a,function(a){var c=a.getAttribute("ng-animate-ref");c&&c.length&&b.push(a)});return b}function I(a){var b=[],c={};s(a,function(a,d){var l=K(a.element),g=0<=["enter","move"].indexOf(a.event),l=a.structural?t(l):[];if(l.length){var f=g?"to":"from";s(l,function(a){var b=a.getAttribute("ng-animate-ref");c[b]=c[b]||{};c[b][f]={animationID:d,element:A(a)}})}else b.push(a)});var d={},g={};s(c,function(c,
t){var f=c.from,e=c.to;if(f&&e){var h=a[f.animationID],k=a[e.animationID],E=f.animationID.toString();if(!g[E]){var I=g[E]={structural:!0,beforeStart:function(){h.beforeStart();k.beforeStart()},close:function(){h.close();k.close()},classes:da(h.classes,k.classes),from:h,to:k,anchors:[]};I.classes.length?b.push(I):(b.push(h),b.push(k))}g[E].anchors.push({out:f.element,"in":e.element})}else f=f?f.animationID:e.animationID,e=f.toString(),d[e]||(d[e]=!0,b.push(a[f]))});return b}function da(a,b){a=a.split(" ");
b=b.split(" ");for(var c=[],d=0;d<a.length;d++){var g=a[d];if("ng-"!==g.substring(0,3))for(var t=0;t<b.length;t++)if(g===b[t]){c.push(g);break}}return c.join(" ")}function ia(a){for(var c=b.length-1;0<=c;c--){var d=f.get(b[c])(a);if(d)return d}}function v(a,b){function c(a){(a=a.data("$$animationRunner"))&&a.setHost(b)}a.from&&a.to?(c(a.from.element),c(a.to.element)):c(a.element)}function ua(){var a=e.data("$$animationRunner");!a||"leave"===H&&u.$$domOperationFired||a.end()}function h(b){e.off("$destroy",
ua);e.removeData("$$animationRunner");U(e,u);ha(e,u);u.domOperation();E&&a.removeClass(e,E);F.complete(!b)}u=pa(u);var q=0<=["enter","move","leave"].indexOf(H),F=new k({end:function(){h()},cancel:function(){h(!0)}});if(!b.length)return h(),F;var g=Ga(e.attr("class"),Ga(u.addClass,u.removeClass)),E=u.tempClasses;E&&(g+=" "+E,u.tempClasses=null);q&&e.data("$$animatePrepareClasses","ng-"+H+"-prepare");e.data("$$animationRunner",F);C.push({element:e,classes:g,event:H,structural:q,options:u,beforeStart:function(){E=
(E?E+" ":"")+"ng-animate";a.addClass(e,E);var b=e.data("$$animatePrepareClasses");b&&a.removeClass(e,b)},close:h});e.on("$destroy",ua);if(1<C.length)return F;d.$$postDigest(function(){var b=[];s(C,function(a){a.element.data("$$animationRunner")?b.push(a):a.close()});C.length=0;var d=I(b),g=[];s(d,function(a){var b=a.from?a.from.element:a.element,c=u.addClass,d=L.cacheKey(b[0],a.event,(c?c+" ":"")+"ng-animate",u.removeClass);g.push({element:b,domNode:K(b),fn:function(){var b,c=a.close;if(L.containsCachedAnimationWithoutDuration(d))c();
else{a.beforeStart();if((a.anchors?a.from.element||a.to.element:a.element).data("$$animationRunner")){var g=ia(a);g&&(b=g.start)}b?(b=b(),b.done(function(a){c(!a)}),v(a,b)):c()}}})});for(var d=x(g),t=0;t<d.length;t++)for(var f=d[t],e=0;e<f.length;e++){var h=f[e],k=h.element;d[t][e]=h.fn;0===t?k.removeData("$$animatePrepareClasses"):(h=k.data("$$animatePrepareClasses"))&&a.addClass(k,h)}Q(d)});return F}}]}]).provider("$animateCss",["$animateProvider",function(a){this.$get=["$window","$$jqLite","$$AnimateRunner",
"$timeout","$$animateCache","$$forceReflow","$sniffer","$$rAFScheduler","$$animateQueue",function(a,c,d,f,k,e,Q,L,x){function C(d,f,e,x){var v,s="stagger-"+e;0<k.count(e)&&(v=k.get(s),v||(f=$(f,"-stagger"),c.addClass(d,f),v=Ka(a,d,x),v.animationDuration=Math.max(v.animationDuration,0),v.transitionDuration=Math.max(v.transitionDuration,0),c.removeClass(d,f),k.put(s,v,!0)));return v||{}}function U(a){u.push(a);L.waitUntilQuiet(function(){k.flush();for(var a=e(),b=0;b<u.length;b++)u[b](a);u.length=0})}
function z(c,d,f,e){d=k.get(f);d||(d=Ka(a,c,Wa),"infinite"===d.animationIterationCount&&(d.animationIterationCount=1));k.put(f,d,e||0<d.transitionDuration||0<d.animationDuration);c=d;f=c.animationDelay;e=c.transitionDelay;c.maxDelay=f&&e?Math.max(f,e):f||e;c.maxDuration=Math.max(c.animationDuration*c.animationIterationCount,c.transitionDuration);return c}var H=aa(c),u=[];return function(a,b){function e(){v()}function L(){v(!0)}function v(b){if(!(P||la&&m)){P=!0;m=!1;V&&!g.$$skipPreparationClasses&&
c.removeClass(a,V);ba&&c.removeClass(a,ba);xa(l,!1);ra.blockTransitions(l,!1);s(y,function(a){l.style[a[0]]=""});H(a,g);ha(a,g);Object.keys(E).length&&s(E,function(a,b){a?l.style.setProperty(b,a):l.style.removeProperty(b)});if(g.onDone)g.onDone();w&&w.length&&a.off(w.join(" "),q);var d=a.data("$$animateCss");d&&(f.cancel(d[0].timer),a.removeData("$$animateCss"));fa&&fa.complete(!b)}}function u(a){p.blockTransition&&ra.blockTransitions(l,a);p.blockKeyframeAnimation&&xa(l,!!a)}function h(){fa=new d({end:e,
cancel:L});U(N);v();return{$$willAnimate:!1,start:function(){return fa},end:e}}function q(a){a.stopPropagation();var b=a.originalEvent||a;b.target===l&&(a=b.$manualTimeStamp||Date.now(),b=parseFloat(b.elapsedTime.toFixed(3)),Math.max(a-J,0)>=G&&b>=D&&(la=!0,v()))}function F(){function b(){if(!P){u(!1);s(y,function(a){l.style[a[0]]=a[1]});H(a,g);c.addClass(a,ba);if(p.recalculateTimingStyles){T=l.getAttribute("class")+" "+V;ka=k.cacheKey(l,ja,g.addClass,g.removeClass);r=z(l,T,ka,!1);ga=r.maxDelay;W=
Math.max(ga,0);D=r.maxDuration;if(0===D){v();return}p.hasTransitions=0<r.transitionDuration;p.hasAnimations=0<r.animationDuration}p.applyAnimationDelay&&(ga="boolean"!==typeof g.delay&&ya(g.delay)?parseFloat(g.delay):ga,W=Math.max(ga,0),r.animationDelay=ga,ea=[qa,ga+"s"],y.push(ea),l.style[ea[0]]=ea[1]);G=1E3*W;R=1E3*D;if(g.easing){var e,h=g.easing;p.hasTransitions&&(e=M+"TimingFunction",y.push([e,h]),l.style[e]=h);p.hasAnimations&&(e=ca+"TimingFunction",y.push([e,h]),l.style[e]=h)}r.transitionDuration&&
w.push(Aa);r.animationDuration&&w.push(Ba);J=Date.now();var m=G+1.5*R;e=J+m;var h=a.data("$$animateCss")||[],F=!0;if(h.length){var n=h[0];(F=e>n.expectedEndTime)?f.cancel(n.timer):h.push(v)}F&&(m=f(d,m,!1),h[0]={timer:m,expectedEndTime:e},h.push(v),a.data("$$animateCss",h));if(w.length)a.on(w.join(" "),q);g.to&&(g.cleanupStyles&&Ma(E,l,Object.keys(g.to)),Ja(a,g))}}function d(){var b=a.data("$$animateCss");if(b){for(var c=1;c<b.length;c++)b[c]();a.removeData("$$animateCss")}}if(!P)if(l.parentNode){var e=
function(a){if(la)m&&a&&(m=!1,v());else if(m=!a,r.animationDuration)if(a=xa(l,m),m)y.push(a);else{var b=y,c=b.indexOf(a);0<=a&&b.splice(c,1)}},h=0<aa&&(r.transitionDuration&&0===X.transitionDuration||r.animationDuration&&0===X.animationDuration)&&Math.max(X.animationDelay,X.transitionDelay);h?f(b,Math.floor(h*aa*1E3),!1):b();A.resume=function(){e(!0)};A.pause=function(){e(!1)}}else v()}var g=b||{};g.$$prepared||(g=pa(Da(g)));var E={},l=K(a);if(!l||!l.parentNode||!x.enabled())return h();var y=[],O=
a.attr("class"),B=Qa(g),P,m,la,fa,A,W,G,D,R,J,w=[];if(0===g.duration||!Q.animations&&!Q.transitions)return h();var ja=g.event&&Z(g.event)?g.event.join(" "):g.event,Y=ja&&g.structural,n="",S="";Y?n=$(ja,"ng-",!0):ja&&(n=ja);g.addClass&&(S+=$(g.addClass,"-add"));g.removeClass&&(S.length&&(S+=" "),S+=$(g.removeClass,"-remove"));g.applyClassesEarly&&S.length&&H(a,g);var V=[n,S].join(" ").trim(),T=O+" "+V,O=B.to&&0<Object.keys(B.to).length;if(!(0<(g.keyframeStyle||"").length||O||V))return h();var X,ka=
k.cacheKey(l,ja,g.addClass,g.removeClass);if(k.containsCachedAnimationWithoutDuration(ka))return V=null,h();0<g.stagger?(B=parseFloat(g.stagger),X={transitionDelay:B,animationDelay:B,transitionDuration:0,animationDuration:0}):X=C(l,V,ka,Xa);g.$$skipPreparationClasses||c.addClass(a,V);g.transitionStyle&&(B=[M,g.transitionStyle],ma(l,B),y.push(B));0<=g.duration&&(B=0<l.style[M].length,B=La(g.duration,B),ma(l,B),y.push(B));g.keyframeStyle&&(B=[ca,g.keyframeStyle],ma(l,B),y.push(B));var aa=X?0<=g.staggerIndex?
g.staggerIndex:k.count(ka):0;(n=0===aa)&&!g.skipBlocking&&ra.blockTransitions(l,9999);var r=z(l,T,ka,!Y),ga=r.maxDelay;W=Math.max(ga,0);D=r.maxDuration;var p={};p.hasTransitions=0<r.transitionDuration;p.hasAnimations=0<r.animationDuration;p.hasTransitionAll=p.hasTransitions&&"all"===r.transitionProperty;p.applyTransitionDuration=O&&(p.hasTransitions&&!p.hasTransitionAll||p.hasAnimations&&!p.hasTransitions);p.applyAnimationDuration=g.duration&&p.hasAnimations;p.applyTransitionDelay=ya(g.delay)&&(p.applyTransitionDuration||
p.hasTransitions);p.applyAnimationDelay=ya(g.delay)&&p.hasAnimations;p.recalculateTimingStyles=0<S.length;if(p.applyTransitionDuration||p.applyAnimationDuration)D=g.duration?parseFloat(g.duration):D,p.applyTransitionDuration&&(p.hasTransitions=!0,r.transitionDuration=D,B=0<l.style[M+"Property"].length,y.push(La(D,B))),p.applyAnimationDuration&&(p.hasAnimations=!0,r.animationDuration=D,y.push([Ca,D+"s"]));if(0===D&&!p.recalculateTimingStyles)return h();var ba=$(V,"-active");if(null!=g.delay){var ea;
"boolean"!==typeof g.delay&&(ea=parseFloat(g.delay),W=Math.max(ea,0));p.applyTransitionDelay&&y.push([na,ea+"s"]);p.applyAnimationDelay&&y.push([qa,ea+"s"])}null==g.duration&&0<r.transitionDuration&&(p.recalculateTimingStyles=p.recalculateTimingStyles||n);G=1E3*W;R=1E3*D;g.skipBlocking||(p.blockTransition=0<r.transitionDuration,p.blockKeyframeAnimation=0<r.animationDuration&&0<X.animationDelay&&0===X.animationDuration);g.from&&(g.cleanupStyles&&Ma(E,l,Object.keys(g.from)),Ia(a,g));p.blockTransition||
p.blockKeyframeAnimation?u(D):g.skipBlocking||ra.blockTransitions(l,!1);return{$$willAnimate:!0,end:e,start:function(){if(!P)return A={end:e,cancel:L,resume:null,pause:null},fa=new d(A),U(F),fa}}}}]}]).provider("$$animateCssDriver",["$$animationProvider",function(a){a.drivers.push("$$animateCssDriver");this.$get=["$animateCss","$rootScope","$$AnimateRunner","$rootElement","$sniffer","$$jqLite","$document",function(a,c,d,f,k,e,Q){function L(a){return a.replace(/\bng-\S+\b/g,"")}function x(a,b){G(a)&&
(a=a.split(" "));G(b)&&(b=b.split(" "));return a.filter(function(a){return-1===b.indexOf(a)}).join(" ")}function C(c,e,f){function k(a){var b={},c=K(a).getBoundingClientRect();s(["width","height","top","left"],function(a){var d=c[a];switch(a){case "top":d+=H.scrollTop;break;case "left":d+=H.scrollLeft}b[a]=Math.floor(d)+"px"});return b}function v(){var c=L(f.attr("class")||""),d=x(c,q),c=x(q,c),d=a(h,{to:k(f),addClass:"ng-anchor-in "+d,removeClass:"ng-anchor-out "+c,delay:!0});return d.$$willAnimate?
d:null}function C(){h.remove();e.removeClass("ng-animate-shim");f.removeClass("ng-animate-shim")}var h=A(K(e).cloneNode(!0)),q=L(h.attr("class")||"");e.addClass("ng-animate-shim");f.addClass("ng-animate-shim");h.addClass("ng-anchor");u.append(h);var F;c=function(){var c=a(h,{addClass:"ng-anchor-out",delay:!0,from:k(e)});return c.$$willAnimate?c:null}();if(!c&&(F=v(),!F))return C();var g=c||F;return{start:function(){function a(){c&&c.end()}var b,c=g.start();c.done(function(){c=null;if(!F&&(F=v()))return c=
F.start(),c.done(function(){c=null;C();b.complete()}),c;C();b.complete()});return b=new d({end:a,cancel:a})}}}function z(a,b,c,e){var f=oa(a,N),k=oa(b,N),h=[];s(e,function(a){(a=C(c,a.out,a["in"]))&&h.push(a)});if(f||k||0!==h.length)return{start:function(){function a(){s(b,function(a){a.end()})}var b=[];f&&b.push(f.start());k&&b.push(k.start());s(h,function(a){b.push(a.start())});var c=new d({end:a,cancel:a});d.all(b,function(a){c.complete(a)});return c}}}function oa(c){var d=c.element,e=c.options||
{};c.structural&&(e.event=c.event,e.structural=!0,e.applyClassesEarly=!0,"leave"===c.event&&(e.onDone=e.domOperation));e.preparationClasses&&(e.event=ba(e.event,e.preparationClasses));c=a(d,e);return c.$$willAnimate?c:null}if(!k.animations&&!k.transitions)return N;var H=Q[0].body;c=K(f);var u=A(c.parentNode&&11===c.parentNode.nodeType||H.contains(c)?c:H);return function(a){return a.from&&a.to?z(a.from,a.to,a.classes,a.anchors):oa(a)}}]}]).provider("$$animateJs",["$animateProvider",function(a){this.$get=
["$injector","$$AnimateRunner","$$jqLite",function(b,c,d){function f(c){c=Z(c)?c:c.split(" ");for(var d=[],f={},k=0;k<c.length;k++){var s=c[k],z=a.$$registeredAnimations[s];z&&!f[s]&&(d.push(b.get(z)),f[s]=!0)}return d}var k=aa(d);return function(a,b,d,x){function C(){x.domOperation();k(a,x)}function z(a,b,d,f,e){switch(d){case "animate":b=[b,f.from,f.to,e];break;case "setClass":b=[b,t,I,e];break;case "addClass":b=[b,t,e];break;case "removeClass":b=[b,I,e];break;default:b=[b,e]}b.push(f);if(a=a.apply(a,
b))if(Ea(a.start)&&(a=a.start()),a instanceof c)a.done(e);else if(Ea(a))return a;return N}function A(a,b,d,e,f){var h=[];s(e,function(e){var l=e[f];l&&h.push(function(){var e,f,h=!1,k=function(a){h||(h=!0,(f||N)(a),e.complete(!a))};e=new c({end:function(){k()},cancel:function(){k(!0)}});f=z(l,a,b,d,function(a){k(!1===a)});return e})});return h}function H(a,b,d,e,f){var h=A(a,b,d,e,f);if(0===h.length){var k,q;"beforeSetClass"===f?(k=A(a,"removeClass",d,e,"beforeRemoveClass"),q=A(a,"addClass",d,e,"beforeAddClass")):
"setClass"===f&&(k=A(a,"removeClass",d,e,"removeClass"),q=A(a,"addClass",d,e,"addClass"));k&&(h=h.concat(k));q&&(h=h.concat(q))}if(0!==h.length)return function(a){var b=[];h.length&&s(h,function(a){b.push(a())});b.length?c.all(b,a):a();return function(a){s(b,function(b){a?b.cancel():b.end()})}}}var u=!1;3===arguments.length&&ta(d)&&(x=d,d=null);x=pa(x);d||(d=a.attr("class")||"",x.addClass&&(d+=" "+x.addClass),x.removeClass&&(d+=" "+x.removeClass));var t=x.addClass,I=x.removeClass,G=f(d),K,v;if(G.length){var M,
h;"leave"===b?(h="leave",M="afterLeave"):(h="before"+b.charAt(0).toUpperCase()+b.substr(1),M=b);"enter"!==b&&"move"!==b&&(K=H(a,b,x,G,h));v=H(a,b,x,G,M)}if(K||v){var q;return{$$willAnimate:!0,end:function(){q?q.end():(u=!0,C(),ha(a,x),q=new c,q.complete(!0));return q},start:function(){function b(c){u=!0;C();ha(a,x);q.complete(c)}if(q)return q;q=new c;var d,f=[];K&&f.push(function(a){d=K(a)});f.length?f.push(function(a){C();a(!0)}):C();v&&f.push(function(a){d=v(a)});q.setHost({end:function(){u||((d||
N)(void 0),b(void 0))},cancel:function(){u||((d||N)(!0),b(!0))}});c.chain(f,b);return q}}}}}]}]).provider("$$animateJsDriver",["$$animationProvider",function(a){a.drivers.push("$$animateJsDriver");this.$get=["$$animateJs","$$AnimateRunner",function(a,c){function d(c){return a(c.element,c.event,c.classes,c.options)}return function(a){if(a.from&&a.to){var b=d(a.from),e=d(a.to);if(b||e)return{start:function(){function a(){return function(){s(d,function(a){a.end()})}}var d=[];b&&d.push(b.start());e&&
d.push(e.start());c.all(d,function(a){f.complete(a)});var f=new c({end:a(),cancel:a()});return f}}}else return d(a)}}]}])})(window,window.angular);
//# sourceMappingURL=angular-animate.min.js.map

;
/*_/^\_I_/^\_N_/^\_F_/^\_I_/^\_N_/^\_I_/^\_T_/^\_E_/^\_

 (c) Copyright Infinite Talent 2021  

`\V/'I`\V/'N`\V/'F`\V/'I`\V/'N`\V/'I`\V/'T`\V/'E`\V/'*/
/*
 AngularJS v1.8.2
 (c) 2010-2020 Google LLC. http://angularjs.org
 License: MIT
*/
(function(t,p){'use strict';function q(g,h,s){n.directive(g,["$parse","$swipe",function(a,b){return function(c,e,f){function k(a){if(!d)return!1;var b=Math.abs(a.y-d.y);a=(a.x-d.x)*h;return l&&75>b&&0<a&&30<a&&.3>b/a}var m=a(f[g]),d,l,r=["touch"];p.isDefined(f.ngSwipeDisableMouse)||r.push("mouse");b.bind(e,{start:function(a,b){d=a;l=!0},cancel:function(a){l=!1},end:function(a,b){k(a)&&c.$apply(function(){e.triggerHandler(s);m(c,{$event:b})})}},r)}}])}var n=p.module("ngTouch",[]);n.info({angularVersion:"1.8.2"});
n.factory("$swipe",[function(){function g(a){a=a.originalEvent||a;var b=a.touches&&a.touches.length?a.touches:[a];a=a.changedTouches&&a.changedTouches[0]||b[0];return{x:a.clientX,y:a.clientY}}function h(a,b){var c=[];p.forEach(a,function(a){(a=n[a][b])&&c.push(a)});return c.join(" ")}var n={mouse:{start:"mousedown",move:"mousemove",end:"mouseup"},touch:{start:"touchstart",move:"touchmove",end:"touchend",cancel:"touchcancel"},pointer:{start:"pointerdown",move:"pointermove",end:"pointerup",cancel:"pointercancel"}};
return{bind:function(a,b,c){var e,f,k,m,d=!1;c=c||["mouse","touch","pointer"];a.on(h(c,"start"),function(a){k=g(a);d=!0;f=e=0;m=k;b.start&&b.start(k,a)});var l=h(c,"cancel");if(l)a.on(l,function(a){d=!1;b.cancel&&b.cancel(a)});a.on(h(c,"move"),function(a){if(d&&k){var c=g(a);e+=Math.abs(c.x-m.x);f+=Math.abs(c.y-m.y);m=c;10>e&&10>f||(f>e?(d=!1,b.cancel&&b.cancel(a)):(a.preventDefault(),b.move&&b.move(c,a)))}});a.on(h(c,"end"),function(a){d&&(d=!1,b.end&&b.end(g(a),a))})}}}]);q("ngSwipeLeft",-1,"swipeleft");
q("ngSwipeRight",1,"swiperight")})(window,window.angular);
//# sourceMappingURL=angular-touch.min.js.map

;
/*_/^\_I_/^\_N_/^\_F_/^\_I_/^\_N_/^\_I_/^\_T_/^\_E_/^\_

 (c) Copyright Infinite Talent 2021  

`\V/'I`\V/'N`\V/'F`\V/'I`\V/'N`\V/'I`\V/'T`\V/'E`\V/'*/


/*!
 * ngImgCrop v0.3.2
 * https://github.com/alexk111/ngImgCrop
 *
 * Copyright (c) 2014 Alex Kaul
 * License: MIT
 *
 * Generated at Wednesday, December 3rd, 2014, 3:54:12 PM
 */
(function () {
    'use strict';

    var crop = angular.module('ngImgCrop', []);

    crop.factory('cropAreaCircle', ['cropArea', function (CropArea) {
        var CropAreaCircle = function () {
            CropArea.apply(this, arguments);

            this._boxResizeBaseSize = 20;
            this._boxResizeNormalRatio = 0.9;
            this._boxResizeHoverRatio = 1.2;
            this._iconMoveNormalRatio = 0.9;
            this._iconMoveHoverRatio = 1.2;

            this._boxResizeNormalSize = this._boxResizeBaseSize * this._boxResizeNormalRatio;
            this._boxResizeHoverSize = this._boxResizeBaseSize * this._boxResizeHoverRatio;

            this._posDragStartX = 0;
            this._posDragStartY = 0;
            this._posResizeStartX = 0;
            this._posResizeStartY = 0;
            this._posResizeStartSize = 0;

            this._boxResizeIsHover = false;
            this._areaIsHover = false;
            this._boxResizeIsDragging = false;
            this._areaIsDragging = false;
        };

        CropAreaCircle.prototype = new CropArea();

        CropAreaCircle.prototype._calcCirclePerimeterCoords = function (angleDegrees) {
            var hSize = this._size / 2;
            var angleRadians = angleDegrees * (Math.PI / 180),
                circlePerimeterX = this._x + hSize * Math.cos(angleRadians),
                circlePerimeterY = this._y + hSize * Math.sin(angleRadians);
            return [circlePerimeterX, circlePerimeterY];
        };

        CropAreaCircle.prototype._calcResizeIconCenterCoords = function () {
            return this._calcCirclePerimeterCoords(-45);
        };

        CropAreaCircle.prototype._isCoordWithinArea = function (coord) {
            return Math.sqrt((coord[0] - this._x) * (coord[0] - this._x) + (coord[1] - this._y) * (coord[1] - this._y)) < this._size / 2;
        };
        CropAreaCircle.prototype._isCoordWithinBoxResize = function (coord) {
            var resizeIconCenterCoords = this._calcResizeIconCenterCoords();
            var hSize = this._boxResizeHoverSize / 2;
            return (coord[0] > resizeIconCenterCoords[0] - hSize && coord[0] < resizeIconCenterCoords[0] + hSize &&
                   coord[1] > resizeIconCenterCoords[1] - hSize && coord[1] < resizeIconCenterCoords[1] + hSize);
        };

        CropAreaCircle.prototype._drawArea = function (ctx, centerCoords, size) {
            ctx.arc(centerCoords[0], centerCoords[1], size / 2, 0, 2 * Math.PI);
        };

        CropAreaCircle.prototype.draw = function () {
            CropArea.prototype.draw.apply(this, arguments);

            // draw move icon
            this._cropCanvas.drawIconMove([this._x, this._y], this._areaIsHover ? this._iconMoveHoverRatio : this._iconMoveNormalRatio);

            // draw resize cubes
            this._cropCanvas.drawIconResizeBoxNESW(this._calcResizeIconCenterCoords(), this._boxResizeBaseSize, this._boxResizeIsHover ? this._boxResizeHoverRatio : this._boxResizeNormalRatio);
        };

        CropAreaCircle.prototype.processMouseMove = function (mouseCurX, mouseCurY) {
            var cursor = 'default';
            var res = false;

            this._boxResizeIsHover = false;
            this._areaIsHover = false;

            if (this._areaIsDragging) {
                this._x = mouseCurX - this._posDragStartX;
                this._y = mouseCurY - this._posDragStartY;
                this._areaIsHover = true;
                cursor = 'move';
                res = true;
                this._events.trigger('area-move');
            } else if (this._boxResizeIsDragging) {
                cursor = 'nesw-resize';
                var iFR, iFX, iFY;
                iFX = mouseCurX - this._posResizeStartX;
                iFY = this._posResizeStartY - mouseCurY;
                if (iFX > iFY) {
                    iFR = this._posResizeStartSize + iFY * 2;
                } else {
                    iFR = this._posResizeStartSize + iFX * 2;
                }

                this._size = Math.max(this._minSize, iFR);
                this._boxResizeIsHover = true;
                res = true;
                this._events.trigger('area-resize');
            } else if (this._isCoordWithinBoxResize([mouseCurX, mouseCurY])) {
                cursor = 'nesw-resize';
                this._areaIsHover = false;
                this._boxResizeIsHover = true;
                res = true;
            } else if (this._isCoordWithinArea([mouseCurX, mouseCurY])) {
                cursor = 'move';
                this._areaIsHover = true;
                res = true;
            }

            this._dontDragOutside();
            angular.element(this._ctx.canvas).css({ 'cursor': cursor });
            return res;
        };

        CropAreaCircle.prototype.processMouseDown = function (mouseDownX, mouseDownY) {
            if (this._isCoordWithinBoxResize([mouseDownX, mouseDownY])) {
                this._areaIsDragging = false;
                this._areaIsHover = false;
                this._boxResizeIsDragging = true;
                this._boxResizeIsHover = true;
                this._posResizeStartX = mouseDownX;
                this._posResizeStartY = mouseDownY;
                this._posResizeStartSize = this._size;
                this._events.trigger('area-resize-start');
            } else if (this._isCoordWithinArea([mouseDownX, mouseDownY])) {
                this._areaIsDragging = true;
                this._areaIsHover = true;
                this._boxResizeIsDragging = false;
                this._boxResizeIsHover = false;
                this._posDragStartX = mouseDownX - this._x;
                this._posDragStartY = mouseDownY - this._y;
                this._events.trigger('area-move-start');
            }
        };

        CropAreaCircle.prototype.processMouseUp = function (/*mouseUpX, mouseUpY*/) {
            if (this._areaIsDragging) {
                this._areaIsDragging = false;
                this._events.trigger('area-move-end');
            }
            if (this._boxResizeIsDragging) {
                this._boxResizeIsDragging = false;
                this._events.trigger('area-resize-end');
            }
            this._areaIsHover = false;
            this._boxResizeIsHover = false;

            this._posDragStartX = 0;
            this._posDragStartY = 0;
        };

        return CropAreaCircle;
    }]);



    crop.factory('cropAreaSquare', ['cropArea', function (CropArea) {
        var CropAreaSquare = function () {
            CropArea.apply(this, arguments);

            this._resizeCtrlBaseRadius = 10;
            this._resizeCtrlNormalRatio = 0.75;
            this._resizeCtrlHoverRatio = 1;
            this._iconMoveNormalRatio = 0.9;
            this._iconMoveHoverRatio = 1.2;

            this._resizeCtrlNormalRadius = this._resizeCtrlBaseRadius * this._resizeCtrlNormalRatio;
            this._resizeCtrlHoverRadius = this._resizeCtrlBaseRadius * this._resizeCtrlHoverRatio;

            this._posDragStartX = 0;
            this._posDragStartY = 0;
            this._posResizeStartX = 0;
            this._posResizeStartY = 0;
            this._posResizeStartSize = 0;

            this._resizeCtrlIsHover = -1;
            this._areaIsHover = false;
            this._resizeCtrlIsDragging = -1;
            this._areaIsDragging = false;
        };

        CropAreaSquare.prototype = new CropArea();

        CropAreaSquare.prototype._calcSquareCorners = function () {
            var hSize = this._size / 2;
            return [
              [this._x - hSize, this._y - hSize],
              [this._x + hSize, this._y - hSize],
              [this._x - hSize, this._y + hSize],
              [this._x + hSize, this._y + hSize]
            ];
        };

        CropAreaSquare.prototype._calcSquareDimensions = function () {
            var hSize = this._size / 2;
            return {
                left: this._x - hSize,
                top: this._y - hSize,
                right: this._x + hSize,
                bottom: this._y + hSize
            };
        };

        CropAreaSquare.prototype._isCoordWithinArea = function (coord) {
            var squareDimensions = this._calcSquareDimensions();
            return (coord[0] >= squareDimensions.left && coord[0] <= squareDimensions.right && coord[1] >= squareDimensions.top && coord[1] <= squareDimensions.bottom);
        };

        CropAreaSquare.prototype._isCoordWithinResizeCtrl = function (coord) {
            var resizeIconsCenterCoords = this._calcSquareCorners();
            var res = -1;
            for (var i = 0, len = resizeIconsCenterCoords.length; i < len; i++) {
                var resizeIconCenterCoords = resizeIconsCenterCoords[i];
                if (coord[0] > resizeIconCenterCoords[0] - this._resizeCtrlHoverRadius && coord[0] < resizeIconCenterCoords[0] + this._resizeCtrlHoverRadius &&
                   coord[1] > resizeIconCenterCoords[1] - this._resizeCtrlHoverRadius && coord[1] < resizeIconCenterCoords[1] + this._resizeCtrlHoverRadius) {
                    res = i;
                    break;
                }
            }
            return res;
        };

        CropAreaSquare.prototype._drawArea = function (ctx, centerCoords, size) {
            var hSize = size / 2;
            ctx.rect(centerCoords[0] - hSize, centerCoords[1] - hSize, size, size);
        };

        CropAreaSquare.prototype.draw = function () {
            CropArea.prototype.draw.apply(this, arguments);

            // draw move icon
            this._cropCanvas.drawIconMove([this._x, this._y], this._areaIsHover ? this._iconMoveHoverRatio : this._iconMoveNormalRatio);

            // draw resize cubes
            var resizeIconsCenterCoords = this._calcSquareCorners();
            for (var i = 0, len = resizeIconsCenterCoords.length; i < len; i++) {
                var resizeIconCenterCoords = resizeIconsCenterCoords[i];
                this._cropCanvas.drawIconResizeCircle(resizeIconCenterCoords, this._resizeCtrlBaseRadius, this._resizeCtrlIsHover === i ? this._resizeCtrlHoverRatio : this._resizeCtrlNormalRatio);
            }
        };

        CropAreaSquare.prototype.processMouseMove = function (mouseCurX, mouseCurY) {
            var cursor = 'default';
            var res = false;

            this._resizeCtrlIsHover = -1;
            this._areaIsHover = false;

            if (this._areaIsDragging) {
                this._x = mouseCurX - this._posDragStartX;
                this._y = mouseCurY - this._posDragStartY;
                this._areaIsHover = true;
                cursor = 'move';
                res = true;
                this._events.trigger('area-move');
            } else if (this._resizeCtrlIsDragging > -1) {
                var xMulti, yMulti;
                switch (this._resizeCtrlIsDragging) {
                    case 0: // Top Left
                        xMulti = -1;
                        yMulti = -1;
                        cursor = 'nwse-resize';
                        break;
                    case 1: // Top Right
                        xMulti = 1;
                        yMulti = -1;
                        cursor = 'nesw-resize';
                        break;
                    case 2: // Bottom Left
                        xMulti = -1;
                        yMulti = 1;
                        cursor = 'nesw-resize';
                        break;
                    case 3: // Bottom Right
                        xMulti = 1;
                        yMulti = 1;
                        cursor = 'nwse-resize';
                        break;
                }
                var iFX = (mouseCurX - this._posResizeStartX) * xMulti;
                var iFY = (mouseCurY - this._posResizeStartY) * yMulti;
                var iFR;
                if (iFX > iFY) {
                    iFR = this._posResizeStartSize + iFY;
                } else {
                    iFR = this._posResizeStartSize + iFX;
                }
                var wasSize = this._size;
                this._size = Math.max(this._minSize, iFR);
                var posModifier = (this._size - wasSize) / 2;
                this._x += posModifier * xMulti;
                this._y += posModifier * yMulti;
                this._resizeCtrlIsHover = this._resizeCtrlIsDragging;
                res = true;
                this._events.trigger('area-resize');
            } else {
                var hoveredResizeBox = this._isCoordWithinResizeCtrl([mouseCurX, mouseCurY]);
                if (hoveredResizeBox > -1) {
                    switch (hoveredResizeBox) {
                        case 0:
                            cursor = 'nwse-resize';
                            break;
                        case 1:
                            cursor = 'nesw-resize';
                            break;
                        case 2:
                            cursor = 'nesw-resize';
                            break;
                        case 3:
                            cursor = 'nwse-resize';
                            break;
                    }
                    this._areaIsHover = false;
                    this._resizeCtrlIsHover = hoveredResizeBox;
                    res = true;
                } else if (this._isCoordWithinArea([mouseCurX, mouseCurY])) {
                    cursor = 'move';
                    this._areaIsHover = true;
                    res = true;
                }
            }

            this._dontDragOutside();
            angular.element(this._ctx.canvas).css({ 'cursor': cursor });

            return res;
        };

        CropAreaSquare.prototype.processMouseDown = function (mouseDownX, mouseDownY) {
            var isWithinResizeCtrl = this._isCoordWithinResizeCtrl([mouseDownX, mouseDownY]);
            if (isWithinResizeCtrl > -1) {
                this._areaIsDragging = false;
                this._areaIsHover = false;
                this._resizeCtrlIsDragging = isWithinResizeCtrl;
                this._resizeCtrlIsHover = isWithinResizeCtrl;
                this._posResizeStartX = mouseDownX;
                this._posResizeStartY = mouseDownY;
                this._posResizeStartSize = this._size;
                this._events.trigger('area-resize-start');
            } else if (this._isCoordWithinArea([mouseDownX, mouseDownY])) {
                this._areaIsDragging = true;
                this._areaIsHover = true;
                this._resizeCtrlIsDragging = -1;
                this._resizeCtrlIsHover = -1;
                this._posDragStartX = mouseDownX - this._x;
                this._posDragStartY = mouseDownY - this._y;
                this._events.trigger('area-move-start');
            }
        };

        CropAreaSquare.prototype.processMouseUp = function (/*mouseUpX, mouseUpY*/) {
            if (this._areaIsDragging) {
                this._areaIsDragging = false;
                this._events.trigger('area-move-end');
            }
            if (this._resizeCtrlIsDragging > -1) {
                this._resizeCtrlIsDragging = -1;
                this._events.trigger('area-resize-end');
            }
            this._areaIsHover = false;
            this._resizeCtrlIsHover = -1;

            this._posDragStartX = 0;
            this._posDragStartY = 0;
        };

        return CropAreaSquare;
    }]);

    crop.factory('cropArea', ['cropCanvas', function (CropCanvas) {
        var CropArea = function (ctx, events) {
            this._ctx = ctx;
            this._events = events;

            this._minSize = 80;

            this._cropCanvas = new CropCanvas(ctx);

            this._image = new Image();
            this._x = 0;
            this._y = 0;
            this._size = 200;
        };

        /* GETTERS/SETTERS */

        CropArea.prototype.getImage = function () {
            return this._image;
        };
        CropArea.prototype.setImage = function (image) {
            this._image = image;
        };

        CropArea.prototype.getX = function () {
            return this._x;
        };
        CropArea.prototype.setX = function (x) {
            this._x = x;
            this._dontDragOutside();
        };

        CropArea.prototype.getY = function () {
            return this._y;
        };
        CropArea.prototype.setY = function (y) {
            this._y = y;
            this._dontDragOutside();
        };

        CropArea.prototype.getSize = function () {
            return this._size;
        };
        CropArea.prototype.setSize = function (size) {
            this._size = Math.max(this._minSize, size);
            this._dontDragOutside();
        };

        CropArea.prototype.getMinSize = function () {
            return this._minSize;
        };
        CropArea.prototype.setMinSize = function (size) {
            this._minSize = size;
            this._size = Math.max(this._minSize, this._size);
            this._dontDragOutside();
        };

        /* FUNCTIONS */
        CropArea.prototype._dontDragOutside = function () {
            var h = this._ctx.canvas.height,
                w = this._ctx.canvas.width;
            if (this._size > w) { this._size = w; }
            if (this._size > h) { this._size = h; }
            if (this._x < this._size / 2) { this._x = this._size / 2; }
            if (this._x > w - this._size / 2) { this._x = w - this._size / 2; }
            if (this._y < this._size / 2) { this._y = this._size / 2; }
            if (this._y > h - this._size / 2) { this._y = h - this._size / 2; }
        };

        CropArea.prototype._drawArea = function () { };

        CropArea.prototype.draw = function () {
            // draw crop area
            this._cropCanvas.drawCropArea(this._image, [this._x, this._y], this._size, this._drawArea);
        };

        CropArea.prototype.processMouseMove = function () { };

        CropArea.prototype.processMouseDown = function () { };

        CropArea.prototype.processMouseUp = function () { };

        return CropArea;
    }]);

    crop.factory('cropCanvas', [function () {
        // Shape = Array of [x,y]; [0, 0] - center
        var shapeArrowNW = [[-0.5, -2], [-3, -4.5], [-0.5, -7], [-7, -7], [-7, -0.5], [-4.5, -3], [-2, -0.5]];
        var shapeArrowNE = [[0.5, -2], [3, -4.5], [0.5, -7], [7, -7], [7, -0.5], [4.5, -3], [2, -0.5]];
        var shapeArrowSW = [[-0.5, 2], [-3, 4.5], [-0.5, 7], [-7, 7], [-7, 0.5], [-4.5, 3], [-2, 0.5]];
        var shapeArrowSE = [[0.5, 2], [3, 4.5], [0.5, 7], [7, 7], [7, 0.5], [4.5, 3], [2, 0.5]];
        var shapeArrowN = [[-1.5, -2.5], [-1.5, -6], [-5, -6], [0, -11], [5, -6], [1.5, -6], [1.5, -2.5]];
        var shapeArrowW = [[-2.5, -1.5], [-6, -1.5], [-6, -5], [-11, 0], [-6, 5], [-6, 1.5], [-2.5, 1.5]];
        var shapeArrowS = [[-1.5, 2.5], [-1.5, 6], [-5, 6], [0, 11], [5, 6], [1.5, 6], [1.5, 2.5]];
        var shapeArrowE = [[2.5, -1.5], [6, -1.5], [6, -5], [11, 0], [6, 5], [6, 1.5], [2.5, 1.5]];

        // Colors
        var colors = {
            areaOutline: '#fff',
            resizeBoxStroke: '#fff',
            resizeBoxFill: '#444',
            resizeBoxArrowFill: '#fff',
            resizeCircleStroke: '#fff',
            resizeCircleFill: '#444',
            moveIconFill: '#fff'
        };

        return function (ctx) {

            /* Base functions */

            // Calculate Point
            var calcPoint = function (point, offset, scale) {
                return [scale * point[0] + offset[0], scale * point[1] + offset[1]];
            };

            // Draw Filled Polygon
            var drawFilledPolygon = function (shape, fillStyle, centerCoords, scale) {
                ctx.save();
                ctx.fillStyle = fillStyle;
                ctx.beginPath();
                var pc, pc0 = calcPoint(shape[0], centerCoords, scale);
                ctx.moveTo(pc0[0], pc0[1]);

                for (var p in shape) {
                    if (p > 0) {
                        pc = calcPoint(shape[p], centerCoords, scale);
                        ctx.lineTo(pc[0], pc[1]);
                    }
                }

                ctx.lineTo(pc0[0], pc0[1]);
                ctx.fill();
                ctx.closePath();
                ctx.restore();
            };

            /* Icons */

            this.drawIconMove = function (centerCoords, scale) {
                drawFilledPolygon(shapeArrowN, colors.moveIconFill, centerCoords, scale);
                drawFilledPolygon(shapeArrowW, colors.moveIconFill, centerCoords, scale);
                drawFilledPolygon(shapeArrowS, colors.moveIconFill, centerCoords, scale);
                drawFilledPolygon(shapeArrowE, colors.moveIconFill, centerCoords, scale);
            };

            this.drawIconResizeCircle = function (centerCoords, circleRadius, scale) {
                var scaledCircleRadius = circleRadius * scale;
                ctx.save();
                ctx.strokeStyle = colors.resizeCircleStroke;
                ctx.lineWidth = 2;
                ctx.fillStyle = colors.resizeCircleFill;
                ctx.beginPath();
                ctx.arc(centerCoords[0], centerCoords[1], scaledCircleRadius, 0, 2 * Math.PI);
                ctx.fill();
                ctx.stroke();
                ctx.closePath();
                ctx.restore();
            };

            this.drawIconResizeBoxBase = function (centerCoords, boxSize, scale) {
                var scaledBoxSize = boxSize * scale;
                ctx.save();
                ctx.strokeStyle = colors.resizeBoxStroke;
                ctx.lineWidth = 2;
                ctx.fillStyle = colors.resizeBoxFill;
                ctx.fillRect(centerCoords[0] - scaledBoxSize / 2, centerCoords[1] - scaledBoxSize / 2, scaledBoxSize, scaledBoxSize);
                ctx.strokeRect(centerCoords[0] - scaledBoxSize / 2, centerCoords[1] - scaledBoxSize / 2, scaledBoxSize, scaledBoxSize);
                ctx.restore();
            };
            this.drawIconResizeBoxNESW = function (centerCoords, boxSize, scale) {
                this.drawIconResizeBoxBase(centerCoords, boxSize, scale);
                drawFilledPolygon(shapeArrowNE, colors.resizeBoxArrowFill, centerCoords, scale);
                drawFilledPolygon(shapeArrowSW, colors.resizeBoxArrowFill, centerCoords, scale);
            };
            this.drawIconResizeBoxNWSE = function (centerCoords, boxSize, scale) {
                this.drawIconResizeBoxBase(centerCoords, boxSize, scale);
                drawFilledPolygon(shapeArrowNW, colors.resizeBoxArrowFill, centerCoords, scale);
                drawFilledPolygon(shapeArrowSE, colors.resizeBoxArrowFill, centerCoords, scale);
            };

            /* Crop Area */

            this.drawCropArea = function (image, centerCoords, size, fnDrawClipPath) {
                var xRatio = image.width / ctx.canvas.width,
                    yRatio = image.height / ctx.canvas.height,
                    xLeft = centerCoords[0] - size / 2,
                    yTop = centerCoords[1] - size / 2;

                ctx.save();
                ctx.strokeStyle = colors.areaOutline;
                ctx.lineWidth = 2;
                ctx.beginPath();
                fnDrawClipPath(ctx, centerCoords, size);
                ctx.stroke();
                ctx.clip();

                // draw part of original image
                if (size > 0) {
                    ctx.drawImage(image, xLeft * xRatio, yTop * yRatio, size * xRatio, size * yRatio, xLeft, yTop, size, size);
                }

                ctx.beginPath();
                fnDrawClipPath(ctx, centerCoords, size);
                ctx.stroke();
                ctx.clip();

                ctx.restore();
            };

        };
    }]);

    /**
     * EXIF service is based on the exif-js library (https://github.com/jseidelin/exif-js)
     */

    crop.service('cropEXIF', [function () {
        var debug = false;

        var ExifTags = this.Tags = {

            // version tags
            0x9000: "ExifVersion",             // EXIF version
            0xA000: "FlashpixVersion",         // Flashpix format version

            // colorspace tags
            0xA001: "ColorSpace",              // Color space information tag

            // image configuration
            0xA002: "PixelXDimension",         // Valid width of meaningful image
            0xA003: "PixelYDimension",         // Valid height of meaningful image
            0x9101: "ComponentsConfiguration", // Information about channels
            0x9102: "CompressedBitsPerPixel",  // Compressed bits per pixel

            // user information
            0x927C: "MakerNote",               // Any desired information written by the manufacturer
            0x9286: "UserComment",             // Comments by user

            // related file
            0xA004: "RelatedSoundFile",        // Name of related sound file

            // date and time
            0x9003: "DateTimeOriginal",        // Date and time when the original image was generated
            0x9004: "DateTimeDigitized",       // Date and time when the image was stored digitally
            0x9290: "SubsecTime",              // Fractions of seconds for DateTime
            0x9291: "SubsecTimeOriginal",      // Fractions of seconds for DateTimeOriginal
            0x9292: "SubsecTimeDigitized",     // Fractions of seconds for DateTimeDigitized

            // picture-taking conditions
            0x829A: "ExposureTime",            // Exposure time (in seconds)
            0x829D: "FNumber",                 // F number
            0x8822: "ExposureProgram",         // Exposure program
            0x8824: "SpectralSensitivity",     // Spectral sensitivity
            0x8827: "ISOSpeedRatings",         // ISO speed rating
            0x8828: "OECF",                    // Optoelectric conversion factor
            0x9201: "ShutterSpeedValue",       // Shutter speed
            0x9202: "ApertureValue",           // Lens aperture
            0x9203: "BrightnessValue",         // Value of brightness
            0x9204: "ExposureBias",            // Exposure bias
            0x9205: "MaxApertureValue",        // Smallest F number of lens
            0x9206: "SubjectDistance",         // Distance to subject in meters
            0x9207: "MeteringMode",            // Metering mode
            0x9208: "LightSource",             // Kind of light source
            0x9209: "Flash",                   // Flash status
            0x9214: "SubjectArea",             // Location and area of main subject
            0x920A: "FocalLength",             // Focal length of the lens in mm
            0xA20B: "FlashEnergy",             // Strobe energy in BCPS
            0xA20C: "SpatialFrequencyResponse",    //
            0xA20E: "FocalPlaneXResolution",   // Number of pixels in width direction per FocalPlaneResolutionUnit
            0xA20F: "FocalPlaneYResolution",   // Number of pixels in height direction per FocalPlaneResolutionUnit
            0xA210: "FocalPlaneResolutionUnit",    // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
            0xA214: "SubjectLocation",         // Location of subject in image
            0xA215: "ExposureIndex",           // Exposure index selected on camera
            0xA217: "SensingMethod",           // Image sensor type
            0xA300: "FileSource",              // Image source (3 == DSC)
            0xA301: "SceneType",               // Scene type (1 == directly photographed)
            0xA302: "CFAPattern",              // Color filter array geometric pattern
            0xA401: "CustomRendered",          // Special processing
            0xA402: "ExposureMode",            // Exposure mode
            0xA403: "WhiteBalance",            // 1 = auto white balance, 2 = manual
            0xA404: "DigitalZoomRation",       // Digital zoom ratio
            0xA405: "FocalLengthIn35mmFilm",   // Equivalent foacl length assuming 35mm film camera (in mm)
            0xA406: "SceneCaptureType",        // Type of scene
            0xA407: "GainControl",             // Degree of overall image gain adjustment
            0xA408: "Contrast",                // Direction of contrast processing applied by camera
            0xA409: "Saturation",              // Direction of saturation processing applied by camera
            0xA40A: "Sharpness",               // Direction of sharpness processing applied by camera
            0xA40B: "DeviceSettingDescription",    //
            0xA40C: "SubjectDistanceRange",    // Distance to subject

            // other tags
            0xA005: "InteroperabilityIFDPointer",
            0xA420: "ImageUniqueID"            // Identifier assigned uniquely to each image
        };

        var TiffTags = this.TiffTags = {
            0x0100: "ImageWidth",
            0x0101: "ImageHeight",
            0x8769: "ExifIFDPointer",
            0x8825: "GPSInfoIFDPointer",
            0xA005: "InteroperabilityIFDPointer",
            0x0102: "BitsPerSample",
            0x0103: "Compression",
            0x0106: "PhotometricInterpretation",
            0x0112: "Orientation",
            0x0115: "SamplesPerPixel",
            0x011C: "PlanarConfiguration",
            0x0212: "YCbCrSubSampling",
            0x0213: "YCbCrPositioning",
            0x011A: "XResolution",
            0x011B: "YResolution",
            0x0128: "ResolutionUnit",
            0x0111: "StripOffsets",
            0x0116: "RowsPerStrip",
            0x0117: "StripByteCounts",
            0x0201: "JPEGInterchangeFormat",
            0x0202: "JPEGInterchangeFormatLength",
            0x012D: "TransferFunction",
            0x013E: "WhitePoint",
            0x013F: "PrimaryChromaticities",
            0x0211: "YCbCrCoefficients",
            0x0214: "ReferenceBlackWhite",
            0x0132: "DateTime",
            0x010E: "ImageDescription",
            0x010F: "Make",
            0x0110: "Model",
            0x0131: "Software",
            0x013B: "Artist",
            0x8298: "Copyright"
        };

        var GPSTags = this.GPSTags = {
            0x0000: "GPSVersionID",
            0x0001: "GPSLatitudeRef",
            0x0002: "GPSLatitude",
            0x0003: "GPSLongitudeRef",
            0x0004: "GPSLongitude",
            0x0005: "GPSAltitudeRef",
            0x0006: "GPSAltitude",
            0x0007: "GPSTimeStamp",
            0x0008: "GPSSatellites",
            0x0009: "GPSStatus",
            0x000A: "GPSMeasureMode",
            0x000B: "GPSDOP",
            0x000C: "GPSSpeedRef",
            0x000D: "GPSSpeed",
            0x000E: "GPSTrackRef",
            0x000F: "GPSTrack",
            0x0010: "GPSImgDirectionRef",
            0x0011: "GPSImgDirection",
            0x0012: "GPSMapDatum",
            0x0013: "GPSDestLatitudeRef",
            0x0014: "GPSDestLatitude",
            0x0015: "GPSDestLongitudeRef",
            0x0016: "GPSDestLongitude",
            0x0017: "GPSDestBearingRef",
            0x0018: "GPSDestBearing",
            0x0019: "GPSDestDistanceRef",
            0x001A: "GPSDestDistance",
            0x001B: "GPSProcessingMethod",
            0x001C: "GPSAreaInformation",
            0x001D: "GPSDateStamp",
            0x001E: "GPSDifferential"
        };

        var StringValues = this.StringValues = {
            ExposureProgram: {
                0: "Not defined",
                1: "Manual",
                2: "Normal program",
                3: "Aperture priority",
                4: "Shutter priority",
                5: "Creative program",
                6: "Action program",
                7: "Portrait mode",
                8: "Landscape mode"
            },
            MeteringMode: {
                0: "Unknown",
                1: "Average",
                2: "CenterWeightedAverage",
                3: "Spot",
                4: "MultiSpot",
                5: "Pattern",
                6: "Partial",
                255: "Other"
            },
            LightSource: {
                0: "Unknown",
                1: "Daylight",
                2: "Fluorescent",
                3: "Tungsten (incandescent light)",
                4: "Flash",
                9: "Fine weather",
                10: "Cloudy weather",
                11: "Shade",
                12: "Daylight fluorescent (D 5700 - 7100K)",
                13: "Day white fluorescent (N 4600 - 5400K)",
                14: "Cool white fluorescent (W 3900 - 4500K)",
                15: "White fluorescent (WW 3200 - 3700K)",
                17: "Standard light A",
                18: "Standard light B",
                19: "Standard light C",
                20: "D55",
                21: "D65",
                22: "D75",
                23: "D50",
                24: "ISO studio tungsten",
                255: "Other"
            },
            Flash: {
                0x0000: "Flash did not fire",
                0x0001: "Flash fired",
                0x0005: "Strobe return light not detected",
                0x0007: "Strobe return light detected",
                0x0009: "Flash fired, compulsory flash mode",
                0x000D: "Flash fired, compulsory flash mode, return light not detected",
                0x000F: "Flash fired, compulsory flash mode, return light detected",
                0x0010: "Flash did not fire, compulsory flash mode",
                0x0018: "Flash did not fire, auto mode",
                0x0019: "Flash fired, auto mode",
                0x001D: "Flash fired, auto mode, return light not detected",
                0x001F: "Flash fired, auto mode, return light detected",
                0x0020: "No flash function",
                0x0041: "Flash fired, red-eye reduction mode",
                0x0045: "Flash fired, red-eye reduction mode, return light not detected",
                0x0047: "Flash fired, red-eye reduction mode, return light detected",
                0x0049: "Flash fired, compulsory flash mode, red-eye reduction mode",
                0x004D: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",
                0x004F: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",
                0x0059: "Flash fired, auto mode, red-eye reduction mode",
                0x005D: "Flash fired, auto mode, return light not detected, red-eye reduction mode",
                0x005F: "Flash fired, auto mode, return light detected, red-eye reduction mode"
            },
            SensingMethod: {
                1: "Not defined",
                2: "One-chip color area sensor",
                3: "Two-chip color area sensor",
                4: "Three-chip color area sensor",
                5: "Color sequential area sensor",
                7: "Trilinear sensor",
                8: "Color sequential linear sensor"
            },
            SceneCaptureType: {
                0: "Standard",
                1: "Landscape",
                2: "Portrait",
                3: "Night scene"
            },
            SceneType: {
                1: "Directly photographed"
            },
            CustomRendered: {
                0: "Normal process",
                1: "Custom process"
            },
            WhiteBalance: {
                0: "Auto white balance",
                1: "Manual white balance"
            },
            GainControl: {
                0: "None",
                1: "Low gain up",
                2: "High gain up",
                3: "Low gain down",
                4: "High gain down"
            },
            Contrast: {
                0: "Normal",
                1: "Soft",
                2: "Hard"
            },
            Saturation: {
                0: "Normal",
                1: "Low saturation",
                2: "High saturation"
            },
            Sharpness: {
                0: "Normal",
                1: "Soft",
                2: "Hard"
            },
            SubjectDistanceRange: {
                0: "Unknown",
                1: "Macro",
                2: "Close view",
                3: "Distant view"
            },
            FileSource: {
                3: "DSC"
            },

            Components: {
                0: "",
                1: "Y",
                2: "Cb",
                3: "Cr",
                4: "R",
                5: "G",
                6: "B"
            }
        };

        function addEvent(element, event, handler) {
            if (element.addEventListener) {
                element.addEventListener(event, handler, false);
            } else if (element.attachEvent) {
                element.attachEvent("on" + event, handler);
            }
        }

        function imageHasData(img) {
            return !!(img.exifdata);
        }

        function base64ToArrayBuffer(base64, contentType) {
            contentType = contentType || base64.match(/^data\:([^\;]+)\;base64,/mi)[1] || ''; // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg'
            base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, '');
            var binary = atob(base64);
            var len = binary.length;
            var buffer = new ArrayBuffer(len);
            var view = new Uint8Array(buffer);
            for (var i = 0; i < len; i++) {
                view[i] = binary.charCodeAt(i);
            }
            return buffer;
        }

        function objectURLToBlob(url, callback) {
            var http = new XMLHttpRequest();
            http.open("GET", url, true);
            http.responseType = "blob";
            http.onload = function (e) {
                if (this.status == 200 || this.status === 0) {
                    callback(this.response);
                }
            };
            http.send();
        }

        function getImageData(img, callback) {
            function handleBinaryFile(binFile) {
                var data = findEXIFinJPEG(binFile);
                var iptcdata = findIPTCinJPEG(binFile);
                img.exifdata = data || {};
                img.iptcdata = iptcdata || {};
                if (callback) {
                    callback.call(img);
                }
            }

            if (img.src) {
                if (/^data\:/i.test(img.src)) { // Data URI
                    var arrayBuffer = base64ToArrayBuffer(img.src);
                    handleBinaryFile(arrayBuffer);

                } else if (/^blob\:/i.test(img.src)) { // Object URL
                    var fileReader = new FileReader();
                    fileReader.onload = function (e) {
                        handleBinaryFile(e.target.result);
                    };
                    objectURLToBlob(img.src, function (blob) {
                        fileReader.readAsArrayBuffer(blob);
                    });
                } else {
                    var http = new XMLHttpRequest();
                    http.onload = function () {
                        if (this.status == 200 || this.status === 0) {
                            handleBinaryFile(http.response);
                        } else {
                            throw "Could not load image";
                        }
                        http = null;
                    };
                    http.open("GET", img.src, true);
                    http.responseType = "arraybuffer";
                    http.send(null);
                }
            } else if (window.FileReader && (img instanceof window.Blob || img instanceof window.File)) {
                var fileReader = new FileReader();
                fileReader.onload = function (e) {
                    if (debug) console.log("Got file of length " + e.target.result.byteLength);
                    handleBinaryFile(e.target.result);
                };

                fileReader.readAsArrayBuffer(img);
            }
        }

        function findEXIFinJPEG(file) {
            var dataView = new DataView(file);

            if (debug) console.log("Got file of length " + file.byteLength);
            if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
                if (debug) console.log("Not a valid JPEG");
                return false; // not a valid jpeg
            }

            var offset = 2,
                length = file.byteLength,
                marker;

            while (offset < length) {
                if (dataView.getUint8(offset) != 0xFF) {
                    if (debug) console.log("Not a valid marker at offset " + offset + ", found: " + dataView.getUint8(offset));
                    return false; // not a valid marker, something is wrong
                }

                marker = dataView.getUint8(offset + 1);
                if (debug) console.log(marker);

                // we could implement handling for other markers here,
                // but we're only looking for 0xFFE1 for EXIF data

                if (marker == 225) {
                    if (debug) console.log("Found 0xFFE1 marker");

                    return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2);

                    // offset += 2 + file.getShortAt(offset+2, true);

                } else {
                    offset += 2 + dataView.getUint16(offset + 2);
                }

            }

        }

        function findIPTCinJPEG(file) {
            var dataView = new DataView(file);

            if (debug) console.log("Got file of length " + file.byteLength);
            if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
                if (debug) console.log("Not a valid JPEG");
                return false; // not a valid jpeg
            }

            var offset = 2,
                length = file.byteLength;

            var isFieldSegmentStart = function (dataView, offset) {
                return (
                    dataView.getUint8(offset) === 0x38 &&
                    dataView.getUint8(offset + 1) === 0x42 &&
                    dataView.getUint8(offset + 2) === 0x49 &&
                    dataView.getUint8(offset + 3) === 0x4D &&
                    dataView.getUint8(offset + 4) === 0x04 &&
                    dataView.getUint8(offset + 5) === 0x04
                );
            };

            while (offset < length) {

                if (isFieldSegmentStart(dataView, offset)) {

                    // Get the length of the name header (which is padded to an even number of bytes)
                    var nameHeaderLength = dataView.getUint8(offset + 7);
                    if (nameHeaderLength % 2 !== 0) nameHeaderLength += 1;
                    // Check for pre photoshop 6 format
                    if (nameHeaderLength === 0) {
                        // Always 4
                        nameHeaderLength = 4;
                    }

                    var startOffset = offset + 8 + nameHeaderLength;
                    var sectionLength = dataView.getUint16(offset + 6 + nameHeaderLength);

                    return readIPTCData(file, startOffset, sectionLength);

                    break;

                }

                // Not the marker, continue searching
                offset++;

            }

        }
        var IptcFieldMap = {
            0x78: 'caption',
            0x6E: 'credit',
            0x19: 'keywords',
            0x37: 'dateCreated',
            0x50: 'byline',
            0x55: 'bylineTitle',
            0x7A: 'captionWriter',
            0x69: 'headline',
            0x74: 'copyright',
            0x0F: 'category'
        };
        function readIPTCData(file, startOffset, sectionLength) {
            var dataView = new DataView(file);
            var data = {};
            var fieldValue, fieldName, dataSize, segmentType, segmentSize;
            var segmentStartPos = startOffset;
            while (segmentStartPos < startOffset + sectionLength) {
                if (dataView.getUint8(segmentStartPos) === 0x1C && dataView.getUint8(segmentStartPos + 1) === 0x02) {
                    segmentType = dataView.getUint8(segmentStartPos + 2);
                    if (segmentType in IptcFieldMap) {
                        dataSize = dataView.getInt16(segmentStartPos + 3);
                        segmentSize = dataSize + 5;
                        fieldName = IptcFieldMap[segmentType];
                        fieldValue = getStringFromDB(dataView, segmentStartPos + 5, dataSize);
                        // Check if we already stored a value with this name
                        if (data.hasOwnProperty(fieldName)) {
                            // Value already stored with this name, create multivalue field
                            if (data[fieldName] instanceof Array) {
                                data[fieldName].push(fieldValue);
                            }
                            else {
                                data[fieldName] = [data[fieldName], fieldValue];
                            }
                        }
                        else {
                            data[fieldName] = fieldValue;
                        }
                    }

                }
                segmentStartPos++;
            }
            return data;
        }

        function readTags(file, tiffStart, dirStart, strings, bigEnd) {
            var entries = file.getUint16(dirStart, !bigEnd),
                tags = {},
                entryOffset, tag,
                i;

            for (i = 0; i < entries; i++) {
                entryOffset = dirStart + i * 12 + 2;
                tag = strings[file.getUint16(entryOffset, !bigEnd)];
                if (!tag && debug) console.log("Unknown tag: " + file.getUint16(entryOffset, !bigEnd));
                tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd);
            }
            return tags;
        }

        function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) {
            var type = file.getUint16(entryOffset + 2, !bigEnd),
                numValues = file.getUint32(entryOffset + 4, !bigEnd),
                valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart,
                offset,
                vals, val, n,
                numerator, denominator;

            switch (type) {
                case 1: // byte, 8-bit unsigned int
                case 7: // undefined, 8-bit byte, value depending on field
                    if (numValues == 1) {
                        return file.getUint8(entryOffset + 8, !bigEnd);
                    } else {
                        offset = numValues > 4 ? valueOffset : (entryOffset + 8);
                        vals = [];
                        for (n = 0; n < numValues; n++) {
                            vals[n] = file.getUint8(offset + n);
                        }
                        return vals;
                    }

                case 2: // ascii, 8-bit byte
                    offset = numValues > 4 ? valueOffset : (entryOffset + 8);
                    return getStringFromDB(file, offset, numValues - 1);

                case 3: // short, 16 bit int
                    if (numValues == 1) {
                        return file.getUint16(entryOffset + 8, !bigEnd);
                    } else {
                        offset = numValues > 2 ? valueOffset : (entryOffset + 8);
                        vals = [];
                        for (n = 0; n < numValues; n++) {
                            vals[n] = file.getUint16(offset + 2 * n, !bigEnd);
                        }
                        return vals;
                    }

                case 4: // long, 32 bit int
                    if (numValues == 1) {
                        return file.getUint32(entryOffset + 8, !bigEnd);
                    } else {
                        vals = [];
                        for (n = 0; n < numValues; n++) {
                            vals[n] = file.getUint32(valueOffset + 4 * n, !bigEnd);
                        }
                        return vals;
                    }

                case 5:    // rational = two long values, first is numerator, second is denominator
                    if (numValues == 1) {
                        numerator = file.getUint32(valueOffset, !bigEnd);
                        denominator = file.getUint32(valueOffset + 4, !bigEnd);
                        val = new Number(numerator / denominator);
                        val.numerator = numerator;
                        val.denominator = denominator;
                        return val;
                    } else {
                        vals = [];
                        for (n = 0; n < numValues; n++) {
                            numerator = file.getUint32(valueOffset + 8 * n, !bigEnd);
                            denominator = file.getUint32(valueOffset + 4 + 8 * n, !bigEnd);
                            vals[n] = new Number(numerator / denominator);
                            vals[n].numerator = numerator;
                            vals[n].denominator = denominator;
                        }
                        return vals;
                    }

                case 9: // slong, 32 bit signed int
                    if (numValues == 1) {
                        return file.getInt32(entryOffset + 8, !bigEnd);
                    } else {
                        vals = [];
                        for (n = 0; n < numValues; n++) {
                            vals[n] = file.getInt32(valueOffset + 4 * n, !bigEnd);
                        }
                        return vals;
                    }

                case 10: // signed rational, two slongs, first is numerator, second is denominator
                    if (numValues == 1) {
                        return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset + 4, !bigEnd);
                    } else {
                        vals = [];
                        for (n = 0; n < numValues; n++) {
                            vals[n] = file.getInt32(valueOffset + 8 * n, !bigEnd) / file.getInt32(valueOffset + 4 + 8 * n, !bigEnd);
                        }
                        return vals;
                    }
            }
        }

        function getStringFromDB(buffer, start, length) {
            var outstr = "";
            for (var n = start; n < start + length; n++) {
                outstr += String.fromCharCode(buffer.getUint8(n));
            }
            return outstr;
        }

        function readEXIFData(file, start) {
            if (getStringFromDB(file, start, 4) != "Exif") {
                if (debug) console.log("Not valid EXIF data! " + getStringFromDB(file, start, 4));
                return false;
            }

            var bigEnd,
                tags, tag,
                exifData, gpsData,
                tiffOffset = start + 6;

            // test for TIFF validity and endianness
            if (file.getUint16(tiffOffset) == 0x4949) {
                bigEnd = false;
            } else if (file.getUint16(tiffOffset) == 0x4D4D) {
                bigEnd = true;
            } else {
                if (debug) console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
                return false;
            }

            if (file.getUint16(tiffOffset + 2, !bigEnd) != 0x002A) {
                if (debug) console.log("Not valid TIFF data! (no 0x002A)");
                return false;
            }

            var firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd);

            if (firstIFDOffset < 0x00000008) {
                if (debug) console.log("Not valid TIFF data! (First offset less than 8)", file.getUint32(tiffOffset + 4, !bigEnd));
                return false;
            }

            tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd);

            if (tags.ExifIFDPointer) {
                exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd);
                for (tag in exifData) {
                    switch (tag) {
                        case "LightSource":
                        case "Flash":
                        case "MeteringMode":
                        case "ExposureProgram":
                        case "SensingMethod":
                        case "SceneCaptureType":
                        case "SceneType":
                        case "CustomRendered":
                        case "WhiteBalance":
                        case "GainControl":
                        case "Contrast":
                        case "Saturation":
                        case "Sharpness":
                        case "SubjectDistanceRange":
                        case "FileSource":
                            exifData[tag] = StringValues[tag][exifData[tag]];
                            break;

                        case "ExifVersion":
                        case "FlashpixVersion":
                            exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]);
                            break;

                        case "ComponentsConfiguration":
                            exifData[tag] =
                                StringValues.Components[exifData[tag][0]] +
                                StringValues.Components[exifData[tag][1]] +
                                StringValues.Components[exifData[tag][2]] +
                                StringValues.Components[exifData[tag][3]];
                            break;
                    }
                    tags[tag] = exifData[tag];
                }
            }

            if (tags.GPSInfoIFDPointer) {
                gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd);
                for (tag in gpsData) {
                    switch (tag) {
                        case "GPSVersionID":
                            gpsData[tag] = gpsData[tag][0] +
                                "." + gpsData[tag][1] +
                                "." + gpsData[tag][2] +
                                "." + gpsData[tag][3];
                            break;
                    }
                    tags[tag] = gpsData[tag];
                }
            }

            return tags;
        }

        this.getData = function (img, callback) {
            if ((img instanceof Image || img instanceof HTMLImageElement) && !img.complete) return false;

            if (!imageHasData(img)) {
                getImageData(img, callback);
            } else {
                if (callback) {
                    callback.call(img);
                }
            }
            return true;
        }

        this.getTag = function (img, tag) {
            if (!imageHasData(img)) return;
            return img.exifdata[tag];
        }

        this.getAllTags = function (img) {
            if (!imageHasData(img)) return {};
            var a,
                data = img.exifdata,
                tags = {};
            for (a in data) {
                if (data.hasOwnProperty(a)) {
                    tags[a] = data[a];
                }
            }
            return tags;
        }

        this.pretty = function (img) {
            if (!imageHasData(img)) return "";
            var a,
                data = img.exifdata,
                strPretty = "";
            for (a in data) {
                if (data.hasOwnProperty(a)) {
                    if (typeof data[a] == "object") {
                        if (data[a] instanceof Number) {
                            strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a].denominator + "]\r\n";
                        } else {
                            strPretty += a + " : [" + data[a].length + " values]\r\n";
                        }
                    } else {
                        strPretty += a + " : " + data[a] + "\r\n";
                    }
                }
            }
            return strPretty;
        }

        this.readFromBinaryFile = function (file) {
            return findEXIFinJPEG(file);
        }
    }]);

    crop.factory('cropHost', ['$document', 'cropAreaCircle', 'cropAreaSquare', 'cropEXIF', function ($document, CropAreaCircle, CropAreaSquare, cropEXIF) {
        /* STATIC FUNCTIONS */

        // Get Element's Offset
        var getElementOffset = function (elem) {
            var box = elem.getBoundingClientRect();

            var body = document.body;
            var docElem = document.documentElement;

            var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
            var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;

            var clientTop = docElem.clientTop || body.clientTop || 0;
            var clientLeft = docElem.clientLeft || body.clientLeft || 0;

            var top = box.top + scrollTop - clientTop;
            var left = box.left + scrollLeft - clientLeft;

            return { top: Math.round(top), left: Math.round(left) };
        };

        return function (elCanvas, opts, events) {
            /* PRIVATE VARIABLES */

            // Object Pointers
            var ctx = null,
                image = null,
                theArea = null;

            // Dimensions
            var minCanvasDims = [100, 100],
                maxCanvasDims = [300, 300];

            // Result Image size
            var resImgSize = 200;

            // Result Image type
            var resImgFormat = 'image/png';

            // Result Image quality
            var resImgQuality = null;

            /* PRIVATE FUNCTIONS */

            // Draw Scene
            function drawScene() {
                // clear canvas
                ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

                if (image !== null) {
                    // draw source image
                    ctx.drawImage(image, 0, 0, ctx.canvas.width, ctx.canvas.height);

                    ctx.save();

                    // and make it darker
                    ctx.fillStyle = 'rgba(0, 0, 0, 0.65)';
                    ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);

                    ctx.restore();

                    // draw Area
                    theArea.draw();
                }
            }

            // Resets CropHost
            var resetCropHost = function () {
                if (image !== null) {
                    theArea.setImage(image);
                    var imageDims = [image.width, image.height],
                        imageRatio = image.width / image.height,
                        canvasDims = imageDims;

                    if (canvasDims[0] > maxCanvasDims[0]) {
                        canvasDims[0] = maxCanvasDims[0];
                        canvasDims[1] = canvasDims[0] / imageRatio;
                    } else if (canvasDims[0] < minCanvasDims[0]) {
                        canvasDims[0] = minCanvasDims[0];
                        canvasDims[1] = canvasDims[0] / imageRatio;
                    }
                    if (canvasDims[1] > maxCanvasDims[1]) {
                        canvasDims[1] = maxCanvasDims[1];
                        canvasDims[0] = canvasDims[1] * imageRatio;
                    } else if (canvasDims[1] < minCanvasDims[1]) {
                        canvasDims[1] = minCanvasDims[1];
                        canvasDims[0] = canvasDims[1] * imageRatio;
                    }

                    elCanvas.prop('width', canvasDims[0]).prop('height', canvasDims[1]).css({ 'margin-left': -canvasDims[0] / 2 + 'px', 'margin-top': -canvasDims[1] / 2 + 'px' });

                    theArea.setX(ctx.canvas.width / 2);
                    theArea.setY(ctx.canvas.height / 2);
                    theArea.setSize(Math.min(200, ctx.canvas.width / 2, ctx.canvas.height / 2));
                } else {
                    elCanvas.prop('width', 0).prop('height', 0).css({ 'margin-top': 0 });
                }

                drawScene();
            };

            /**
             * Returns event.changedTouches directly if event is a TouchEvent.
             * If event is a jQuery event, return changedTouches of event.originalEvent
             */
            var getChangedTouches = function (event) {
                if (angular.isDefined(event.changedTouches)) {
                    return event.changedTouches;
                } else {
                    return event.originalEvent.changedTouches;
                }
            };

            var onMouseMove = function (e) {
                if (image !== null) {
                    var offset = getElementOffset(ctx.canvas),
                        pageX, pageY;
                    if (e.type === 'touchmove') {
                        pageX = getChangedTouches(e)[0].pageX;
                        pageY = getChangedTouches(e)[0].pageY;
                    } else {
                        pageX = e.pageX;
                        pageY = e.pageY;
                    }
                    theArea.processMouseMove(pageX - offset.left, pageY - offset.top);
                    drawScene();
                }
            };

            var onMouseDown = function (e) {
                e.preventDefault();
                e.stopPropagation();
                if (image !== null) {
                    var offset = getElementOffset(ctx.canvas),
                        pageX, pageY;
                    if (e.type === 'touchstart') {
                        pageX = getChangedTouches(e)[0].pageX;
                        pageY = getChangedTouches(e)[0].pageY;
                    } else {
                        pageX = e.pageX;
                        pageY = e.pageY;
                    }
                    theArea.processMouseDown(pageX - offset.left, pageY - offset.top);
                    drawScene();
                }
            };

            var onMouseUp = function (e) {
                if (image !== null) {
                    var offset = getElementOffset(ctx.canvas),
                        pageX, pageY;
                    if (e.type === 'touchend') {
                        pageX = getChangedTouches(e)[0].pageX;
                        pageY = getChangedTouches(e)[0].pageY;
                    } else {
                        pageX = e.pageX;
                        pageY = e.pageY;
                    }
                    theArea.processMouseUp(pageX - offset.left, pageY - offset.top);
                    drawScene();
                }
            };

            this.getResultImageDataURI = function () {
                var temp_ctx, temp_canvas;
                temp_canvas = angular.element('<canvas></canvas>')[0];
                temp_ctx = temp_canvas.getContext('2d');
                temp_canvas.width = resImgSize;
                temp_canvas.height = resImgSize;
                if (image !== null) {
                    temp_ctx.drawImage(image, (theArea.getX() - theArea.getSize() / 2) * (image.width / ctx.canvas.width), (theArea.getY() - theArea.getSize() / 2) * (image.height / ctx.canvas.height), theArea.getSize() * (image.width / ctx.canvas.width), theArea.getSize() * (image.height / ctx.canvas.height), 0, 0, resImgSize, resImgSize);
                }
                if (resImgQuality !== null) {
                    return temp_canvas.toDataURL(resImgFormat, resImgQuality);
                }
                return temp_canvas.toDataURL(resImgFormat);
            };

            this.setNewImageSource = function (imageSource) {
                image = null;
                resetCropHost();
                events.trigger('image-updated');
                if (!!imageSource) {
                    var newImage = new Image();
                    if (imageSource.substring(0, 4).toLowerCase() === 'http') {
                        newImage.crossOrigin = 'anonymous';
                    }
                    newImage.onload = function () {

                        cropEXIF.getData(newImage, function () {
                            var orientation = cropEXIF.getTag(newImage, 'Orientation');

                            if ([3, 6, 8].indexOf(orientation) > -1) {
                                var canvas = document.createElement("canvas"),
                                ctx = canvas.getContext("2d"),
                                cw = newImage.width, ch = newImage.height, cx = 0, cy = 0, deg = 0;
                                var MAX_WIDTH = 400;
                                var MAX_HEIGHT = 300;

                                if (cw > ch) {
                                    if (cw > MAX_WIDTH) {
                                        ch *= MAX_WIDTH / cw;
                                        cw = MAX_WIDTH;
                                    }
                                } else {
                                    if (ch > MAX_HEIGHT) {
                                        cw *= MAX_HEIGHT / ch;
                                        ch = MAX_HEIGHT;
                                    }
                                }
                                switch (orientation) {
                                    case 3:
                                        cx = -newImage.width;
                                        cy = -newImage.height;
                                        deg = 180;
                                        break;
                                    case 6:
                                        cw = newImage.height;
                                        ch = newImage.width;
                                        cy = -newImage.height;
                                        deg = 90;
                                        break;
                                    case 8:
                                        cw = newImage.height;
                                        ch = newImage.width;
                                        cx = -newImage.width;
                                        deg = 270;
                                        break;
                                }

                                canvas.width = cw;
                                canvas.height = ch;
                                ctx.rotate(deg * Math.PI / 180);
                                ctx.drawImage(newImage, cx, cy);

                                image = new Image();
                                image.onload = function () {
                                    resetCropHost();
                                    events.trigger('image-updated');
                                };

                                image.src = canvas.toDataURL("image/png");
                                if (image.src == "") {
                                    alert(image.src);
                                    image = newImage;
                                    resetCropHost();
                                    events.trigger('image-updated');
                                }
                            } else {
                                image = newImage;
                                resetCropHost();
                                events.trigger('image-updated');
                            }
                        });
                        appScope.closetimer();
                        events.trigger('load-done');
                    };
                    newImage.onerror = function () {
                        appScope.errorloadingCroptool();
                        events.trigger('load-error');
                    };
                    events.trigger('load-start');
                    newImage.src = imageSource;
                }
            };

            this.setMaxDimensions = function (width, height) {
                maxCanvasDims = [width, height];

                if (image !== null) {
                    var curWidth = ctx.canvas.width,
                        curHeight = ctx.canvas.height;

                    var imageDims = [image.width, image.height],
                        imageRatio = image.width / image.height,
                        canvasDims = imageDims;

                    if (canvasDims[0] > maxCanvasDims[0]) {
                        canvasDims[0] = maxCanvasDims[0];
                        canvasDims[1] = canvasDims[0] / imageRatio;
                    } else if (canvasDims[0] < minCanvasDims[0]) {
                        canvasDims[0] = minCanvasDims[0];
                        canvasDims[1] = canvasDims[0] / imageRatio;
                    }
                    if (canvasDims[1] > maxCanvasDims[1]) {
                        canvasDims[1] = maxCanvasDims[1];
                        canvasDims[0] = canvasDims[1] * imageRatio;
                    } else if (canvasDims[1] < minCanvasDims[1]) {
                        canvasDims[1] = minCanvasDims[1];
                        canvasDims[0] = canvasDims[1] * imageRatio;
                    }
                    elCanvas.prop('width', canvasDims[0]).prop('height', canvasDims[1]).css({ 'margin-left': -canvasDims[0] / 2 + 'px', 'margin-top': -canvasDims[1] / 2 + 'px' });

                    var ratioNewCurWidth = ctx.canvas.width / curWidth,
                        ratioNewCurHeight = ctx.canvas.height / curHeight,
                        ratioMin = Math.min(ratioNewCurWidth, ratioNewCurHeight);

                    theArea.setX(theArea.getX() * ratioNewCurWidth);
                    theArea.setY(theArea.getY() * ratioNewCurHeight);
                    theArea.setSize(theArea.getSize() * ratioMin);
                } else {
                    elCanvas.prop('width', 0).prop('height', 0).css({ 'margin-top': 0 });
                }

                drawScene();

            };

            this.setAreaMinSize = function (size) {
                size = parseInt(size, 10);
                if (!isNaN(size)) {
                    theArea.setMinSize(size);
                    drawScene();
                }
            };

            this.setResultImageSize = function (size) {
                size = parseInt(size, 10);
                if (!isNaN(size)) {
                    resImgSize = size;
                }
            };

            this.setResultImageFormat = function (format) {
                resImgFormat = format;
            };

            this.setResultImageQuality = function (quality) {
                quality = parseFloat(quality);
                if (!isNaN(quality) && quality >= 0 && quality <= 1) {
                    resImgQuality = quality;
                }
            };

            this.setAreaType = function (type) {
                var curSize = theArea.getSize(),
                    curMinSize = theArea.getMinSize(),
                    curX = theArea.getX(),
                    curY = theArea.getY();

                var AreaClass = CropAreaCircle;
                if (type === 'square') {
                    AreaClass = CropAreaSquare;
                }
                theArea = new AreaClass(ctx, events);
                theArea.setMinSize(curMinSize);
                theArea.setSize(curSize);
                theArea.setX(curX);
                theArea.setY(curY);

                // resetCropHost();
                if (image !== null) {
                    theArea.setImage(image);
                }

                drawScene();
            };
            this.setPosition = function (position) {
                if (position.withoutSavingPosition) {
                    position.size = Math.min(200, ctx.canvas.width / 2, ctx.canvas.height / 2);
                    position.x = ctx.canvas.width / 2;
                    position.y = ctx.canvas.height / 2;
                }

                theArea.setX(position.x);
                theArea.setY(position.y);
                theArea.setSize(position.size);
            }
            /* Life Cycle begins */

            // Init Context var
            ctx = elCanvas[0].getContext('2d');

            // Init CropArea
            theArea = new CropAreaCircle(ctx, events);

            // Init Mouse Event Listeners
            $document.on('mousemove', onMouseMove);
            elCanvas.on('mousedown', onMouseDown);
            $document.on('mouseup', onMouseUp);

            // Init Touch Event Listeners
            $document.on('touchmove', onMouseMove);
            elCanvas.on('touchstart', onMouseDown);
            $document.on('touchend', onMouseUp);

            // CropHost Destructor
            this.destroy = function () {
                $document.off('mousemove', onMouseMove);
                elCanvas.off('mousedown', onMouseDown);
                $document.off('mouseup', onMouseMove);

                $document.off('touchmove', onMouseMove);
                elCanvas.off('touchstart', onMouseDown);
                $document.off('touchend', onMouseMove);

                elCanvas.remove();
            };
        };

    }]);


    crop.factory('cropPubSub', [function () {
        return function () {
            var events = {};
            // Subscribe
            this.on = function (names, handler) {
                names.split(' ').forEach(function (name) {
                    if (!events[name]) {
                        events[name] = [];
                    }
                    events[name].push(handler);
                });
                return this;
            };
            // Publish
            this.trigger = function (name, args) {
                angular.forEach(events[name], function (handler) {
                    handler.call(null, args);
                });
                return this;
            };
        };
    }]);

    crop.directive('imgCrop', ['$timeout', 'cropHost', 'cropPubSub', function ($timeout, CropHost, CropPubSub) {
        return {
            restrict: 'E',
            scope: {
                image: '=',
                resultImage: '=',

                changeOnFly: '=',
                areaType: '@',
                areaMinSize: '=',
                resultImageSize: '=',
                resultImageFormat: '@',
                resultImageQuality: '=',

                onChange: '&',
                onLoadBegin: '&',
                onLoadDone: '&',
                onLoadError: '&'
            },
            template: '<canvas></canvas>',
            controller: ['$scope', function ($scope) {
                $scope.events = new CropPubSub();
            }],
            link: function (scope, element/*, attrs*/) {
                // Init Events Manager
                var events = scope.events;

                // Init Crop Host
                var cropHost = new CropHost(element.find('canvas'), {}, events);

                // Store Result Image to check if it's changed
                var storedResultImage;

                var updateResultImage = function (scope) {
                    var resultImage = cropHost.getResultImageDataURI();
                    if (storedResultImage !== resultImage) {
                        storedResultImage = resultImage;
                        if (angular.isDefined(scope.resultImage)) {
                            scope.resultImage = resultImage;
                        }
                        scope.onChange({ $dataURI: scope.resultImage });
                    }
                };

                // Wrapper to safely exec functions within $apply on a running $digest cycle
                var fnSafeApply = function (fn) {
                    return function () {
                        $timeout(function () {
                            scope.$apply(function (scope) {
                                fn(scope);
                            });
                        });
                    };
                };

                // Setup CropHost Event Handlers
                events
                  .on('load-start', fnSafeApply(function (scope) {
                      scope.onLoadBegin({});
                  }))
                  .on('load-done', fnSafeApply(function (scope) {
                      scope.onLoadDone({});
                  }))
                  .on('load-error', fnSafeApply(function (scope) {
                      scope.onLoadError({});
                  }))
                  .on('area-move area-resize', fnSafeApply(function (scope) {
                      if (!!scope.changeOnFly) {
                          updateResultImage(scope);
                      }
                  }))
                  .on('area-move-end area-resize-end image-updated', fnSafeApply(function (scope) {
                      updateResultImage(scope);
                  }));

                // Sync CropHost with Directive's options
                scope.$watch('image', function () {
                    cropHost.setNewImageSource(scope.image);
                });
                scope.$watch('areaType', function () {
                    cropHost.setAreaType(scope.areaType);
                    updateResultImage(scope);
                });
                scope.$watch('areaMinSize', function () {
                    cropHost.setAreaMinSize(scope.areaMinSize);
                    updateResultImage(scope);
                });
                scope.$watch('resultImageSize', function () {
                    cropHost.setResultImageSize(scope.resultImageSize);
                    updateResultImage(scope);
                });
                scope.$watch('resultImageFormat', function () {
                    cropHost.setResultImageFormat(scope.resultImageFormat);
                    updateResultImage(scope);
                });
                scope.$watch('resultImageQuality', function () {
                    cropHost.setResultImageQuality(scope.resultImageQuality);
                    updateResultImage(scope);
                });
                appScope.$on('keyboardCropPosition', function (ev, data) {
                    console.log(data);
                    cropHost.setPosition(data);
                    updateResultImage(scope);
                });
                // Update CropHost dimensions when the directive element is resized
                scope.$watch(
                  function () {
                      return [element[0].clientWidth, element[0].clientHeight];
                  },
                  function (value) {
                      cropHost.setMaxDimensions(value[0], value[1]);
                      updateResultImage(scope);
                  },
                  true
                );

                // Destroy CropHost Instance when the directive is destroying
                scope.$on('$destroy', function () {
                    cropHost.destroy();
                });
            }
        };
    }]);
}());





!function (e) {
    "use strict";
    function t(e, i, a) {
        var o,
        n = document.createElement("img");
        return n.onerror = function (o) {
            return t.onerror(n, o, e, i, a)
        }
        ,
        n.onload = function (o) {
            return t.onload(n, o, e, i, a)
        }
        ,
        "string" == typeof e ? (t.fetchBlob(e, function (i) {
            i ? (e = i, o = t.createObjectURL(e)) : (o = e, a && a.crossOrigin && (n.crossOrigin = a.crossOrigin)), n.src = o
        }
        , a), n) : t.isInstanceOf("Blob", e) || t.isInstanceOf("File", e) ? (o = n._objectURL = t.createObjectURL(e)) ? (n.src = o, n) : t.readFile(e, function (e) {
            var t = e.target;
            t && t.result ? n.src = t.result : i && i(e)
        }
        ) : void 0
    }
    function i(e, i) {
        !e._objectURL || i && i.noRevoke || (t.revokeObjectURL(e._objectURL), delete e._objectURL)
    }
    var a = e.createObjectURL && e || e.URL && URL.revokeObjectURL && URL || e.webkitURL && webkitURL;
    t.fetchBlob = function (e, t, i) {
        t()
    }
    ,
    t.isInstanceOf = function (e, t) {
        return Object.prototype.toString.call(t) === "[object " + e + "]"
    }
    ,
    t.transform = function (e, t, i, a, o) {
        i(e, o)
    }
    ,
    t.onerror = function (e, t, a, o, n) {
        i(e, n),
        o && o.call(e, t)
    }
    ,
    t.onload = function (e, a, o, n, r) {
        i(e, r),
        n && t.transform(e, r, n, o, {}
        )
    }
    ,
    t.createObjectURL = function (e) {
        return !!a && a.createObjectURL(e)
    }
    ,
    t.revokeObjectURL = function (e) {
        return !!a && a.revokeObjectURL(e)
    }
    ,
    t.readFile = function (t, i, a) {
        if (e.FileReader) {
            var o = new FileReader;
            if (o.onload = o.onerror = i, a = a || "readAsDataURL", o[a]) return o[a](t),
            o
        }
        return !1
    }
    ,
    "function" == typeof define && define.amd ? define(function () {
        return t
    }
    ) : "object" == typeof module && module.exports ? module.exports = t : e.loadImage = t
}

("undefined" != typeof window && window || this),
function (e) {
    "use strict";
    "function" == typeof define && define.amd ? define(["./load-image"], e) : e("object" == typeof module && module.exports ? require("./load-image") : window.loadImage)
}

(function (e) {
    "use strict";
    var t = e.transform;
    e.transform = function (i, a, o, n, r) {
        t.call(e, e.scale(i, a, r), a, o, n, r)
    }
    , e.transformCoordinates = function () { }
    , e.getTransformedOptions = function (e, t) {
        var i, a, o, n, r = t.aspectRatio;
        if (!r) return t;
        i = {}
        ;
        for (a in t) t.hasOwnProperty(a) && (i[a] = t[a]);
        return i.crop = !0, o = e.naturalWidth || e.width, n = e.naturalHeight || e.height, o / n > r ? (i.maxWidth = n * r, i.maxHeight = n) : (i.maxWidth = o, i.maxHeight = o / r), i
    }
    , e.renderImageToCanvas = function (e, t, i, a, o, n, r, s, l, d) {
        return e.getContext("2d").drawImage(t, i, a, o, n, r, s, l, d), e
    }
    , e.hasCanvasOption = function (e) {
        return e.canvas || e.crop || !!e.aspectRatio
    }
    , e.scale = function (t, i, a) {
        function o() {
            var e = Math.max((l || v) / v, (d || P) / P);
            e > 1 && (v *= e, P *= e)
        }
        function n() {
            var e = Math.min((r || v) / v, (s || P) / P);
            e < 1 && (v *= e, P *= e)
        }
        i = i || {}
        ;
        var r, s, l, d, c, u, f, g, h, m, p, S = document.createElement("canvas"), b = t.getContext || e.hasCanvasOption(i) && S.getContext, y = t.naturalWidth || t.width, x = t.naturalHeight || t.height, v = y, P = x;
        if (b && (f = (i = e.getTransformedOptions(t, i, a)).left || 0, g = i.top || 0, i.sourceWidth ? (c = i.sourceWidth, void 0 !== i.right && void 0 === i.left && (f = y - c - i.right)) : c = y - f - (i.right || 0), i.sourceHeight ? (u = i.sourceHeight, void 0 !== i.bottom && void 0 === i.top && (g = x - u - i.bottom)) : u = x - g - (i.bottom || 0), v = c, P = u), r = i.maxWidth, s = i.maxHeight, l = i.minWidth, d = i.minHeight, b && r && s && i.crop ? (v = r, P = s, (p = c / u - r / s) < 0 ? (u = s * c / r, void 0 === i.top && void 0 === i.bottom && (g = (x - u) / 2)) : p > 0 && (c = r * u / s, void 0 === i.left && void 0 === i.right && (f = (y - c) / 2))) : ((i.contain || i.cover) && (l = r = r || l, d = s = s || d), i.cover ? (n(), o()) : (o(), n())), b) {
            if ((h = i.pixelRatio) > 1 && (S.style.width = v + "px", S.style.height = P + "px", v *= h, P *= h, S.getContext("2d").scale(h, h)), (m = i.downsamplingRatio) > 0 && m < 1 && v < c && P < u) for (;
            c * m > v;
            ) S.width = c * m, S.height = u * m, e.renderImageToCanvas(S, t, f, g, c, u, 0, 0, S.width, S.height), f = 0, g = 0, c = S.width, u = S.height, (t = document.createElement("canvas")).width = c, t.height = u, e.renderImageToCanvas(t, S, 0, 0, c, u, 0, 0, c, u);
            return S.width = v, S.height = P, e.transformCoordinates(S, i), e.renderImageToCanvas(S, t, f, g, c, u, 0, 0, v, P)
        }
        return t.width = v, t.height = P, t
    }
}

),
function (e) {
    "use strict";
    "function" == typeof define && define.amd ? define(["./load-image"], e) : e("object" == typeof module && module.exports ? require("./load-image") : window.loadImage)
}

(function (e) {
    "use strict";
    var t = "undefined" != typeof Blob && (Blob.prototype.slice || Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
    e.blobSlice = t && function () {
        return (this.slice || this.webkitSlice || this.mozSlice).apply(this, arguments)
    }
    , e.metaDataParsers = {
        jpeg: {
            65505: []
        }
    }
    , e.parseMetaData = function (t, i, a, o) {
        a = a || {}
        , o = o || {}
        ;
        var n = this, r = a.maxMetaDataSize || 262144;
        !!("undefined" != typeof DataView && t && t.size >= 12 && "image/jpeg" === t.type && e.blobSlice) && e.readFile(e.blobSlice.call(t, 0, r), function (t) {
            if (t.target.error) return console.log(t.target.error), void i(o);
            var r, s, l, d, c = t.target.result, u = new DataView(c), f = 2, g = u.byteLength - 4, h = f;
            if (65496 === u.getUint16(0)) {
                for (;
                f < g && ((r = u.getUint16(f)) >= 65504 && r <= 65519 || 65534 === r) ;
                ) {
                    if (s = u.getUint16(f + 2) + 2, f + s > u.byteLength) {
                        console.log("Invalid meta data: Invalid segment size.");
                        break
                    }
                    if (l = e.metaDataParsers.jpeg[r]) for (d = 0;
                    d < l.length;
                    d += 1) l[d].call(n, u, f, s, o, a);
                    h = f += s
                }
                !a.disableImageHead && h > 6 && (c.slice ? o.imageHead = c.slice(0, h) : o.imageHead = new Uint8Array(c).subarray(0, h))
            }
            else console.log("Invalid JPEG file: Missing JPEG marker.");
            i(o)
        }
        , "readAsArrayBuffer") || i(o)
    }
    , e.hasMetaOption = function (e) {
        return e && e.meta
    }
    ;
    var i = e.transform;
    e.transform = function (t, a, o, n, r) {
        e.hasMetaOption(a) ? e.parseMetaData(n, function (r) {
            i.call(e, t, a, o, n, r)
        }
        , a, r) : i.apply(e, arguments)
    }
}

),
function (e) {
    "use strict";
    "function" == typeof define && define.amd ? define(["./load-image", "./load-image-meta"], e) : "object" == typeof module && module.exports ? e(require("./load-image"), require("./load-image-meta")) : e(window.loadImage)
}

(function (e) {
    "use strict";
    "undefined" != typeof fetch && "undefined" != typeof Request && (e.fetchBlob = function (t, i, a) {
        if (e.hasMetaOption(a)) return fetch(new Request(t, a)).then(function (e) {
            return e.blob()
        }
        ).then(i).catch(function (e) {
            console.log(e), i()
        }
        );
        i()
    }
    )
}

),
function (e) {
    "use strict";
    "function" == typeof define && define.amd ? define(["./load-image", "./load-image-meta"], e) : "object" == typeof module && module.exports ? e(require("./load-image"), require("./load-image-meta")) : e(window.loadImage)
}

(function (e) {
    "use strict";
    e.ExifMap = function () {
        return this
    }
    , e.ExifMap.prototype.map = {
        Orientation: 274
    }
    , e.ExifMap.prototype.get = function (e) {
        return this[e] || this[this.map[e]]
    }
    , e.getExifThumbnail = function (e, t, i) {
        var a, o, n;
        {
            if (i && !(t + i > e.byteLength)) {
                for (a = [], o = 0;
                o < i;
                o += 1) n = e.getUint8(t + o), a.push((n < 16 ? "0" : "") + n.toString(16));
                return "data:image/jpeg,%" + a.join("%")
            }
            console.log("Invalid Exif data: Invalid thumbnail data.")
        }
    }
    , e.exifTagTypes = {
        1: {
            getValue: function (e, t) {
                return e.getUint8(t)
            }
            , size: 1
        }
        , 2: {
            getValue: function (e, t) {
                return String.fromCharCode(e.getUint8(t))
            }
            , size: 1, ascii: !0
        }
        , 3: {
            getValue: function (e, t, i) {
                return e.getUint16(t, i)
            }
            , size: 2
        }
        , 4: {
            getValue: function (e, t, i) {
                return e.getUint32(t, i)
            }
            , size: 4
        }
        , 5: {
            getValue: function (e, t, i) {
                return e.getUint32(t, i) / e.getUint32(t + 4, i)
            }
            , size: 8
        }
        , 9: {
            getValue: function (e, t, i) {
                return e.getInt32(t, i)
            }
            , size: 4
        }
        , 10: {
            getValue: function (e, t, i) {
                return e.getInt32(t, i) / e.getInt32(t + 4, i)
            }
            , size: 8
        }
    }
    , e.exifTagTypes[7] = e.exifTagTypes[1], e.getExifValue = function (t, i, a, o, n, r) {
        var s, l, d, c, u, f, g = e.exifTagTypes[o];
        if (g) {
            if (s = g.size * n, !((l = s > 4 ? i + t.getUint32(a + 8, r) : a + 8) + s > t.byteLength)) {
                if (1 === n) return g.getValue(t, l, r);
                for (d = [], c = 0;
                c < n;
                c += 1) d[c] = g.getValue(t, l + c * g.size, r);
                if (g.ascii) {
                    for (u = "", c = 0;
                    c < d.length && "\0" !== (f = d[c]) ;
                    c += 1) u += f;
                    return u
                }
                return d
            }
            console.log("Invalid Exif data: Invalid data offset.")
        }
        else console.log("Invalid Exif data: Invalid tag type.")
    }
    , e.parseExifTag = function (t, i, a, o, n) {
        var r = t.getUint16(a, o);
        n.exif[r] = e.getExifValue(t, i, a, t.getUint16(a + 2, o), t.getUint32(a + 4, o), o)
    }
    , e.parseExifTags = function (e, t, i, a, o) {
        var n, r, s;
        if (i + 6 > e.byteLength) console.log("Invalid Exif data: Invalid directory offset.");
        else {
            if (n = e.getUint16(i, a), !((r = i + 2 + 12 * n) + 4 > e.byteLength)) {
                for (s = 0;
                s < n;
                s += 1) this.parseExifTag(e, t, i + 2 + 12 * s, a, o);
                return e.getUint32(r, a)
            }
            console.log("Invalid Exif data: Invalid directory size.")
        }
    }
    , e.parseExifData = function (t, i, a, o, n) {
        if (!n.disableExif) {
            var r, s, l, d = i + 10;
            if (1165519206 === t.getUint32(i + 4)) if (d + 8 > t.byteLength) console.log("Invalid Exif data: Invalid segment size.");
            else if (0 === t.getUint16(i + 8)) {
                switch (t.getUint16(d)) {
                    case 18761: r = !0;
                        break;
                    case 19789: r = !1;
                        break;
                    default: return void console.log("Invalid Exif data: Invalid byte alignment marker.")
                }
                42 === t.getUint16(d + 2, r) ? (s = t.getUint32(d + 4, r), o.exif = new e.ExifMap, (s = e.parseExifTags(t, d, d + s, r, o)) && !n.disableExifThumbnail && (l = {
                    exif: {}
                }
                , s = e.parseExifTags(t, d, d + s, r, l), l.exif[513] && (o.exif.Thumbnail = e.getExifThumbnail(t, d + l.exif[513], l.exif[514]))), o.exif[34665] && !n.disableExifSub && e.parseExifTags(t, d, d + o.exif[34665], r, o), o.exif[34853] && !n.disableExifGps && e.parseExifTags(t, d, d + o.exif[34853], r, o)) : console.log("Invalid Exif data: Missing TIFF marker.")
            }
            else console.log("Invalid Exif data: Missing byte alignment offset.")
        }
    }
    , e.metaDataParsers.jpeg[65505].push(e.parseExifData)
}

),
function (e) {
    "use strict";
    "function" == typeof define && define.amd ? define(["./load-image", "./load-image-exif"], e) : "object" == typeof module && module.exports ? e(require("./load-image"), require("./load-image-exif")) : e(window.loadImage)
}

(function (e) {
    "use strict";
    e.ExifMap.prototype.tags = {
        256: "ImageWidth", 257: "ImageHeight", 34665: "ExifIFDPointer", 34853: "GPSInfoIFDPointer", 40965: "InteroperabilityIFDPointer", 258: "BitsPerSample", 259: "Compression", 262: "PhotometricInterpretation", 274: "Orientation", 277: "SamplesPerPixel", 284: "PlanarConfiguration", 530: "YCbCrSubSampling", 531: "YCbCrPositioning", 282: "XResolution", 283: "YResolution", 296: "ResolutionUnit", 273: "StripOffsets", 278: "RowsPerStrip", 279: "StripByteCounts", 513: "JPEGInterchangeFormat", 514: "JPEGInterchangeFormatLength", 301: "TransferFunction", 318: "WhitePoint", 319: "PrimaryChromaticities", 529: "YCbCrCoefficients", 532: "ReferenceBlackWhite", 306: "DateTime", 270: "ImageDescription", 271: "Make", 272: "Model", 305: "Software", 315: "Artist", 33432: "Copyright", 36864: "ExifVersion", 40960: "FlashpixVersion", 40961: "ColorSpace", 40962: "PixelXDimension", 40963: "PixelYDimension", 42240: "Gamma", 37121: "ComponentsConfiguration", 37122: "CompressedBitsPerPixel", 37500: "MakerNote", 37510: "UserComment", 40964: "RelatedSoundFile", 36867: "DateTimeOriginal", 36868: "DateTimeDigitized", 37520: "SubSecTime", 37521: "SubSecTimeOriginal", 37522: "SubSecTimeDigitized", 33434: "ExposureTime", 33437: "FNumber", 34850: "ExposureProgram", 34852: "SpectralSensitivity", 34855: "PhotographicSensitivity", 34856: "OECF", 34864: "SensitivityType", 34865: "StandardOutputSensitivity", 34866: "RecommendedExposureIndex", 34867: "ISOSpeed", 34868: "ISOSpeedLatitudeyyy", 34869: "ISOSpeedLatitudezzz", 37377: "ShutterSpeedValue", 37378: "ApertureValue", 37379: "BrightnessValue", 37380: "ExposureBias", 37381: "MaxApertureValue", 37382: "SubjectDistance", 37383: "MeteringMode", 37384: "LightSource", 37385: "Flash", 37396: "SubjectArea", 37386: "FocalLength", 41483: "FlashEnergy", 41484: "SpatialFrequencyResponse", 41486: "FocalPlaneXResolution", 41487: "FocalPlaneYResolution", 41488: "FocalPlaneResolutionUnit", 41492: "SubjectLocation", 41493: "ExposureIndex", 41495: "SensingMethod", 41728: "FileSource", 41729: "SceneType", 41730: "CFAPattern", 41985: "CustomRendered", 41986: "ExposureMode", 41987: "WhiteBalance", 41988: "DigitalZoomRatio", 41989: "FocalLengthIn35mmFilm", 41990: "SceneCaptureType", 41991: "GainControl", 41992: "Contrast", 41993: "Saturation", 41994: "Sharpness", 41995: "DeviceSettingDescription", 41996: "SubjectDistanceRange", 42016: "ImageUniqueID", 42032: "CameraOwnerName", 42033: "BodySerialNumber", 42034: "LensSpecification", 42035: "LensMake", 42036: "LensModel", 42037: "LensSerialNumber", 0: "GPSVersionID", 1: "GPSLatitudeRef", 2: "GPSLatitude", 3: "GPSLongitudeRef", 4: "GPSLongitude", 5: "GPSAltitudeRef", 6: "GPSAltitude", 7: "GPSTimeStamp", 8: "GPSSatellites", 9: "GPSStatus", 10: "GPSMeasureMode", 11: "GPSDOP", 12: "GPSSpeedRef", 13: "GPSSpeed", 14: "GPSTrackRef", 15: "GPSTrack", 16: "GPSImgDirectionRef", 17: "GPSImgDirection", 18: "GPSMapDatum", 19: "GPSDestLatitudeRef", 20: "GPSDestLatitude", 21: "GPSDestLongitudeRef", 22: "GPSDestLongitude", 23: "GPSDestBearingRef", 24: "GPSDestBearing", 25: "GPSDestDistanceRef", 26: "GPSDestDistance", 27: "GPSProcessingMethod", 28: "GPSAreaInformation", 29: "GPSDateStamp", 30: "GPSDifferential", 31: "GPSHPositioningError"
    }
    , e.ExifMap.prototype.stringValues = {
        ExposureProgram: {
            0: "Undefined", 1: "Manual", 2: "Normal program", 3: "Aperture priority", 4: "Shutter priority", 5: "Creative program", 6: "Action program", 7: "Portrait mode", 8: "Landscape mode"
        }
        , MeteringMode: {
            0: "Unknown", 1: "Average", 2: "CenterWeightedAverage", 3: "Spot", 4: "MultiSpot", 5: "Pattern", 6: "Partial", 255: "Other"
        }
        , LightSource: {
            0: "Unknown", 1: "Daylight", 2: "Fluorescent", 3: "Tungsten (incandescent light)", 4: "Flash", 9: "Fine weather", 10: "Cloudy weather", 11: "Shade", 12: "Daylight fluorescent (D 5700 - 7100K)", 13: "Day white fluorescent (N 4600 - 5400K)", 14: "Cool white fluorescent (W 3900 - 4500K)", 15: "White fluorescent (WW 3200 - 3700K)", 17: "Standard light A", 18: "Standard light B", 19: "Standard light C", 20: "D55", 21: "D65", 22: "D75", 23: "D50", 24: "ISO studio tungsten", 255: "Other"
        }
        , Flash: {
            0: "Flash did not fire", 1: "Flash fired", 5: "Strobe return light not detected", 7: "Strobe return light detected", 9: "Flash fired, compulsory flash mode", 13: "Flash fired, compulsory flash mode, return light not detected", 15: "Flash fired, compulsory flash mode, return light detected", 16: "Flash did not fire, compulsory flash mode", 24: "Flash did not fire, auto mode", 25: "Flash fired, auto mode", 29: "Flash fired, auto mode, return light not detected", 31: "Flash fired, auto mode, return light detected", 32: "No flash function", 65: "Flash fired, red-eye reduction mode", 69: "Flash fired, red-eye reduction mode, return light not detected", 71: "Flash fired, red-eye reduction mode, return light detected", 73: "Flash fired, compulsory flash mode, red-eye reduction mode", 77: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected", 79: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected", 89: "Flash fired, auto mode, red-eye reduction mode", 93: "Flash fired, auto mode, return light not detected, red-eye reduction mode", 95: "Flash fired, auto mode, return light detected, red-eye reduction mode"
        }
        , SensingMethod: {
            1: "Undefined", 2: "One-chip color area sensor", 3: "Two-chip color area sensor", 4: "Three-chip color area sensor", 5: "Color sequential area sensor", 7: "Trilinear sensor", 8: "Color sequential linear sensor"
        }
        , SceneCaptureType: {
            0: "Standard", 1: "Landscape", 2: "Portrait", 3: "Night scene"
        }
        , SceneType: {
            1: "Directly photographed"
        }
        , CustomRendered: {
            0: "Normal process", 1: "Custom process"
        }
        , WhiteBalance: {
            0: "Auto white balance", 1: "Manual white balance"
        }
        , GainControl: {
            0: "None", 1: "Low gain up", 2: "High gain up", 3: "Low gain down", 4: "High gain down"
        }
        , Contrast: {
            0: "Normal", 1: "Soft", 2: "Hard"
        }
        , Saturation: {
            0: "Normal", 1: "Low saturation", 2: "High saturation"
        }
        , Sharpness: {
            0: "Normal", 1: "Soft", 2: "Hard"
        }
        , SubjectDistanceRange: {
            0: "Unknown", 1: "Macro", 2: "Close view", 3: "Distant view"
        }
        , FileSource: {
            3: "DSC"
        }
        , ComponentsConfiguration: {
            0: "", 1: "Y", 2: "Cb", 3: "Cr", 4: "R", 5: "G", 6: "B"
        }
        , Orientation: {
            1: "top-left", 2: "top-right", 3: "bottom-right", 4: "bottom-left", 5: "left-top", 6: "right-top", 7: "right-bottom", 8: "left-bottom"
        }
    }
    , e.ExifMap.prototype.getText = function (e) {
        var t = this.get(e);
        switch (e) {
            case "LightSource": case "Flash": case "MeteringMode": case "ExposureProgram": case "SensingMethod": case "SceneCaptureType": case "SceneType": case "CustomRendered": case "WhiteBalance": case "GainControl": case "Contrast": case "Saturation": case "Sharpness": case "SubjectDistanceRange": case "FileSource": case "Orientation": return this.stringValues[e][t];
            case "ExifVersion": case "FlashpixVersion": if (!t) return;
                return String.fromCharCode(t[0], t[1], t[2], t[3]);
            case "ComponentsConfiguration": if (!t) return;
                return this.stringValues[e][t[0]] + this.stringValues[e][t[1]] + this.stringValues[e][t[2]] + this.stringValues[e][t[3]];
            case "GPSVersionID": if (!t) return;
                return t[0] + "." + t[1] + "." + t[2] + "." + t[3]
        }
        return String(t)
    }
    , function (e) {
        var t, i = e.tags, a = e.map;
        for (t in i) i.hasOwnProperty(t) && (a[i[t]] = t)
    }
    (e.ExifMap.prototype), e.ExifMap.prototype.getAll = function () {
        var e, t, i = {}
        ;
        for (e in this) this.hasOwnProperty(e) && (t = this.tags[e]) && (i[t] = this.getText(t));
        return i
    }
}

),
function (e) {
    "use strict";
    "function" == typeof define && define.amd ? define(["./load-image", "./load-image-scale", "./load-image-meta"], e) : "object" == typeof module && module.exports ? e(require("./load-image"), require("./load-image-scale"), require("./load-image-meta")) : e(window.loadImage)
}

(function (e) {
    "use strict";
    var t = e.hasCanvasOption, i = e.hasMetaOption, a = e.transformCoordinates, o = e.getTransformedOptions;
    e.hasCanvasOption = function (i) {
        return !!i.orientation || t.call(e, i)
    }
    , e.hasMetaOption = function (t) {
        return t && !0 === t.orientation || i.call(e, t)
    }
    , e.transformCoordinates = function (t, i) {
        a.call(e, t, i);
        var o = t.getContext("2d"), n = t.width, r = t.height, s = t.style.width, l = t.style.height, d = i.orientation;
        if (d && !(d > 8)) switch (d > 4 && (t.width = r, t.height = n, t.style.width = l, t.style.height = s), d) {
            case 2: o.translate(n, 0), o.scale(-1, 1);
                break;
            case 3: o.translate(n, r), o.rotate(Math.PI);
                break;
            case 4: o.translate(0, r), o.scale(1, -1);
                break;
            case 5: o.rotate(.5 * Math.PI), o.scale(1, -1);
                break;
            case 6: o.rotate(.5 * Math.PI), o.translate(0, -r);
                break;
            case 7: o.rotate(.5 * Math.PI), o.translate(n, -r), o.scale(-1, 1);
                break;
            case 8: o.rotate(-.5 * Math.PI), o.translate(-n, 0)
        }
    }
    , e.getTransformedOptions = function (t, i, a) {
        var n, r, s = o.call(e, t, i), l = s.orientation;
        if (!0 === l && a && a.exif && (l = a.exif.get("Orientation")), !l || l > 8 || 1 === l) return s;
        n = {}
        ;
        for (r in s) s.hasOwnProperty(r) && (n[r] = s[r]);
        switch (n.orientation = l, l) {
            case 2: n.left = s.right, n.right = s.left;
                break;
            case 3: n.left = s.right, n.top = s.bottom, n.right = s.left, n.bottom = s.top;
                break;
            case 4: n.top = s.bottom, n.bottom = s.top;
                break;
            case 5: n.left = s.top, n.top = s.left, n.right = s.bottom, n.bottom = s.right;
                break;
            case 6: n.left = s.top, n.top = s.right, n.right = s.bottom, n.bottom = s.left;
                break;
            case 7: n.left = s.bottom, n.top = s.right, n.right = s.top, n.bottom = s.left;
                break;
            case 8: n.left = s.bottom, n.top = s.left, n.right = s.top, n.bottom = s.right
        }
        return n.orientation > 4 && (n.maxWidth = s.maxHeight, n.maxHeight = s.maxWidth, n.minWidth = s.minHeight, n.minHeight = s.minWidth, n.sourceWidth = s.sourceHeight, n.sourceHeight = s.sourceWidth), n
    }
}

);
//# sourceMappingURL=load-image.all.min.js.map


;
/*_/^\_I_/^\_N_/^\_F_/^\_I_/^\_N_/^\_I_/^\_T_/^\_E_/^\_

 (c) Copyright Infinite Talent 2021  

`\V/'I`\V/'N`\V/'F`\V/'I`\V/'N`\V/'I`\V/'T`\V/'E`\V/'*/




/*! ng-dialog - v0.3.12 (https://github.com/likeastore/ngDialog) */
!function(a,b){"undefined"!=typeof module&&module.exports?module.exports=b(require("angular")):"function"==typeof define&&define.amd?define(["angular"],b):b(a.angular)}(this,function(a){"use strict";var b,c=a.module("ngDialog",[]),d=a.element,e=a.isDefined,f=(document.body||document.documentElement).style,g=e(f.animation)||e(f.WebkitAnimation)||e(f.MozAnimation)||e(f.MsAnimation)||e(f.OAnimation),h="animationend webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend",i=!1;return c.provider("ngDialog",function(){var c=this.defaults={className:"ngdialog-theme-default",plain:!1,showClose:!0,closeByDocument:!0,closeByEscape:!0,closeByNavigation:!1,appendTo:!1,preCloseCallback:!1,overlay:!0,cache:!0};this.setForceBodyReload=function(a){i=a||!1},this.setDefaults=function(b){a.extend(c,b)};var e,f=0,j=0,k={};this.$get=["$document","$templateCache","$compile","$q","$http","$rootScope","$timeout","$window","$controller",function(l,m,n,o,p,q,r,s,t){var u=l.find("body");i&&q.$on("$locationChangeSuccess",function(){u=l.find("body")});var v={onDocumentKeydown:function(a){27===a.keyCode&&w.close("$escape")},setBodyPadding:function(a){var b=parseInt(u.css("padding-right")||0,10);u.css("padding-right",b+a+"px"),u.data("ng-dialog-original-padding",b)},resetBodyPadding:function(){var a=u.data("ng-dialog-original-padding");a?u.css("padding-right",a+"px"):u.css("padding-right","")},performCloseDialog:function(a,c){var d=a.attr("id");if("undefined"!=typeof s.Hammer){var f=b.hammerTime;f.off("tap",e),f.destroy&&f.destroy(),delete b.hammerTime}else a.unbind("click");1===j&&u.unbind("keydown"),a.hasClass("ngdialog-closing")||(j-=1),q.$broadcast("ngDialog.closing",a),j=0>j?0:j,g?(b.$destroy(),a.unbind(h).bind(h,function(){a.remove(),0===j&&(u.removeClass("ngdialog-open"),v.resetBodyPadding()),q.$broadcast("ngDialog.closed",a)}).addClass("ngdialog-closing")):(b.$destroy(),a.remove(),0===j&&(u.removeClass("ngdialog-open"),v.resetBodyPadding()),q.$broadcast("ngDialog.closed",a)),k[d]&&(k[d].resolve({id:d,value:c,$dialog:a,remainingDialogs:j}),delete k[d])},closeDialog:function(b,c){var d=b.data("$ngDialogPreCloseCallback");if(d&&a.isFunction(d)){var e=d.call(b,c);a.isObject(e)?e.closePromise?e.closePromise.then(function(){v.performCloseDialog(b,c)}):e.then(function(){v.performCloseDialog(b,c)},function(){}):e!==!1&&v.performCloseDialog(b,c)}else v.performCloseDialog(b,c)}},w={open:function(g){function h(a,b){return p.get(a,b||{}).then(function(a){return a.data||""})}function i(b){return b?a.isString(b)&&x.plain?b:"boolean"!=typeof x.cache||x.cache?m.get(b)||h(b,{cache:!0}):h(b,{cache:!1}):"Empty template"}var l=this,x=a.copy(c);g=g||{},a.extend(x,g),f+=1,l.latestID="ngdialog"+f;var y;k[l.latestID]=y=o.defer(),b=a.isObject(x.scope)?x.scope.$new():q.$new();var z,A;return o.when(i(x.template||x.templateUrl)).then(function(c){if(m.put(x.template||x.templateUrl,c),x.showClose&&(c+='<div class="ngdialog-close"></div>'),l.$result=z=d('<div id="ngdialog'+f+'" class="ngdialog"></div>'),z.html(x.overlay?'<div class="ngdialog-overlay"></div><div class="ngdialog-content">'+c+"</div>":'<div class="ngdialog-content">'+c+"</div>"),x.data&&a.isString(x.data)){var g=x.data.replace(/^\s*/,"")[0];b.ngDialogData="{"===g||"["===g?a.fromJson(x.data):x.data}else x.data&&a.isObject(x.data)&&(b.ngDialogData=x.data);if(x.controller&&(a.isString(x.controller)||a.isArray(x.controller)||a.isFunction(x.controller))){var h=t(x.controller,{$scope:b,$element:z});z.data("$ngDialogControllerController",h)}if(x.className&&z.addClass(x.className),A=x.appendTo&&a.isString(x.appendTo)?a.element(document.querySelector(x.appendTo)):u,x.preCloseCallback){var i;a.isFunction(x.preCloseCallback)?i=x.preCloseCallback:a.isString(x.preCloseCallback)&&b&&(a.isFunction(b[x.preCloseCallback])?i=b[x.preCloseCallback]:b.$parent&&a.isFunction(b.$parent[x.preCloseCallback])?i=b.$parent[x.preCloseCallback]:q&&a.isFunction(q[x.preCloseCallback])&&(i=q[x.preCloseCallback])),i&&z.data("$ngDialogPreCloseCallback",i)}if(b.closeThisDialog=function(a){v.closeDialog(z,a)},r(function(){n(z)(b);var a=s.innerWidth-u.prop("clientWidth");u.addClass("ngdialog-open");var c=a-(s.innerWidth-u.prop("clientWidth"));c>0&&v.setBodyPadding(c),A.append(z),x.name?q.$broadcast("ngDialog.opened",{dialog:z,name:x.name}):q.$broadcast("ngDialog.opened",z)}),x.closeByEscape&&u.bind("keydown",v.onDocumentKeydown),x.closeByNavigation&&q.$on("$locationChangeSuccess",function(){v.closeDialog(z)}),e=function(a){var b=x.closeByDocument?d(a.target).hasClass("ngdialog-overlay"):!1,c=d(a.target).hasClass("ngdialog-close");(b||c)&&w.close(z.attr("id"),c?"$closeButton":"$document")},"undefined"!=typeof s.Hammer){var k=b.hammerTime=s.Hammer(z[0]);k.on("tap",e)}else z.bind("click",e);return j+=1,w}),{id:"ngdialog"+f,closePromise:y.promise,close:function(a){v.closeDialog(z,a)}}},openConfirm:function(b){var c=o.defer(),e={closeByEscape:!1,closeByDocument:!1};a.extend(e,b),e.scope=a.isObject(e.scope)?e.scope.$new():q.$new(),e.scope.confirm=function(a){c.resolve(a);var b=d(document.getElementById(f.id));v.performCloseDialog(b,a)};var f=w.open(e);return f.closePromise.then(function(a){return a?c.reject(a.value):c.reject()}),c.promise},close:function(a,b){var c=d(document.getElementById(a));return c.length?v.closeDialog(c,b):w.closeAll(b),w},closeAll:function(b){var c=document.querySelectorAll(".ngdialog");a.forEach(c,function(a){v.closeDialog(d(a),b)})},getDefaults:function(){return c}};return w}]}),c.directive("ngDialog",["ngDialog",function(b){return{restrict:"A",scope:{ngDialogScope:"="},link:function(c,d,e){d.on("click",function(d){d.preventDefault();var f=a.isDefined(c.ngDialogScope)?c.ngDialogScope:"noScope";a.isDefined(e.ngDialogClosePrevious)&&b.close(e.ngDialogClosePrevious);var g=b.getDefaults();b.open({template:e.ngDialog,className:e.ngDialogClass||g.className,controller:e.ngDialogController,scope:f,data:e.ngDialogData,showClose:"false"===e.ngDialogShowClose?!1:"true"===e.ngDialogShowClose?!0:g.showClose,closeByDocument:"false"===e.ngDialogCloseByDocument?!1:"true"===e.ngDialogCloseByDocument?!0:g.closeByDocument,closeByEscape:"false"===e.ngDialogCloseByEscape?!1:"true"===e.ngDialogCloseByEscape?!0:g.closeByEscape,preCloseCallback:e.ngDialogPreCloseCallback||g.preCloseCallback})})}}}]),c});




;
(function( $, undefined ) {
  $.extend($.datepicker, {
    _generateDaysHTML: $.datepicker._generateHTML,
    _generateMonthsHTML: function(inst) {
      inst.dpDiv.addClass('ui-monthpicker');
      var maxDraw, prevText, prev, nextText, next,
			controls, buttonPanel, showWeek, dayNames, dayNamesMin,
			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
			selectOtherMonths, defaultDate, html, group, col, selectedDate,
			cornerClass, calender, day, daysInMonth,
			printDate, otherMonth, unselectable,
			tempDate = new Date(),
			today = this._daylightSavingAdjust(
				new Date(tempDate.getFullYear(), tempDate.getMonth(), 1)), // clear time
			isRTL = this._get(inst, "isRTL"),
			showButtonPanel = this._get(inst, "showButtonPanel"),
			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
			numMonths = this._getNumberOfMonths(inst),
			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
			stepMonths = this._get(inst, "stepMonths"),
			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
				new Date(inst.currentYear, inst.currentMonth, 1))),
			minDate = this._getMinMaxDate(inst, "min"),
			maxDate = this._getMinMaxDate(inst, "max"),
			drawMonth = inst.drawMonth - showCurrentAtPos,
			drawYear = inst.drawYear;

		if (drawMonth < 0) {
			drawMonth += 12;
			drawYear--;
		}
		if (maxDate) {
			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
				drawMonth--;
				if (drawMonth < 0) {
					drawMonth = 11;
					drawYear--;
				}
			}
		}
		inst.drawMonth = drawMonth;
		inst.drawYear = drawYear;

		prevText = this._get(inst, "prevText");
		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
			this._getFormatConfig(inst)));

		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
			"<a class='ui-datepicker-prev ui-corner-all pmonth' data-handler='prev' data-event='click' href='#0'" +
			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + (isRTL ? "e" : "w") + "' style='display: none;'>" + prevText + "</span></a>" :
			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled pmonth' title='" + prevText + "' href='#0'><span class='ui-icon ui-icon-circle-triangle-" + (isRTL ? "e" : "w") + "' style='display: none;'>" + prevText + "</span></a>"));

		nextText = this._get(inst, "nextText");
		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
			this._getFormatConfig(inst)));

		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
			"<a class='ui-datepicker-next ui-corner-all nmonth' data-handler='next' data-event='click' href='#0'" +
			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + (isRTL ? "w" : "e") + "' style='display: none;'>" + nextText + "</span></a>" :
			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled nmonth' href='#0' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + (isRTL ? "w" : "e") + "' style='display: none;'>" + nextText + "</span></a>"));		controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
			this._get(inst, "closeText") + "</button>" : "");

		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + controls + "</div>" : "";

		showWeek = this._get(inst, "showWeek");
		dayNames = this._get(inst, "dayNames");
		dayNamesMin = this._get(inst, "dayNamesMin");
		monthNames = this._get(inst, "monthNames");
		monthNamesShort = this._get(inst, "monthNamesShort");
		beforeShowDay = this._get(inst, "beforeShowDay");
		showOtherMonths = this._get(inst, "showOtherMonths");
		selectOtherMonths = this._get(inst, "selectOtherMonths");
		defaultDate = this._getDefaultDate(inst);
		html = "";
		for (row = 0; row < numMonths[0]; row++) {
			group = "";
			this.maxRows = 4;
			for (col = 0; col < numMonths[1]; col++) {
				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
				cornerClass = " ui-corner-all";
				calender = "";
				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
						row > 0 || col > 0, monthNames, monthNamesShort) 
						.replace("class='ui-datepicker-title'", "class='ui-datepicker-title' aria-level='2'") +
					"</div><table class='ui-datepicker-calendar'>";
				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
				}
				numRows = 4;
				this.maxRows = numRows;
				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1));
        calender += '<tr>';
        for (mRow = 0; mRow < 4; mRow++) {
          calender += '<tr>';
          for (mData = 0; mData < 3; mData++) {
            var month = mRow*3 + mData;
            printDate = this._daylightSavingAdjust(new Date(drawYear, month, 1));
			calender += "<td class='" +
				(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
				(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "") + "'" + // highlight today (if different)
				" data-handler='selectDay' data-event='click' data-month='" + month + "' data-year='" + printDate.getFullYear() + "' role='presentation'>" +
				"<div role='button' tabindex='0' aria-label='" + monthNames[month] + " " + printDate.getFullYear() + "'" +
				" class='ui-state-default" +
				(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
				(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") +
				"'>" + monthNamesShort[month] + "</div><a href='#' data-date='1' style='display: none;'>1</a></td>";
			}
          calender += '</tr>';
        }
				calender += "</tbody></table>";
				group += calender;
			}
			html += group;
		}
		html += buttonPanel;
		inst._keyEvent = false;
		return html;

	  },
	  _generateMonthYearHeader: function (inst, drawMonth, drawYear, minDate, maxDate, secondary, monthNames, monthNamesShort) {
		  var startYear = minDate ? minDate.getFullYear() : drawYear - 10;
		  var endYear = maxDate ? maxDate.getFullYear() : drawYear + 10;
		  var yearsHtml = "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change' onkeydown='event.stopPropagation();' >";
		  for (var year = startYear; year <= endYear; year++) {
			  yearsHtml += "<option value='" + year + "'" + (year === drawYear ? " selected" : "") + ">" + year + "</option>";
		  }
		  yearsHtml += "</select>";
		  var monthText = "<span class='ui-datepicker-month-text'>" + monthNames[drawMonth] + "</span>";
		  return "<div class='ui-datepicker-title'>" + monthText + " " + yearsHtml + "</div>";
	  },
    _generateHTML: function(inst) {
      if ( inst.settings.monthPicker ) {
        return this._generateMonthsHTML(inst);
      } else {
        return this._generateDaysHTML(inst);
      }
    }
  });
  $.fn.monthpicker = function(options) {
    return this.each(function() {
      var $this = $(this);
      var altField = $this.next();
      altField.on('focus', function() { $this.datepicker('show') });
      var settings = {
        monthPicker: true,
        stepMonths: 12,
        changeMonth: false,
        altField: altField,
		altFormat: 'M yy',
		  buttonText: appScope.dynamicStrings ? appScope.dynamicStrings.AriaLabel_CalButton : "Choose date from calendar"
		  
	  }
      $.extend(settings, options);
      $this.datepicker(settings);
    });
  }
}) (jQuery);
;
