\n
\n
\n
\n
\n \n \n {{\'EDIT_PROPERTIES\' | translate}} :\n \n \n
\n
\n
\n
\n \n {{\'ADD_NEW_OPTIONS\' | translate}} :\n \n
\n
\n
\n
\n
\n \n {{\'ADD_NEW_GROUPS\' | translate}} :\n \n
\n
\n
\n
\n
\n \n {{\'EDIT_GROUPS_OPTIONS\' | translate}} :\n \n
\n
\n
\n
\n
\n
\n
\n
\n',d.define=e,c.exports}),a.register("24",["15","16","23"],function(a){var b,c,d,e,f;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a["default"]}],execute:function(){"use strict";e="editGroupedSelectControl",a("EDIT_GROUPED_SELECT_COMPONENT",e),f={template:d,bindings:{nyaSelect:"=",groupedSelectRowCollection:"=",newOptionGroupedSelect:"=",newGroupGroupedSelect:"=",groupSelectGroupClick:"=",GroupedSelectGroups:"=",addNewOptionGroupedSelect:"&",addNewGroupToGroupedSelect:"&",upThisGroupedSelectRow:"&",downThisGroupedSelectRow:"&",showGroupListToChoose:"&",removeGroupedSelectRow:"&"},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editGroupedSelectControlComponent",f)}}}),a.registerDynamic("25",[],!0,function(a,b,c){var d=this,e=d.define;return d.define=void 0,c.exports='
\n
\n
\n
\n
\n \n {{\'PREVIEW_TAB\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n {{\'EDIT_PROPERTIES\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n',d.define=e,c.exports}),a.register("26",["15","16","25"],function(a){var b,c,d,e,f;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a["default"]}],execute:function(){"use strict";e="editHeaderControl",a("EDIT_HEADER_CONTROL_COMPONENT",e),f={template:d,bindings:{nyaSelect:"="},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editHeaderControlComponent",f)}}}),a.registerDynamic("27",[],!0,function(a,b,c){var d=this,e=d.define;return d.define=void 0,c.exports='
\n
\n
\n
\n
\n \n \n {{\'PREVIEW_TAB\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n {{\'EDIT_PROPERTIES\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n',d.define=e,c.exports}),a.register("28",["15","16","27"],function(a){var b,c,d,e,f;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a["default"]}],execute:function(){"use strict";e="editPasswordControl",a("EDIT_PASSWORD_CONTROL_COMPONENT",e),f={template:d,bindings:{nyaSelect:"="},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editPasswordControlComponent",f)}}}),a.registerDynamic("29",[],!0,function(a,b,c){var d=this,e=d.define;return d.define=void 0,c.exports='
\n
\n
\n
\n
\n \n \n {{\'PREVIEW_TAB\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n {{\'EDIT_PROPERTIES\' | translate}} :\n \n \n
\n
\n
\n
\n \n {{\'ADD_NEW_RADIO\' | translate}} :\n \n
\n
\n
\n
\n
\n \n {{\'EDIT_REMOVE_RADIO\' | translate}} :\n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n',
+d.define=e,c.exports}),a.register("2a",["15","16","29"],function(a){var b,c,d,e,f;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a["default"]}],execute:function(){"use strict";e="editRadioControl",a("EDIT_RADIO_CONTROL_COMPONENT",e),f={template:d,bindings:{nyaSelect:"=",radioRowCollection:"=",newOptionRadio:"=",addNewOptionRadio:"&",upThisRadioRow:"&",downThisRadioRow:"&",removeRadioRow:"&"},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editRadioControlComponent",f)}}}),a.registerDynamic("2b",[],!0,function(a,b,c){var d=this,e=d.define;return d.define=void 0,c.exports='
\n
\n
\n
\n
\n \n \n {{\'PREVIEW_TAB\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n {{\'EDIT_PROPERTIES\' | translate}} :\n \n \n
\n
\n\n\n
\n
\n
\n',d.define=e,c.exports}),a.register("2c",["15","16","2b"],function(a){var b,c,d,e,f;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a["default"]}],execute:function(){"use strict";e="editRichTextEditorControl",a("EDIT_RICH_TEXT_EDITOR_COMPONENT",e),f={template:d,bindings:{nyaSelect:"="},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editRichTextEditorControlComponent",f)}}}),a.registerDynamic("2d",[],!0,function(a,b,c){var d=this,e=d.define;return d.define=void 0,c.exports='
\n
\n
\n
\n
\n \n \n {{\'PREVIEW_TAB\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n {{\'EDIT_PROPERTIES\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n',d.define=e,c.exports}),a.register("2e",["15","16","2d"],function(a){var b,c,d,e,f;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a["default"]}],execute:function(){"use strict";e="editSubTitleControl",a("EDIT_SUBTITLE_CONTROL_COMPONENT",e),f={template:d,bindings:{nyaSelect:"="},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editSubTitleControlComponent",f)}}}),a.registerDynamic("2f",[],!0,function(a,b,c){var d=this,e=d.define;return d.define=void 0,c.exports='
\n
\n
\n
\n
\n \n \n {{\'PREVIEW_TAB\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n {{\'EDIT_PROPERTIES\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n',d.define=e,c.exports}),a.register("30",["15","16","2f"],function(a){var b,c,d,e,f;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a["default"]}],execute:function(){"use strict";e="editTextareaControl",a("EDIT_TEXTAREA_CONTROL_COMPONENT",e),f={template:d,bindings:{nyaSelect:"="},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editTextareaControlComponent",f)}}}),a.registerDynamic("31",[],!0,function(a,b,c){var d=this,e=d.define;return d.define=void 0,c.exports='
\n
\n
\n
\n
\n \n \n {{\'PREVIEW_TAB\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n \n \n {{\'EDIT_PROPERTIES\' | translate}} :\n \n \n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n',d.define=e,c.exports}),a.register("32",["15","16","31"],function(a){var b,c,d,e,f;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a["default"]}],execute:function(){"use strict";e="editTextInputControl",a("EDIT_TEXTINPUT_CONTROL_COMPONENT",e),f={template:d,bindings:{nyaSelect:"="},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editTextInputControlComponent",f)}}}),a.register("33",["15","16"],function(a){var b,c,d,e;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]}],execute:function(){"use strict";d="editValidEditFooter",a("EDIT_EDIT_VALID_FOOTER_COMPONENT",d),e={template:'\n \n ',bindings:{nyaSelect:"=",ok:"&",cancel:"&"},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editValidEditFooterComponent",e)}}}),a.register("34",["15","16"],function(a){var b,c,d,e;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]}],execute:function(){"use strict";d="editChooseControl",a("EDIT_CHOOSE_CONTROL_COMPONENT",d),e={template:'\n
\n \n \n \n \n {{ option.name }}\n \n \n \n \n \n ',bindings:{modelNyaSelect:"=",nyaSelectFiltered:"=",selectThisControl:"&"},controller:function(){function a(){c(this,a)}return b(a,null,[{key:"$inject",get:function(){return[]}}]),a}()},a("editChooseControlComponent",e)}}}),a.register("35",["14","20","22","24","26","28","30","32","33","34","1a","1c","1e","2a","2c","2e"],function(a){"use strict";var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H;return{setters:[function(a){b=a["default"],c=a.EDIT_MODAL_CONTROLLER_NAME},function(a){d=a.editDateControlComponent,e=a.EDIT_DATE_COMPONENT},function(a){f=a.editEmailControlComponent,g=a.EDIT_EMAIL_COMPONENT},function(a){h=a.editGroupedSelectControlComponent,i=a.EDIT_GROUPED_SELECT_COMPONENT},function(a){j=a.editHeaderControlComponent,k=a.EDIT_HEADER_CONTROL_COMPONENT},function(a){l=a.editPasswordControlComponent,m=a.EDIT_PASSWORD_CONTROL_COMPONENT},function(a){n=a.editTextareaControlComponent,o=a.EDIT_TEXTAREA_CONTROL_COMPONENT},function(a){p=a.editTextInputControlComponent,q=a.EDIT_TEXTINPUT_CONTROL_COMPONENT},function(a){r=a.editValidEditFooterComponent,s=a.EDIT_EDIT_VALID_FOOTER_COMPONENT},function(a){t=a.editChooseControlComponent,u=a.EDIT_CHOOSE_CONTROL_COMPONENT},function(a){v=a.editBlankControlComponent,w=a.EDIT_BLANK_CONTROL_COMPONENT},function(a){x=a.editBasicSelectControlComponent,y=a.EDIT_BASIC_SELECT_COMPONENT},function(a){z=a.editCheckBoxControlComponent,A=a.EDIT_CHECKBOX_COMPONENT},function(a){B=a.editRadioControlComponent,C=a.EDIT_RADIO_CONTROL_COMPONENT},function(a){D=a.editRichTextEditorControlComponent,E=a.EDIT_RICH_TEXT_EDITOR_COMPONENT},function(a){F=a.editSubTitleControlComponent,G=a.EDIT_SUBTITLE_CONTROL_COMPONENT}],execute:function(){H="editControlModal.module",a("default",angular.module(H,[]).controller(c,b).component(w,v).component(y,x).component(A,z).component(e,d).component(g,f).component(i,h).component(k,j).component(m,l).component(C,B).component(E,D).component(G,F).component(o,n).component(q,p).component(s,r).component(u,t))}}}),a.register("36",[],function(a){"use strict";var b,c,d,e;return{setters:[],execute:function(){b=function(a){var b={controls:[{id:"empty",name:"no control",subtitle:"no control",group:"Blank",formlyType:"blank",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{}},{id:"Header",name:"Header",subtitle:"no control",group:"Decoration",formlyType:"header",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{}},{id:"Subtitle",name:"Subtitle",subtitle:"no control",group:"Decoration",formlyType:"subTitle",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{}},{id:"TextInput",name:"Text input",subtitle:"Text input",group:"input",formlyType:"input",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{messages:{required:function(a,b,c){var d="this Text input field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return e}}}},{id:"Password",name:"Password",subtitle:"Password",group:"input",formlyType:"input",formlySubtype:"password",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{messages:{required:function(a,b,c){var d="this Password field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return e}}}},{id:"Email",name:"Email",subtitle:"Email",group:"input",formlyType:"input",formlySubtype:"email",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{emailShape:{expression:function(a,b){var c=b||a;return/^[a-z]+[a-z0-9._]+@[a-z]+\.[a-z.]{2,5}$/.test(c)},message:"$viewValue + ' is not a valid email'"}},formlyValidation:{messages:{required:function(a,b,c){var d="this Email field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return c.to.required?e:void 0}}}},{id:"Date",name:"Date",subtitle:"Date",group:"input",formlyType:"datepicker",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],datepickerOptions:"dd-MMMM-yyyy",formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{messages:{required:function(a,b,c){var d="this Date field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return e}}}},{id:"Texarea",name:"Textarea",subtitle:"Textarea",group:"Textarea",formlyType:"textarea",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{messages:{required:function(a,b,c){var d="this Textarea field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return e}}}},{id:"RichTextEditor",name:"RichTextEditor",subtitle:"RichTextEditor",group:"Textarea",formlyType:"richEditor",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{messages:{required:function(a,b,c){var d="this RichTextEditor field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return e}}}},{id:"Radio",name:"Radio",subtitle:"Radio",options:[],group:"Radio",formlyType:"radio",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{messages:{required:function(a,b,c){var d="this Password field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return e}}}},{id:"Checkbox",name:"Checkbox",subtitle:"Checkbox",group:"Checkbox",formlyType:"checkbox",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{messages:{required:function(a,b,c){var d="this Checkbox field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return e}}}},{id:"BasicSelect",name:"Basic select",subtitle:"Basic select",options:[],group:"Select",formlyType:"basicSelect",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{messages:{required:function(a,b,c){var d="this Basic select field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return e}}}},{id:"GroupedSelect",name:"Grouped Select",subtitle:"Grouped Select",options:[],group:"Select",formlyType:"groupedSelect",formlySubtype:"",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{messages:{required:function(a,b,c){var d="this Grouped Select field is required",e="undefined"!=typeof c.to.label&&""!==c.to.label?c.to.label+" is required":d;return e}}}}],selectedControl:"none",temporyConfig:{selectedControl:"none",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyPlaceholder:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{}}};return angular.copy(b,a),!0},c=function(){var a={};return angular.extend(a,{formlyLabel:"",formlyRequired:!1,formlyPlaceholder:"",formlyDesciption:"",formlyOptions:[]}),a},d=function(a){for(var b={selectedControl:"none",formlyType:"none",formlySubtype:"none",formlyLabel:"",formlyRequired:!1,formlyDesciption:"",formlyPlaceholder:"",formlyOptions:[],formlyExpressionProperties:{},formlyValidators:{},formlyValidation:{}},c=a.controls.length-1;c>=0;c--)a.selectedControl===a.controls[c].id&&(b.selectedControl=a.selectedControl,b.formlyType=a.controls[c].formlyType,b.formlySubtype=a.controls[c].formlySubtype,b.formlyLabel=a.controls[c].formlyLabel,b.formlyRequired=a.controls[c].formlyRequired,b.formlyDesciption=a.controls[c].formlyDesciption,b.formlyPlaceholder=a.controls[c].formlyPlaceholder,b.formlyOptions=a.controls[c].formlyOptions,b.formlyExpressionProperties=angular.copy(a.controls[c].formlyExpressionProperties),b.formlyValidators=angular.copy(a.controls[c].formlyValidators),b.formlyValidation=angular.copy(a.controls[c].formlyValidation),"datepicker"===a.controls[c].formlyType&&(b.datepickerOptions=a.controls[c].datepickerOptions));return b},e=function(a,b){for(var c=!0,d=b.lines.length-1;d>=0;d--)for(var e=b.lines[d].columns.length-1;e>=0;e--)b.lines[d].columns[e].control.key===a&&(c=!1);return c},a("resetNyaSelect",b),a("returnControlFromAddCtrlModalModel",d),a("validKeyUniqueness",e),a("getResetConfig",c)}}}),a.register("37",["15","16","36"],function(a){var b,c,d,e,f,g,h,i;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a.resetNyaSelect,e=a.returnControlFromAddCtrlModalModel,f=a.validKeyUniqueness,g=a.getResetConfig}],execute:function(){"use strict";h="$modalProxy",i=function(){function a(b){c(this,a),this.easyFormSteWayConfig=b}return b(a,[{key:"initNyaSelect",value:function(a){return d(a)}},{key:"getControlsDefinition",value:function(){var a={};return d(a),a}},{key:"getNyASelectFromSelectedLineColumn",value:function(a,b,c,e){return d(a),"undefined"!=typeof b.lines[c].columns[e].control.templateOptions&&(a.temporyConfig.selectedControl="undefined"!=typeof b.lines[c].columns[e].control.selectedControl?b.lines[c].columns[e].control.selectedControl:"none",a.temporyConfig.formlyLabel="undefined"!=typeof b.lines[c].columns[e].control.templateOptions.label?b.lines[c].columns[e].control.templateOptions.label:"",a.temporyConfig.formlyRequired="undefined"!=typeof b.lines[c].columns[e].control.templateOptions.required?b.lines[c].columns[e].control.templateOptions.required:"",a.temporyConfig.formlyDesciption="undefined"!=typeof b.lines[c].columns[e].control.templateOptions.description?b.lines[c].columns[e].control.templateOptions.description:"",a.temporyConfig.formlyPlaceholder="undefined"!=typeof b.lines[c].columns[e].control.templateOptions.placeholder?b.lines[c].columns[e].control.templateOptions.placeholder:"",a.temporyConfig.formlyOptions="undefined"!=typeof b.lines[c].columns[e].control.templateOptions.options?b.lines[c].columns[e].control.templateOptions.options:"",a.temporyConfig.formlyExpressionProperties="undefined"!=typeof b.lines[c].columns[e].control.formlyExpressionProperties?angular.copy(b.lines[c].columns[e].control.formlyExpressionProperties):{},a.temporyConfig.formlyValidators="undefined"!=typeof b.lines[c].columns[e].control.formlyValidators?angular.copy(b.lines[c].columns[e].control.formlyValidators):{},a.temporyConfig.formlyValidation="undefined"!=typeof b.lines[c].columns[e].control.formlyValidation?angular.copy(b.lines[c].columns[e].control.formlyValidation):{},"Date"===a.temporyConfig.selectedControl&&(a.temporyConfig.datepickerOptions="undefined"!=typeof b.lines[c].columns[e].control.templateOptions.datepickerOptions?angular.copy(b.lines[c].columns[e].control.templateOptions.datepickerOptions):"")),a}},{key:"bindConfigurationModelFromModalReturn",value:function(a,b,c,d){var g=e(c);d.lines[a].columns[b].control.selectedControl=g.selectedControl,d.lines[a].columns[b].control.type=g.formlyType,d.lines[a].columns[b].control.subtype=g.formlySubtype,d.lines[a].columns[b].control.templateOptions={label:"",required:!1,description:"",placeholder:"",options:[]},d.lines[a].columns[b].control.templateOptions.label=g.formlyLabel,d.lines[a].columns[b].control.templateOptions.required=g.formlyRequired,d.lines[a].columns[b].control.templateOptions.description=g.formlyDesciption,d.lines[a].columns[b].control.templateOptions.placeholder=g.formlyPlaceholder,d.lines[a].columns[b].control.templateOptions.options=g.formlyOptions,d.lines[a].columns[b].control.formlyExpressionProperties=angular.copy(g.formlyExpressionProperties),d.lines[a].columns[b].control.formlyValidators=angular.copy(g.formlyValidators),d.lines[a].columns[b].control.formlyValidation=angular.copy(g.formlyValidation),"datepicker"===d.lines[a].columns[b].control.type&&(d.lines[a].columns[b].control.templateOptions.datepickerOptions=angular.copy(g.datepickerOptions));var h=d.lines[a].columns[b].control.type+"-"+Date.now();f(h,d)===!0?d.lines[a].columns[b].control.key=h:(h=d.lines[a].columns[b].control.type+"-"+Date.now(),f(h,d)===!0?d.lines[a].columns[b].control.key=h:h=d.lines[a].columns[b].control.type+"-"+Date.now()),d.lines[a].columns[b].control.edited=!0}},{key:"applyConfigToSelectedControl",value:function(a){for(var b=a.controls.length-1;b>=0;b--)a.controls[b].id===a.selectedControl&&(a.controls[b].formlyLabel=a.temporyConfig.formlyLabel,a.controls[b].formlyRequired=a.temporyConfig.formlyRequired,a.controls[b].formlyDesciption=a.temporyConfig.formlyDesciption,a.controls[b].formlyPlaceholder=a.temporyConfig.formlyPlaceholder,a.controls[b].formlyOptions=a.temporyConfig.formlyOptions,"Date"===a.controls[b].id&&(a.controls[b].datepickerOptions=angular.copy(a.temporyConfig.datepickerOptions)))}},{key:"resetTemporyConfig",value:function(){return g()}},{key:"refreshControlFormlyExpressionProperties",value:function(a){var b=this;angular.isObject(a)&&angular.forEach(a.lines,function(a,c){angular.forEach(a.columns,function(a,c){var d=b.getControlsDefinition();angular.forEach(d.controls,function(b,c){a.control.type===b.formlyType&&a.control.subtype===b.formlySubtype&&(a.control.formlyExpressionProperties=b.formlyExpressionProperties)})})})}},{key:"refreshControlFormlyValidators",value:function(a){var b=this;angular.isObject(a)&&angular.forEach(a.lines,function(a,c){angular.forEach(a.columns,function(a,c){var d=b.getControlsDefinition();angular.forEach(d.controls,function(b,c){a.control.type===b.formlyType&&a.control.subtype===b.formlySubtype&&(a.control.formlyValidators=b.formlyValidators)})})})}},{key:"refreshControlFormlyValidation",value:function(a){var b=this;angular.isObject(a)&&angular.forEach(a.lines,function(a,c){angular.forEach(a.columns,function(a,c){var d=b.getControlsDefinition();angular.forEach(d.controls,function(b,c){a.control.type===b.formlyType&&a.control.subtype===b.formlySubtype&&(a.control.formlyValidation=b.formlyValidation)})})})}},{key:"filterDisabledControl",value:function(a){var b=this.easyFormSteWayConfig.getListEnabledControl(),c=[];return angular.forEach(b,function(b){angular.forEach(a.controls,function(a){a.id===b.name&&b.enabled===!0&&(c=c.concat(a))})}),c}},{key:"getFilteredNyaSelectObject",value:function(){var a={};return d(a),angular.copy(this.filterDisabledControl(angular.copy(a)))}}]),a}(),i.$inject=["easyFormSteWayConfig"],a("default",i),a("CONTROLLER_MODAL_PROXY_SERVICE",h)}}}),a.register("38",["37"],function(a){"use strict";var b,c,d;return{setters:[function(a){b=a["default"],c=a.CONTROLLER_MODAL_PROXY_SERVICE}],execute:function(){d="modalProxyModule",a("default",angular.module(d,[]).service(c,b))}}}),a.register("39",[],function(a){"use strict";var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;return{setters:[],execute:function(){b={activeLine:1,listConfigStep:["init","first","second","third"],stepIndicators:[!0,!1,!1,!1],configStepCounter:0,submitButtonText:"submit",cancelButtonText:"cancel",lines:[{line:1,activeColumn:1,columns:[{numColumn:1,exist:!0,control:{type:"none",key:"none"}}]}]},c={activeLine:1,listConfigStep:["init","first","second","third"],stepIndicators:[!0,!1,!1,!1],configStepCounter:0,submitButtonText:"submit",cancelButtonText:"cancel",lines:[]},d=function(a){return"undefined"!=typeof a.templateOptions?!0:!1},e=function(a){return"undefined"!=typeof a.templateOptions&&"undefined"!=typeof a.templateOptions.label?a.templateOptions.label:""},f=function(a){return"undefined"!=typeof a.templateOptions&&"undefined"!=typeof a.templateOptions.datepickerOptions?angular.copy(a.templateOptions.datepickerOptions):{
+format:""}},g=function(a){return"undefined"!=typeof a.formlyExpressionProperties?angular.copy(a.formlyExpressionProperties):{}},h=function(a){return"undefined"!=typeof a.formlyValidators?angular.copy(a.formlyValidators):{}},i=function(a){return"undefined"!=typeof a.formlyValidation?angular.copy(a.formlyValidation):{}},j=function(a){return"undefined"!=typeof a.templateOptions&&"undefined"!=typeof a.templateOptions.required?a.templateOptions.required:""},k=function(a){return"undefined"!=typeof a.templateOptions&&"undefined"!=typeof a.templateOptions.options?a.templateOptions.options:""},l=function(a){return"undefined"!=typeof a.subtype?a.subtype:""},m=function(a){return"undefined"!=typeof a.templateOptions&&"undefined"!=typeof a.templateOptions.placeholder?a.templateOptions.placeholder:""},n=function(a){return"undefined"!=typeof a.templateOptions&&"undefined"!=typeof a.templateOptions.description?a.templateOptions.description:""},o=function(a,b,c){a.templateOptions.datepickerOptions=f(b.lines[c].columns[0].control)},p=function(a,b,c){var d='
'+n(b.lines[c].columns[0].control)+" ";a.push({template:"undefined"!=typeof b.lines[c].columns[0].control.type&&"header"===b.lines[c].columns[0].control.type?d:"
"})},q=function(a,b,c){var d={className:"col-xs-12",type:"undefined"!=typeof b.lines[c].columns[0].control.type?"none"===b.lines[c].columns[0].control.type?"blank":b.lines[c].columns[0].control.type:"blank",key:"undefined"!=typeof b.lines[c].columns[0].control.key?b.lines[c].columns[0].control.key:"blank"+Date.now(),templateOptions:{type:l(b.lines[c].columns[0].control),label:e(b.lines[c].columns[0].control),required:j(b.lines[c].columns[0].control),placeholder:m(b.lines[c].columns[0].control),description:n(b.lines[c].columns[0].control),options:k(b.lines[c].columns[0].control)},expressionProperties:g(b.lines[c].columns[0].control),validators:h(b.lines[c].columns[0].control),validation:i(b.lines[c].columns[0].control)};"datepicker"===b.lines[c].columns[0].control.type&&o(d,b,c),a.push(d)},r=function(a,b,c){var d={className:"col-xs-6",template:'
'+n(b.lines[c].columns[0].control)+" "},f={className:"col-xs-6",template:'
'+n(b.lines[c].columns[1].control)+" "},p={className:"col-xs-6",type:"undefined"!=typeof b.lines[c].columns[0].control.type?"none"===b.lines[c].columns[0].control.type?"blank":b.lines[c].columns[0].control.type:"blank",key:"undefined"!=typeof b.lines[c].columns[0].control.key?b.lines[c].columns[0].control.key:"blank"+Date.now(),templateOptions:{type:l(b.lines[c].columns[0].control),label:e(b.lines[c].columns[0].control),required:j(b.lines[c].columns[0].control),placeholder:m(b.lines[c].columns[0].control),description:n(b.lines[c].columns[0].control),options:k(b.lines[c].columns[0].control)},expressionProperties:g(b.lines[c].columns[0].control),validators:h(b.lines[c].columns[0].control),validation:i(b.lines[c].columns[0].control)};"datepicker"===b.lines[c].columns[0].control.type&&o(p,b,c);var q={className:"col-xs-6",type:"undefined"!=typeof b.lines[c].columns[1].control.type?"none"===b.lines[c].columns[1].control.type?"blank":b.lines[c].columns[1].control.type:"blank",key:"undefined"!=typeof b.lines[c].columns[1].control.key?b.lines[c].columns[1].control.key:"blank"+Date.now(),templateOptions:{type:l(b.lines[c].columns[1].control),label:e(b.lines[c].columns[1].control),required:j(b.lines[c].columns[1].control),placeholder:m(b.lines[c].columns[1].control),description:n(b.lines[c].columns[1].control),options:k(b.lines[c].columns[1].control)},expressionProperties:g(b.lines[c].columns[1].control),validators:h(b.lines[c].columns[1].control),validation:i(b.lines[c].columns[1].control)};"datepicker"===b.lines[c].columns[1].control.type&&o(q,b,c);var r=[];"header"===b.lines[c].columns[0].control.type?r.push(d):r.push(p),"header"===b.lines[c].columns[1].control.type?r.push(f):r.push(q),a.push({className:"row",fieldGroup:r})},s=function(a,b,c){var d={className:"col-xs-4",template:'
'+n(b.lines[c].columns[0].control)+" "},f={className:"col-xs-4",template:'
'+n(b.lines[c].columns[1].control)+" "},p={className:"col-xs-4",template:'
'+n(b.lines[c].columns[2].control)+" "},q={className:"col-xs-4",type:"undefined"!=typeof b.lines[c].columns[0].control.type?"none"===b.lines[c].columns[0].control.type?"blank":b.lines[c].columns[0].control.type:"blank",key:"undefined"!=typeof b.lines[c].columns[0].control.key?b.lines[c].columns[0].control.key:"blank"+Date.now(),templateOptions:{type:l(b.lines[c].columns[0].control),label:e(b.lines[c].columns[0].control),required:j(b.lines[c].columns[0].control),placeholder:m(b.lines[c].columns[0].control),description:n(b.lines[c].columns[0].control),options:k(b.lines[c].columns[0].control)},expressionProperties:g(b.lines[c].columns[0].control),validators:h(b.lines[c].columns[0].control),validation:i(b.lines[c].columns[0].control)};"datepicker"===b.lines[c].columns[0].control.type&&o(q,b,c);var r={className:"col-xs-4",type:"undefined"!=typeof b.lines[c].columns[1].control.type?"none"===b.lines[c].columns[1].control.type?"blank":b.lines[c].columns[1].control.type:"blank",key:"undefined"!=typeof b.lines[c].columns[1].control.key?b.lines[c].columns[1].control.key:"blank"+Date.now(),templateOptions:{type:l(b.lines[c].columns[1].control),label:e(b.lines[c].columns[1].control),required:j(b.lines[c].columns[1].control),placeholder:m(b.lines[c].columns[1].control),description:n(b.lines[c].columns[1].control),options:k(b.lines[c].columns[1].control)},expressionProperties:g(b.lines[c].columns[1].control),validators:h(b.lines[c].columns[1].control),validation:i(b.lines[c].columns[1].control)};"datepicker"===b.lines[c].columns[1].control.type&&o(r,b,c);var s={className:"col-xs-4",type:"undefined"!=typeof b.lines[c].columns[2].control.type?"none"===b.lines[c].columns[2].control.type?"blank":b.lines[c].columns[2].control.type:"blank",key:"undefined"!=typeof b.lines[c].columns[2].control.key?b.lines[c].columns[2].control.key:"blank"+Date.now(),templateOptions:{type:l(b.lines[c].columns[2].control),label:e(b.lines[c].columns[2].control),required:j(b.lines[c].columns[2].control),placeholder:m(b.lines[c].columns[2].control),description:n(b.lines[c].columns[2].control),options:k(b.lines[c].columns[2].control)},expressionProperties:g(b.lines[c].columns[2].control),validators:h(b.lines[c].columns[2].control),validation:i(b.lines[c].columns[2].control)};"datepicker"===b.lines[c].columns[2].control.type&&o(s,b,c);var t=[];"header"===b.lines[c].columns[0].control.type?t.push(d):t.push(q),"header"===b.lines[c].columns[1].control.type?t.push(f):t.push(r),"header"===b.lines[c].columns[2].control.type?t.push(p):t.push(s),a.push({className:"row",fieldGroup:t})},t=function(a){var b={};return angular.copy(b,a),!0},u=function(a){var b=[];angular.copy(b,a)},a("configurationModelInit",b),a("configurationModelResult",c),a("resetDataModel",t),a("resetFormlyModel",u),a("isTemplateOptionDefined",d),a("extractTemplateOptionLabel",e),a("extractTemplateOptionDatepickerOptions",f),a("extractFormlyExpressionProperties",g),a("extractFormlyValidators",h),a("extractFormlyValidation",i),a("extractTemplateOptionRequired",j),a("extractTemplateOptionOptions",k),a("extractTemplateOptionType",l),a("extractTemplateOptionPlaceholder",m),a("extractTemplateOptionDescription",n),a("addDatepickerOptionsProperty",o),a("addOneColumnHeader",p),a("addOneColumnControl",q),a("addTwoColumnControl",r),a("addThreeColumnControl",s)}}}),a.register("3a",["15","16","39"],function(a){var b,c,d,e,f,g,h,i,j,k,l,m;return{setters:[function(a){b=a["default"]},function(a){c=a["default"]},function(a){d=a.configurationModelInit,e=a.configurationModelResult,f=a.resetDataModel,g=a.resetFormlyModel,h=a.addOneColumnHeader,i=a.addOneColumnControl,j=a.addTwoColumnControl,k=a.addThreeColumnControl}],execute:function(){"use strict";l="$formlyProxy",m=function(){function a(){c(this,a),this.init()}return b(a,[{key:"init",value:function(){}},{key:"initConfigurationEditFromScratch",value:function(a){angular.copy(d,a)}},{key:"bindConfigurationLines",value:function(a,b){if(angular.isArray(b)){var c=e;return c.lines=[].concat(b),angular.copy(c,a),this.getMessageObject("configuration model is bound","lines are bound to configuration model.")}return this.getErrorObject("lines is not an array","Checks lines type, it is not an array.")}},{key:"applyConfigurationToformlyModel",value:function(a,b,c){g(b),f(c);for(var d=a.lines.length,e=0;d>e;e++)1===a.lines[e].columns.length&&("header"===a.lines[e].columns[0].control.type?h(b,a,e):i(b,a,e)),2===a.lines[e].columns.length&&j(b,a,e),3===a.lines[e].columns.length&&k(b,a,e)}},{key:"getMessageObject",value:function(a,b){var c={noError:!0,title:a,Message:b};return c}}]),a}(),m.$inject=[],a("default",m),a("FORMLY_PROXY_SERVICE",l)}}}),a.register("3b",["3a"],function(a){"use strict";var b,c,d;return{setters:[function(a){b=a["default"],c=a.FORMLY_PROXY_SERVICE}],execute:function(){d="formlyProxyModule",a("default",angular.module(d,[]).service(c,b))}}}),a.registerDynamic("3c",[],!0,function(a,b,c){var d=this,e=d.define;d.define=void 0;var f=Object;return c.exports={create:f.create,getProto:f.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:f.getOwnPropertyDescriptor,setDesc:f.defineProperty,setDescs:f.defineProperties,getKeys:f.keys,getNames:f.getOwnPropertyNames,getSymbols:f.getOwnPropertySymbols,each:[].forEach},d.define=e,c.exports}),a.registerDynamic("3d",["3c"],!0,function(a,b,c){var d=this,e=d.define;d.define=void 0;var f=a("3c");return c.exports=function(a,b,c){return f.setDesc(a,b,c)},d.define=e,c.exports}),a.registerDynamic("3e",["3d"],!0,function(a,b,c){var d=this,e=d.define;return d.define=void 0,c.exports={"default":a("3d"),__esModule:!0},d.define=e,c.exports}),a.registerDynamic("15",["3e"],!0,function(a,b,c){"use strict";var d=this,e=d.define;d.define=void 0;var f=a("3e")["default"];return b["default"]=function(){function a(a,b){for(var c=0;c
=0;c--)if(a.rows[c].option===b)return!1;return!0}},{key:"isOptionValidFormat",value:function(a){return""!==a?!0:!1}},{key:"addNewOptionRadio",value:function(a,b){var c={resultFlag:!1,details:""},d=this.validOption(a,b);if(d.resultFlag===!0){var e={option:b,order:a.rows.length};return a.rows.push(e),c.resultFlag=!0,c.details="",c}return angular.copy(d,c),c}},{key:"addNewOptionBasicSelect",value:function(a,b){var c={resultFlag:!1,details:""},d=this.validOption(a,b);if(d.resultFlag===!0){var e={option:b,order:a.rows.length};return a.rows.push(e),c.resultFlag=!0,c.details="",c}return angular.copy(d,c),c}},{key:"addNewOptionGroupedSelect",value:function(a,b,c){var d={resultFlag:!1,details:""},e=this.validOption(a,b);if(e.resultFlag===!0){var f={option:b,group:c,order:a.rows.length};return a.rows.push(f),d.resultFlag=!0,d.details="",d}return angular.copy(e,d),d}},{key:"removeOption",value:function(a,b){var c={resultFlag:!1,details:""};return-1!==b?(a.rows.splice(b,1),c.resultFlag=!0,c.details="",c):(c.resultFlag=!1,c.details="Option index not valid",c)}},{key:"upthisOption",value:function(a,b){var c={resultFlag:!1,details:""};if(b>-1){if(b>0){if(a.rows[b-1]){var d=a.rows[b];return a.rows.splice(b,1),a.rows.splice(b-1,0,d),c.resultFlag=!0,c.details="",c}return c.resultFlag=!1,c.details="Can't retreive option from option index",c}return c.resultFlag=!0,c.details="",c}return c.resultFlag=!1,c.details="Option index not valid",c}},{key:"downthisOption",value:function(a,b){var c={resultFlag:!1,details:""};if(b>-1){if(b=0;d--)if(a.rows[d].option===b)return c.resultFlag=!1,c.details="Entered option is not unique",c;return c.resultFlag=!0,c.details="",c}return c.resultFlag=!1,c.details="Entered option is empty",c}}]),a}(),e.$inject=[],a("default",e),a("SELECT_OPTION_MANAGE_NAME",d)}}}),a.register("40",["3f"],function(a){"use strict";var b,c,d;return{setters:[function(a){b=a["default"],c=a.SELECT_OPTION_MANAGE_NAME}],execute:function(){d="commonModule",a("default",angular.module(d,[]).service(c,b))}}}),a.register("1",["2","4","6","19","35","38","40","e","f","3b"],function(a){"use strict";var b,c,d,e,f,g,h,i,j,k,l,m,n,o;return{setters:[function(a){},function(a){b=a["default"],c=a.EASY_FORM_VERSION_NAME,d=a.EASY_FORM_VERSION_VALUE},function(a){e=a["default"]},function(a){f=a["default"]},function(a){g=a["default"]},function(a){h=a["default"]},function(a){i=a["default"]},function(a){j=a["default"]},function(a){k=a["default"]},function(a){l=a["default"]}],execute:function(){m="eda.easyformGen.stepway",n=[k.name,j.name,f.name,g.name,h.name,l.name,i.name],o=angular.module(m,n).value(c,d).config(e).config(b),a("default",o)}}})})(function(a){a()});
+//# sourceMappingURL=eda.stepway.min.js.map
\ No newline at end of file
diff --git a/static/js/formly.min.js b/static/js/formly.min.js
new file mode 100644
index 0000000..a1bf5d5
--- /dev/null
+++ b/static/js/formly.min.js
@@ -0,0 +1,4 @@
+/*! angular-formly v8.0.4 | MIT | built with ♥ by Astrism , Kent C. Dodds (ó ì_í)=óò=(ì_í ò) */
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("api-check"),require("angular")):"function"==typeof define&&define.amd?define(["api-check","angular"],t):"object"==typeof exports?exports.ngFormly=t(require("api-check"),require("angular")):e.ngFormly=t(e.apiCheck,e.angular)}(this,function(e,t){return function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={exports:{},id:o,loaded:!1};return e[o].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var r=n(9),i=o(r);t["default"]=i["default"],e.exports=t["default"]},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=n(18);o.version||(o=window.angular),t["default"]=o,e.exports=t["default"]},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function r(e){return i(e,".")||i(e,"[")&&i(e,"]")}function i(e,t){return e&&e.indexOf?-1!==e.indexOf(t):!1}function a(e,t,n,o,r){return v["default"].isFunction(t)?t(o,n,e,r):e.$eval(t,v["default"].extend({$viewValue:o,$modelValue:n},r))}function l(e,t,n){if(t.id)return t.id;var o=t.type;return!o&&t.template?o="template":!o&&t.templateUrl&&(o="templateUrl"),[e,o,t.key,n].join("_")}function f(e){return v["default"].forEach(arguments,function(t,n){n&&v["default"].forEach(t,function(t,n){v["default"].isDefined(e[n])?s(e[n],t)&&f(e[n],t):e[n]=v["default"].copy(t)})}),e}function s(e,t){return v["default"].isObject(e)&&v["default"].isObject(t)&&Object.getPrototypeOf(e)===Object.getPrototypeOf(t)}function u(e,t){if(e.prop||(e=v["default"].element(e)),e.prop("nodeName")===t.toUpperCase())return e;for(var n=e.children(),o=0;n&&on;n++)t[n]=arguments[n];return function(){var e=arguments;t.forEach(function(t){return t.apply(null,e)})}}function c(e,t,n){return n&&(e=e[n],t=t[n]),t&&e?(v["default"].forEach(t,function(t){-1===e.indexOf(t)&&e.push(t)}),e):t?t:e}function m(e,t){return v["default"].isString(e)&&v["default"].isString(t)?e.length>=t.length&&e.substring(0,t.length)===t:!1}function y(e,t){return v["default"].isString(e)&&v["default"].isString(t)?e.length>=t.length&&-1!==e.indexOf(t):!1}Object.defineProperty(t,"__esModule",{value:!0});var h=n(1),v=o(h);t["default"]={containsSelector:r,containsSpecialChar:i,formlyEval:a,getFieldId:l,reverseDeepMerge:f,findByNodeName:u,arrayify:p,extendFunction:d,extendArray:c,startsWith:m,contains:y},e.exports=t["default"]},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t["default"]="https://github.com/formly-js/angular-formly/blob/8.0.4/other/ERRORS_AND_WARNINGS.md#",e.exports=t["default"]},function(t,n){t.exports=e},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function r(e){return{restrict:"A",require:"ngModel",link:function(t,n,o,r){function i(e,t,n){l(t,n),t=a["default"].isObject(t)?t.expression:t,p?f(t,n,e):s(t,n,e)}function l(n,o){var i=n.message;i&&(u.validation.messages[o]=function(){return e.formlyEval(t,i,r.$modelValue,r.$viewValue)})}function f(n,o,i){var a=i?"$asyncValidators":"$validators";r[a][o]=function(o,r){return e.formlyEval(t,n,o,r)}}function s(n,o,i){var a=void 0;r.$parsers.unshift(function(l){var f=e.formlyEval(t,n,r.$modelValue,l);return i?(r.$pending=r.$pending||{},r.$pending[o]=!0,a=f,f.then(function(){a===f&&r.$setValidity(o,!0)})["catch"](function(){a===f&&r.$setValidity(o,!1)})["finally"](function(){var e=r.$pending||{};1===Object.keys(e).length?delete r.$pending:delete r.$pending[o]})):r.$setValidity(o,f),l})}var u=t.options;u.validation.messages=u.validation.messages||{},a["default"].forEach(u.validation.messages,function(n,o){u.validation.messages[o]=function(){return e.formlyEval(t,n,r.$modelValue,r.$viewValue)}});var p=r.hasOwnProperty("$validators")&&!o.hasOwnProperty("useParsers");a["default"].forEach(u.validators,a["default"].bind(null,i,!1)),a["default"].forEach(u.asyncValidators,a["default"].bind(null,i,!0))}}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(1),a=o(i);t["default"]=r,r.$inject=["formlyUtil"],e.exports=t["default"]},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t\n \n ").then(E(e.options,e.formOptions)).then(w)}function y(){e.options.elementAttributes&&o.attr(e.options.elementAttributes)}function h(){e.options.className&&o.addClass(e.options.className),e.options.type&&o.addClass("formly-field-"+e.options.type)}function w(t){return o.html(v(t)),n(o.contents())(e),t}function $(t){function n(t){var n=/\{\{(.*?)}}/,r=n.exec(t);r&&(t=i(t)(e)),o(t)}function o(t){e.$watch('form["'+t+'"]',function(t){t&&(_>1?(e.options.formControl||(e.options.formControl=[]),e.options.formControl.push(t)):e.options.formControl=t,e.fc=e.options.formControl,y(),u(),p(),c())})}function u(){y=e.$watch(function(){var t=f.extras.errorExistsAndShouldBeVisibleExpression,n=e.options,o=j(e.fc);return o.some(function(e){return e.$invalid})?"boolean"==typeof n.validation.show?n.validation.show:t?o.some(function(n){return d.formlyEval(e,t,n.$modelValue,n.$viewValue)}):o.some(function(e){var t=s["default"].isUndefined(e.$touched)&&e.$dirty;return e.$touched||t}):!1},function(t){e.options.validation.errorExistsAndShouldBeVisible=t,e.showError=t})}function p(){m("parsers")}function c(){m("formatters");var t=e.fc,n=e.form.$pristine;e.options.formatters&&!function(){var o=t.$modelValue;t.$formatters.forEach(function(e){o=e(o)}),t.$setViewValue(o),t.$render(),t.$setPristine(),n&&e.form.$setPristine()}()}function m(t){function n(r){if(!r)return[];s["default"].isString(r)&&(r=f.getType(r,!0,e.options));var i=[];return r["extends"]&&(i=d.extendArray(i,n(r["extends"]))),i=d.extendArray(i,l(r,t,[])),i=d.extendArray(i,o(a(r)))}function o(){var e=arguments.length<=0||void 0===arguments[0]?[]:arguments[0],t=[];return s["default"].forEach(s["default"].copy(j(e)).reverse(),function(e){t=d.extendArray(t,n(e))}),t}function i(t){function n(n){var o=e.options.value();return d.formlyEval(e,t,o,n)}return n[u]=t,n}var u="originalParser";"formatters"===t&&(u="originalFormatter");var p=n(C);p=d.extendArray(p,o(e.options.optionsTypes)),p=d.extendArray(p,e.options[t]),s["default"].forEach(p,function(e,t){p[t]=i(e)});var c=e.fc;s["default"].isArray(c)||(c=[c]),s["default"].forEach(c,function(e){var n;e["$"+t]=(n=e["$"+t]).concat.apply(n,r(p))})}var y=s["default"].noop;if(!e.options.noFormControl){var h=s["default"].element(""+t+"
"),v=h[0].querySelectorAll("[ng-model],[data-ng-model]");v.length&&s["default"].forEach(v,function(e){_++,n(e.getAttribute("name"))})}}function A(){C&&C.link&&C.link.apply(F,T),e.options.link&&e.options.link.apply(F,T)}function M(n){return function(o){var r=t.when(o);return s["default"].forEach(n,function(n){r=r.then(function(o){return t.when(n(o,e.options,e)).then(function(e){return s["default"].isString(e)?e:v(e)})})}),r}}if(e.options.fieldGroup)return void c();!p&&e.options.model&&e.$watch("options.model",function(){return e.options.runExpressions()},!0),y(),h();var C=g(e.options),T=arguments,F=this,_=0,W=b(e.options,e.formOptions);O(e.options).then(M(W.preWrapper)).then(E(e.options,e.formOptions)).then(M(W.postWrapper)).then(w).then($).then(A)["catch"](function(t){m("there-was-a-problem-setting-the-template-for-this-field","There was a problem setting the template for this field ",e.options,t)})}function v(e){var t=s["default"].element(" ");return t.append(e).html()}function g(e){return e.type&&f.getType(e.type)}function b(e,t){function n(e){var t=e||{},n=t.preWrapper,i=void 0===n?[]:n,a=t.postWrapper,l=void 0===a?[]:a;o=o.concat(i),r=r.concat(l)}var o=[],r=[];return n(e.templateManipulators),n(t.templateManipulators),n(f.templateManipulators),{preWrapper:o,postWrapper:r}}function O(e){function t(t,n){return s["default"].isDefined(e[t])?e[t]:n&&s["default"].isDefined(n[t])?n[t]:void 0}var n=f.getType(e.type,!0,e),o=t("template",n),r=t("templateUrl",n);if(s["default"].isUndefined(o)&&!r)throw c.getFieldError("type-type-has-no-template","Type '"+e.type+"' has no template. On element:",e);return x(r||o,s["default"].isUndefined(o),e)}function x(n,r,i){var a=void 0;if(a=s["default"].isFunction(n)?t.when(n(i)):t.when(n),!r)return a;var l=function(){var t={cache:o};return{v:a.then(function(n){return e.get(n,t)}).then(function(e){return e.data})["catch"](function(e){m("problem-loading-template-for-templateurl","Problem loading template for "+n,e)})}}();return"object"==typeof l?l.v:void 0}function E(e,n){var o=$(e,n);return function(n){if(!o.length)return t.when(n);o.forEach(function(t){c.checkWrapper(t,e),M(t,e)});var r=o.map(function(e){return x(e.template||e.templateUrl,!e.template)});return t.all(r).then(function(e){e.forEach(function(e,t){c.checkWrapperTemplate(e,o[t])}),e.reverse();var t=e.shift();return e.forEach(function(e){t=w(t,e)}),w(t,n)})}}function w(e,t){var n=s["default"].element(" ");n.append(e);var o=n.find("formly-transclude");return o.length||(o=d.findByNodeName(n,"formly-transclude")),o.replaceWith(t),n.html()}function $(e,t){var n=e.wrapper;if(null===n)return[];n=n?j(n).map(f.getWrapper):j(f.getWrapperByType(e.type));var o=f.getType(e.type,!0,e);if(o&&o.wrapper){var r=j(o.wrapper).map(f.getWrapper);n=n.concat(r)}if(t.wrapper){var i=j(t.wrapper).map(f.getWrapper);n=n.concat(i)}var a=f.getWrapper();return a&&n.push(a),n}function A(e){u["throw"](u.formlyFieldOptions,e,{prefix:"formly-field directive",url:"formly-field-directive-validation-failed"});var t=e.type&&f.getType(e.type);t&&M(t,e,!0),e.expressionProperties&&e.expressionProperties.hide&&m("dont-use-expressionproperties.hide-use-hideexpression-instead","You have specified `hide` in `expressionProperties`. Use `hideExpression` instead",e)}function k(e){u["throw"](u.fieldGroup,e,{prefix:"formly-field directive",url:"formly-field-directive-validation-failed"})}function M(e,t,n){var o=e.apiCheck,r=e.apiCheckInstance,i=e.apiCheckFunction,a=e.apiCheckOptions;C(o,r,i,a,t),n&&t.type&&s["default"].forEach(f.getTypeHeritage(t.type),function(e){C(e.apiCheck,e.apiCheckInstance,e.apiCheckFunction,e.apiCheckOptions,t)})}function C(e,t,n,o,r){if(e){var i=t||f.extras.apiCheckInstance||u;if(!i.config.disabled&&!p["default"].globalConfig.disabled){var a=n||"warn",l=e(i);s["default"].forEach(l,function(e,t){var n=i.shape(e),l=s["default"].extend({prefix:"formly-field type "+r.type+" for property "+t,url:u.config.output.docsBaseUrl+"formly-field-type-apicheck-failed"},o);i[a](n,r[t],l)})}}}var j=d.arrayify;return y.$inject=["$scope","$timeout","$parse","$controller","formlyValidationMessages"],{restrict:"AE",transclude:!0,require:"?^formlyForm",scope:{options:"=",model:"=",originalModel:"=?",formId:"@",index:"=?",fields:"=?",formState:"=?",formOptions:"=?",form:"=?"},controller:y,link:h}}function a(e){return l(e,"optionsTypes",[])}function l(e,t,n){return e.defaultOptions&&e.defaultOptions[t]||n}Object.defineProperty(t,"__esModule",{value:!0});var f=n(1),s=o(f),u=n(4),p=o(u);t["default"]=i,i.$inject=["$http","$q","$compile","$templateCache","$interpolate","formlyConfig","formlyApiCheck","formlyUtil","formlyUsability","formlyWarn"],e.exports=t["default"]},function(e,t){"use strict";function n(e,t){return{restrict:"A",link:function(n,o,r){var i=null,a=o[0],l=t[0];r.$observe("formlyFocus",function(t){"true"===t?e(function(){i=l.activeElement,a.focus()},~~r.focusWait):"false"===t&&l.activeElement===a&&(a.blur(),r.hasOwnProperty("refocus")&&i&&i.focus())})}}}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=n,n.$inject=["$timeout","$document"],e.exports=t["default"]},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t\n <"+h+' formly-field\n ng-repeat="field in fields '+s()+'"\n '+l()+'="!field.hide"\n class="formly-field"\n options="field"\n model="field.model || model"\n original-model="model"\n fields="fields"\n form="theFormlyForm"\n form-id="'+u()+'"\n form-state="options.formState"\n form-options="options"\n index="$index">\n '+h+'>\n
\n '+y+">\n "}function s(i,l,s){function u(){f["default"].forEach(i.fields,c)}function p(e,t){var n=e.$validate;t?t.then(n):n()}function c(e,t){var n=e.model||i.model,o=e.runExpressions&&e.runExpressions();if(e.hideExpression){var r=n[e.key];e.hide=C(e.hideExpression,r,e,t,{model:n})}e.extras&&e.extras.validateOnModelChange&&e.formControl&&(f["default"].isArray(e.formControl)?f["default"].forEach(e.formControl,function(e){p(e,o)}):p(e.formControl,o))}function m(){i.fields=i.fields||[],y(i.options);var t=i.options.fieldTransform||o.extras.fieldTransform;f["default"].isArray(t)||(t=[t]),f["default"].forEach(t,function(t){if(t&&(i.fields=t(i.fields,i.model,i.options,i.form),!i.fields))throw e.getFormlyError("fieldTransform must return an array of fields")}),b(),i.options.watchAllExpressions&&f["default"].forEach(i.fields,O),f["default"].forEach(i.fields,w),f["default"].forEach(i.fields,$)}function y(e){o.extras.fieldTransform&&f["default"].isFunction(o.extras.fieldTransform)?t("fieldtransform-as-a-function-deprecated","fieldTransform as a function has been deprecated.","Attempted for formlyConfig.extras: "+o.extras.fieldTransform.name,o.extras):e.fieldTransform&&f["default"].isFunction(e.fieldTransform)&&t("fieldtransform-as-a-function-deprecated","fieldTransform as a function has been deprecated.","Attempted for form",e)}function h(){l["throw"]([l.formOptionsApi.optional],[i.options],{prefix:"formly-form options check"}),i.options=i.options||{},i.options.formState=i.options.formState||{},f["default"].extend(i.options,{updateInitialValue:v,resetModel:g})}function v(){f["default"].forEach(i.fields,function(e){d(e)&&e.options?e.options.updateInitialValue():e.updateInitialValue()})}function g(){f["default"].forEach(i.fields,function(e){d(e)&&e.options?e.options.resetModel():e.resetModel&&e.resetModel()})}function b(){var e=[i.model],t=i.options.manualModelWatcher;i.options.formState&&e.push(i.options.formState),f["default"].forEach(i.fields,function(n){var o=x(n);n.model&&o&&-1===e.indexOf(n.model)&&!t&&(i.$watch(function(){return n.model},u,!0),e.push(n.model))})}function O(e,t){e.hideExpression&&!function(){var n=e.model||i.model;i.$watch(function(){var o=n[e.key];return C(e.hideExpression,o,e,t,{model:n})},function(t){return e.hide=t},!0)}()}function x(t){function n(n){var o=i.fields.indexOf(t),r=C(n,void 0,t,o,{model:i.model});if(!r)throw e.getFieldError("field-model-must-be-initialized","Field model must be initialized. When specifying a model as a string for a field, the result of the expression must have been initialized ahead of time.",t);return r}var o=!0;return f["default"].isString(t.model)&&!function(){var e=t.model;o=!E(e),t.model=n(e),i.$watch(function(){return n(e)},function(e){return t.model=e})}(),o}function E(e){return["model","formState"].some(function(t){return s.startsWith(e,t+".")||s.startsWith(e,t+"[")})}function w(e,t){d(e)||(e.key=e.key||t||0)}function $(t,n){if(f["default"].isDefined(t.watcher)){var o=t.watcher;f["default"].isArray(o)||(o=[o]),f["default"].forEach(o,function(o){if(!f["default"].isDefined(o.listener)&&!o.runFieldExpressions)throw e.getFieldError("all-field-watchers-must-have-a-listener","All field watchers must have a listener",t);var r=A(o,t,n),a=k(o,t,n),l=o.type||"$watch";o.stopWatching=i[l](r,a,o.watchDeep)})}}function A(e,t,o){var l=void 0;return f["default"].isUndefined(e.expression)?t.key&&(l="model['"+t.key.toString().split(".").join("']['")+"']"):l=e.expression,f["default"].isFunction(l)?!function(){var n=l;l=function(){var t=M.apply(void 0,[e,o].concat(a.call(arguments)));return n.apply(void 0,r(t))},l.displayName="Formly Watch Expression for field for "+t.key}():t.model&&(l=n(l).bind(null,i,{model:t.model})),l}function k(e,t,n){var o=e.listener;return(f["default"].isFunction(o)||e.runFieldExpressions)&&!function(){var i=o;o=function(){var o=void 0;if(i){var l=M.apply(void 0,[e,n].concat(a.call(arguments)));o=i.apply(void 0,r(l))}return e.runFieldExpressions&&c(t,n),o},o.displayName="Formly Watch Listener for field for "+t.key}(),o}function M(e,t){for(var n=arguments.length,o=Array(n>2?n-2:0),r=2;n>r;r++)o[r-2]=arguments[r];return[i.fields[t]].concat(o,[e.stopWatching])}function C(e,t,n,o){var r=arguments.length<=4||void 0===arguments[4]?{}:arguments[4];return r=f["default"].extend(j(n,o),r),s.formlyEval(i,e,t,t,r)}function j(e,t){return{model:e.model,options:e,index:t,formState:i.options.formState,originalModel:i.model,formOptions:i.options,formId:i.formId}}h(),i.model=i.model||{},m(),i.options.manualModelWatcher?f["default"].isFunction(i.options.manualModelWatcher)&&i.$watch(i.options.manualModelWatcher,u,!0):i.$watch("model",u,!0),i.options.formState&&i.$watch("options.formState",u,!0)}function u(e,r,i){function a(){var a=i.name;if(e.formId=a,e.theFormlyForm=e[a],i.form){var l=n(i.form),f=l.assign,s=l(e.$parent);s?(e.theFormlyForm=s,e[a]&&e.theFormlyForm.$removeControl(e[a]),r.removeData("$formController")):f(e.$parent,e[a])}e.theFormlyForm||o.disableWarnings||t("formly-form-has-no-formcontroller","Your formly-form does not have a `form` property. Many functions of the form (like validation) may not work",r,e)}function l(){var t=o.extras.removeChromeAutoComplete===!0,n=e.options&&e.options.removeChromeAutoComplete===!1,i=e.options&&e.options.removeChromeAutoComplete===!0;if(t&&!n||i){var a=document.createElement("input");a.setAttribute("autocomplete","address-level4"),a.setAttribute("hidden","true"),r[0].appendChild(a)}}a(),l()}function p(e){return e?e.replace(/([A-Z])/g,function(e){return"-"+e.toLowerCase()}):""}function d(e){return e&&!!e.fieldGroup}var c=1;return s.$inject=["$scope","formlyApiCheck","formlyUtil"],{restrict:"AE",template:l,replace:!0,transclude:!0,scope:{fields:"=",model:"=",form:"=?",options:"=?"},controller:s,link:u}}Object.defineProperty(t,"__esModule",{value:!0});var a=Array.prototype.slice,l=n(1),f=o(l);t["default"]=i,i.$inject=["formlyUsability","formlyWarn","$parse","formlyConfig","$interpolate"],e.exports=t["default"]},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var r=n(1),i=o(r),a=n(10),l=o(a),f=n(3),s=o(f),u=n(12),p=o(u),d=n(11),c=o(d),m=n(13),y=o(m),h=n(16),v=o(h),g=n(17),b=o(g),O=n(5),x=o(O),E=n(6),w=o(E),$=n(7),A=o($),k=n(8),M=o(k),C=n(15),j=o(C),T=n(14),F=o(T),_="formly";t["default"]=_;var W=i["default"].module(_,[]);W.constant("formlyApiCheck",l["default"]),W.constant("formlyErrorAndWarningsUrlPrefix",s["default"]),W.constant("formlyVersion","8.0.4"),W.provider("formlyUsability",p["default"]),W.provider("formlyConfig",c["default"]),W.factory("formlyValidationMessages",y["default"]),W.factory("formlyUtil",v["default"]),W.factory("formlyWarn",b["default"]),W.directive("formlyCustomValidation",x["default"]),W.directive("formlyField",w["default"]),W.directive("formlyFocus",A["default"]),W.directive("formlyForm",M["default"]),W.run(j["default"]),W.run(F["default"]),e.exports=t["default"]},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function r(e,t){function n(n,r,i,a){var l=a&&a.hasOwnProperty(r),f=e.some(function(e){return a&&a.hasOwnProperty(e)});return f||l?l?t(n,r,i,a):void 0:s.utils.getError(r,i,o)}a["default"].isArray(e)||(e=[e]);var o="specified if these are not specified: `"+e.join(", ")+"` (otherwise it's optional)";return n.type=o,s.utils.checkerHelpers.setupChecker(n)}Object.defineProperty(t,"__esModule",{value:!0});var i=n(1),a=o(i),l=n(4),f=o(l),s=f["default"]({output:{prefix:"angular-formly:",docsBaseUrl:n(3)}}),u=s.oneOfType([s.string,s.func]),p=s.typeOrArrayOf(s.string).nullable,d=s.func,c=s.shape.onlyIf("apiCheck",s.func.withProperties({warn:s.func,"throw":s.func,shape:s.func})),m=s.shape.onlyIf("apiCheck",s.oneOf(["throw","warn"])),y=s.shape({name:r("types",s.string).optional,template:s.shape.ifNot("templateUrl",s.string).optional,templateUrl:s.shape.ifNot("template",s.string).optional,types:s.typeOrArrayOf(s.string).optional,overwriteOk:s.bool.optional,apiCheck:d.optional,apiCheckInstance:c.optional,apiCheckFunction:m.optional,apiCheckOptions:s.object.optional}).strict,h=s.objectOf(s.oneOfType([u,s.shape({expression:u,message:u.optional}).strict])),v=s.oneOfType([s.string,s.object]),g=s.shape({preWrapper:s.arrayOf(s.func).nullable.optional,postWrapper:s.arrayOf(s.func).nullable.optional}).strict.nullable,b=s.objectOf(s.oneOfType([u,s.shape({expression:u,message:u.optional}).strict])),O=s.typeOrArrayOf(s.shape({expression:u.optional,listener:u.optional,runFieldExpressions:s.bool.optional})),x={$$hashKey:s.any.optional,type:s.shape.ifNot(["template","templateUrl"],s.string).optional,template:s.shape.ifNot(["type","templateUrl"],s.oneOfType([s.string,s.func])).optional,templateUrl:s.shape.ifNot(["type","template"],s.oneOfType([s.string,s.func])).optional,key:s.oneOfType([s.string,s.number]).optional,model:v.optional,originalModel:v.optional,className:s.string.optional,id:s.string.optional,name:s.string.optional,expressionProperties:h.optional,extras:s.shape({validateOnModelChange:s.bool.optional,skipNgModelAttrsManipulator:s.oneOfType([s.string,s.bool]).optional}).strict.optional,data:s.object.optional,templateOptions:s.object.optional,wrapper:p.optional,modelOptions:s.shape({updateOn:s.string.optional,debounce:s.oneOfType([s.objectOf(s.number),s.number]).optional,allowInvalid:s.bool.optional,getterSetter:s.bool.optional,timezone:s.string.optional}).optional,watcher:O.optional,validators:b.optional,asyncValidators:b.optional,parsers:s.arrayOf(u).optional,formatters:s.arrayOf(u).optional,noFormControl:s.bool.optional,hide:s.bool.optional,hideExpression:u.optional,ngModelElAttrs:s.objectOf(s.string).optional,ngModelAttrs:s.objectOf(s.shape({statement:s.shape.ifNot(["value","attribute","bound","boolean"],s.any).optional,value:s.shape.ifNot("statement",s.any).optional,attribute:s.shape.ifNot("statement",s.any).optional,bound:s.shape.ifNot("statement",s.any).optional,"boolean":s.shape.ifNot("statement",s.any).optional}).strict).optional,elementAttributes:s.objectOf(s.string).optional,optionsTypes:s.typeOrArrayOf(s.string).optional,link:s.func.optional,controller:s.oneOfType([s.string,s.func,s.array]).optional,validation:s.shape({show:s.bool.nullable.optional,messages:s.objectOf(u).optional,errorExistsAndShouldBeVisible:s.bool.optional}).optional,formControl:s.typeOrArrayOf(s.object).optional,value:s.func.optional,runExpressions:s.func.optional,templateManipulators:g.optional,resetModel:s.func.optional,updateInitialValue:s.func.optional,initialValue:s.any.optional,defaultValue:s.any.optional},E=s.shape(x).strict,w=s.shape({formState:s.object.optional,resetModel:s.func.optional,updateInitialValue:s.func.optional,removeChromeAutoComplete:s.bool.optional,templateManipulators:g.optional,manualModelWatcher:s.oneOfType([s.bool,s.func]).optional,watchAllExpressions:s.bool.optional,wrapper:p.optional,fieldTransform:s.oneOfType([s.func,s.array]).optional,data:s.object.optional}).strict,$=s.shape({$$hashKey:s.any.optional,key:s.oneOfType([s.string,s.number]).optional,fieldGroup:s.arrayOf(s.oneOfType([E,s.object])),className:s.string.optional,options:w.optional,templateOptions:s.object.optional,wrapper:p.optional,watcher:O.optional,hide:s.bool.optional,hideExpression:u.optional,data:s.object.optional,model:v.optional,form:s.object.optional,elementAttributes:s.objectOf(s.string).optional}).strict,A=a["default"].copy(x);A.key=s.string.optional;var k=s.shape({name:s.string,template:s.shape.ifNot("templateUrl",s.oneOfType([s.string,s.func])).optional,templateUrl:s.shape.ifNot("template",s.oneOfType([s.string,s.func])).optional,controller:s.oneOfType([s.func,s.string,s.array]).optional,link:s.func.optional,defaultOptions:s.oneOfType([s.func,s.shape(A)]).optional,"extends":s.string.optional,wrapper:p.optional,data:s.object.optional,apiCheck:d.optional,apiCheckInstance:c.optional,apiCheckFunction:m.optional,apiCheckOptions:s.object.optional,overwriteOk:s.bool.optional}).strict;a["default"].extend(s,{formlyTypeOptions:k,formlyFieldOptions:E,formlyExpression:u,formlyWrapperType:y,fieldGroup:$,formOptionsApi:w}),t["default"]=s,e.exports=t["default"]},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t" in it: '+e+"\nAdditional information: "+JSON.stringify(t))}var f=this;a["default"].extend(this,{getFormlyError:o,getFieldError:n,checkWrapper:i,checkWrapperTemplate:l,getErrorMessage:r,$get:function(){return f}})}Object.defineProperty(t,"__esModule",{value:!0});var i=n(1),a=o(i);t["default"]=r,r.$inject=["formlyApiCheck","formlyErrorAndWarningsUrlPrefix"],e.exports=t["default"]},function(e,t){"use strict";function n(){function e(e,t,r,i,a){o.messages[e]=n(t,r,i,a)}function t(e,t){o.messages[e]=function(){return t}}function n(e,t,n,o){return function(r,i,a){return"undefined"!=typeof a.options.templateOptions[e]?t+" "+a.options.templateOptions[e]+" "+n:o}}var o={addTemplateOptionValueMessage:e,addStringMessage:t,messages:{}};return o}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=n,e.exports=t["default"]},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function r(e){e&&e.documentMode<9&&!function(){var t=e.get(0),n=["formly-field","formly-form"];a["default"].forEach(n,function(e){t.createElement(e)})}()}Object.defineProperty(t,"__esModule",{value:!0});var i=n(1),a=o(i);t["default"]=r,r.$inject=["$document"],e.exports=t["default"]},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function r(e,t){function n(e,n,r){function i(){(a["default"].isDefined(n.validators)||a["default"].isDefined(n.validation.messages))&&u(g,"formly-custom-validation","")}function l(){d(n.key)&&p(g,"ng-model","model."+n.key)}function c(){a["default"].isDefined(n.modelOptions)&&(u(g,"ng-model-options","options.modelOptions"),n.modelOptions.getterSetter&&p(g,"ng-model","options.value"))}function m(){if(n.templateOptions||n.expressionProperties){var e=n.templateOptions||{},o=n.expressionProperties||{},r=f();a["default"].extend(r,n.ngModelAttrs),a["default"].forEach(r,function(r,i){var l=void 0,f=void 0,p="options.templateOptions['"+i+"']",d=e[i],c=s(o,i),m=a["default"].isDefined(d),y=a["default"].isDefined(c);if(r.value)f=r.value,l=i;else if(r.statement&&m)if(f=r.statement,a["default"].isString(e[i]))l="$eval("+p+")";else{if(!a["default"].isFunction(e[i]))throw new Error("options.templateOptions."+i+" must be a string or function: "+JSON.stringify(n));l=p+"(model[options.key], options, this, $event)"}else r.bound&&y?(f=r.bound,l=p):(r.attribute||r["boolean"])&&y?(f=r.attribute||r["boolean"],l=""+t.startSymbol()+p+t.endSymbol()):r.attribute&&m?(f=r.attribute,l=d):r["boolean"]?m&&!y&&d&&(f=r["boolean"],l=!0):r.bound&&m&&(f=r.bound,l=p);a["default"].isDefined(f)&&a["default"].isDefined(l)&&u(g,f,l)})}}function y(){a["default"].forEach(n.ngModelElAttrs,function(e,t){p(g,t,e)})}var h=document.createElement("div"),v=n.extras&&n.extras.skipNgModelAttrsManipulator;if(v===!0)return e;h.innerHTML=e;var g=o(h,v);return g&&g.length?(u(g,"id",r.id),u(g,"name",r.name||r.id),i(),l(),c(),m(),y(),h.innerHTML):e}function o(e,t){var n=a["default"].isString(t)?":not("+t+")":"",o=":not([formly-skip-ng-model-attrs-manipulator])",i="[ng-model]"+n+o+", [data-ng-model]"+n+o;try{return e.querySelectorAll(i)}catch(l){return r(e,t)}}function r(e,t){var n=e.querySelectorAll("[ng-model], [data-ng-model]"),o=[];o.item=function(e){return this[e]};for(var r=0;r, Kent C. Dodds (ó ì_í)=óò=(ì_í ò) */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"api-check\"), require(\"angular\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"api-check\", \"angular\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ngFormly\"] = factory(require(\"api-check\"), require(\"angular\"));\n\telse\n\t\troot[\"ngFormly\"] = factory(root[\"apiCheck\"], root[\"angular\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_4__, __WEBPACK_EXTERNAL_MODULE_18__) {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _indexCommon = __webpack_require__(9);\n\t\n\tvar _indexCommon2 = _interopRequireDefault(_indexCommon);\n\t\n\texports['default'] = _indexCommon2['default'];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 1 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t// some versions of angular don't export the angular module properly,\n\t// so we get it from window in this case.\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\tvar angular = __webpack_require__(18);\n\t\n\t/* istanbul ignore next */\n\tif (!angular.version) {\n\t angular = window.angular;\n\t}\n\texports['default'] = angular;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\texports['default'] = {\n\t containsSelector: containsSelector, containsSpecialChar: containsSpecialChar, formlyEval: formlyEval, getFieldId: getFieldId, reverseDeepMerge: reverseDeepMerge, findByNodeName: findByNodeName,\n\t arrayify: arrayify, extendFunction: extendFunction, extendArray: extendArray, startsWith: startsWith, contains: contains\n\t};\n\t\n\tfunction containsSelector(string) {\n\t return containsSpecialChar(string, '.') || containsSpecialChar(string, '[') && containsSpecialChar(string, ']');\n\t}\n\t\n\tfunction containsSpecialChar(a, b) {\n\t if (!a || !a.indexOf) {\n\t return false;\n\t }\n\t return a.indexOf(b) !== -1;\n\t}\n\t\n\tfunction formlyEval(scope, expression, $modelValue, $viewValue, extraLocals) {\n\t if (_angularFix2['default'].isFunction(expression)) {\n\t return expression($viewValue, $modelValue, scope, extraLocals);\n\t } else {\n\t return scope.$eval(expression, _angularFix2['default'].extend({ $viewValue: $viewValue, $modelValue: $modelValue }, extraLocals));\n\t }\n\t}\n\t\n\tfunction getFieldId(formId, options, index) {\n\t if (options.id) {\n\t return options.id;\n\t }\n\t var type = options.type;\n\t if (!type && options.template) {\n\t type = 'template';\n\t } else if (!type && options.templateUrl) {\n\t type = 'templateUrl';\n\t }\n\t\n\t return [formId, type, options.key, index].join('_');\n\t}\n\t\n\tfunction reverseDeepMerge(dest) {\n\t _angularFix2['default'].forEach(arguments, function (src, index) {\n\t if (!index) {\n\t return;\n\t }\n\t _angularFix2['default'].forEach(src, function (val, prop) {\n\t if (!_angularFix2['default'].isDefined(dest[prop])) {\n\t dest[prop] = _angularFix2['default'].copy(val);\n\t } else if (objAndSameType(dest[prop], val)) {\n\t reverseDeepMerge(dest[prop], val);\n\t }\n\t });\n\t });\n\t return dest;\n\t}\n\t\n\tfunction objAndSameType(obj1, obj2) {\n\t return _angularFix2['default'].isObject(obj1) && _angularFix2['default'].isObject(obj2) && Object.getPrototypeOf(obj1) === Object.getPrototypeOf(obj2);\n\t}\n\t\n\t// recurse down a node tree to find a node with matching nodeName, for custom tags jQuery.find doesn't work in IE8\n\tfunction findByNodeName(el, nodeName) {\n\t if (!el.prop) {\n\t // not a jQuery or jqLite object -> wrap it\n\t el = _angularFix2['default'].element(el);\n\t }\n\t\n\t if (el.prop('nodeName') === nodeName.toUpperCase()) {\n\t return el;\n\t }\n\t\n\t var c = el.children();\n\t for (var i = 0; c && i < c.length; i++) {\n\t var node = findByNodeName(c[i], nodeName);\n\t if (node) {\n\t return node;\n\t }\n\t }\n\t}\n\t\n\tfunction arrayify(obj) {\n\t if (obj && !_angularFix2['default'].isArray(obj)) {\n\t obj = [obj];\n\t } else if (!obj) {\n\t obj = [];\n\t }\n\t return obj;\n\t}\n\t\n\tfunction extendFunction() {\n\t for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) {\n\t fns[_key] = arguments[_key];\n\t }\n\t\n\t return function extendedFunction() {\n\t var args = arguments;\n\t fns.forEach(function (fn) {\n\t return fn.apply(null, args);\n\t });\n\t };\n\t}\n\t\n\tfunction extendArray(primary, secondary, property) {\n\t if (property) {\n\t primary = primary[property];\n\t secondary = secondary[property];\n\t }\n\t if (secondary && primary) {\n\t _angularFix2['default'].forEach(secondary, function (item) {\n\t if (primary.indexOf(item) === -1) {\n\t primary.push(item);\n\t }\n\t });\n\t return primary;\n\t } else if (secondary) {\n\t return secondary;\n\t } else {\n\t return primary;\n\t }\n\t}\n\t\n\tfunction startsWith(str, search) {\n\t if (_angularFix2['default'].isString(str) && _angularFix2['default'].isString(search)) {\n\t return str.length >= search.length && str.substring(0, search.length) === search;\n\t } else {\n\t return false;\n\t }\n\t}\n\t\n\tfunction contains(str, search) {\n\t if (_angularFix2['default'].isString(str) && _angularFix2['default'].isString(search)) {\n\t return str.length >= search.length && str.indexOf(search) !== -1;\n\t } else {\n\t return false;\n\t }\n\t}\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 3 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t\"use strict\";\n\t\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\texports[\"default\"] = \"https://github.com/formly-js/angular-formly/blob/\" + (\"8.0.4\") + \"/other/ERRORS_AND_WARNINGS.md#\";\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 4 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_4__;\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\texports['default'] = formlyCustomValidation;\n\t\n\t// @ngInject\n\tfunction formlyCustomValidation(formlyUtil) {\n\t return {\n\t restrict: 'A',\n\t require: 'ngModel',\n\t link: function formlyCustomValidationLink(scope, el, attrs, ctrl) {\n\t var opts = scope.options;\n\t opts.validation.messages = opts.validation.messages || {};\n\t _angularFix2['default'].forEach(opts.validation.messages, function (message, key) {\n\t opts.validation.messages[key] = function () {\n\t return formlyUtil.formlyEval(scope, message, ctrl.$modelValue, ctrl.$viewValue);\n\t };\n\t });\n\t\n\t var useNewValidatorsApi = ctrl.hasOwnProperty('$validators') && !attrs.hasOwnProperty('useParsers');\n\t _angularFix2['default'].forEach(opts.validators, _angularFix2['default'].bind(null, addValidatorToPipeline, false));\n\t _angularFix2['default'].forEach(opts.asyncValidators, _angularFix2['default'].bind(null, addValidatorToPipeline, true));\n\t\n\t function addValidatorToPipeline(isAsync, validator, name) {\n\t setupMessage(validator, name);\n\t validator = _angularFix2['default'].isObject(validator) ? validator.expression : validator;\n\t if (useNewValidatorsApi) {\n\t setupWithValidators(validator, name, isAsync);\n\t } else {\n\t setupWithParsers(validator, name, isAsync);\n\t }\n\t }\n\t\n\t function setupMessage(validator, name) {\n\t var message = validator.message;\n\t if (message) {\n\t opts.validation.messages[name] = function () {\n\t return formlyUtil.formlyEval(scope, message, ctrl.$modelValue, ctrl.$viewValue);\n\t };\n\t }\n\t }\n\t\n\t function setupWithValidators(validator, name, isAsync) {\n\t var validatorCollection = isAsync ? '$asyncValidators' : '$validators';\n\t\n\t ctrl[validatorCollection][name] = function evalValidity(modelValue, viewValue) {\n\t return formlyUtil.formlyEval(scope, validator, modelValue, viewValue);\n\t };\n\t }\n\t\n\t function setupWithParsers(validator, name, isAsync) {\n\t var inFlightValidator = undefined;\n\t ctrl.$parsers.unshift(function evalValidityOfParser(viewValue) {\n\t var isValid = formlyUtil.formlyEval(scope, validator, ctrl.$modelValue, viewValue);\n\t if (isAsync) {\n\t ctrl.$pending = ctrl.$pending || {};\n\t ctrl.$pending[name] = true;\n\t inFlightValidator = isValid;\n\t isValid.then(function () {\n\t if (inFlightValidator === isValid) {\n\t ctrl.$setValidity(name, true);\n\t }\n\t })['catch'](function () {\n\t if (inFlightValidator === isValid) {\n\t ctrl.$setValidity(name, false);\n\t }\n\t })['finally'](function () {\n\t var $pending = ctrl.$pending || {};\n\t if (Object.keys($pending).length === 1) {\n\t delete ctrl.$pending;\n\t } else {\n\t delete ctrl.$pending[name];\n\t }\n\t });\n\t } else {\n\t ctrl.$setValidity(name, isValid);\n\t }\n\t return viewValue;\n\t });\n\t }\n\t }\n\t };\n\t}\n\tformlyCustomValidation.$inject = [\"formlyUtil\"];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 6 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\tvar _apiCheck = __webpack_require__(4);\n\t\n\tvar _apiCheck2 = _interopRequireDefault(_apiCheck);\n\t\n\texports['default'] = formlyField;\n\t\n\t/**\n\t * @ngdoc directive\n\t * @name formlyField\n\t * @restrict AE\n\t */\n\t// @ngInject\n\tfunction formlyField($http, $q, $compile, $templateCache, $interpolate, formlyConfig, formlyApiCheck, formlyUtil, formlyUsability, formlyWarn) {\n\t var arrayify = formlyUtil.arrayify;\n\t\n\t FormlyFieldController.$inject = [\"$scope\", \"$timeout\", \"$parse\", \"$controller\", \"formlyValidationMessages\"];\n\t return {\n\t restrict: 'AE',\n\t transclude: true,\n\t require: '?^formlyForm',\n\t scope: {\n\t options: '=',\n\t model: '=',\n\t originalModel: '=?',\n\t formId: '@', // TODO remove formId in a breaking release\n\t index: '=?',\n\t fields: '=?',\n\t formState: '=?',\n\t formOptions: '=?',\n\t form: '=?' },\n\t // TODO require form in a breaking release\n\t controller: FormlyFieldController,\n\t link: fieldLink\n\t };\n\t\n\t // @ngInject\n\t function FormlyFieldController($scope, $timeout, $parse, $controller, formlyValidationMessages) {\n\t /* eslint max-statements:[2, 34] */\n\t if ($scope.options.fieldGroup) {\n\t setupFieldGroup();\n\t return;\n\t }\n\t\n\t var fieldType = getFieldType($scope.options);\n\t simplifyLife($scope.options);\n\t mergeFieldOptionsWithTypeDefaults($scope.options, fieldType);\n\t extendOptionsWithDefaults($scope.options, $scope.index);\n\t checkApi($scope.options);\n\t // set field id to link labels and fields\n\t\n\t // initalization\n\t setFieldIdAndName();\n\t setDefaultValue();\n\t setInitialValue();\n\t runExpressions();\n\t watchExpressions();\n\t addValidationMessages($scope.options);\n\t invokeControllers($scope, $scope.options, fieldType);\n\t\n\t // function definitions\n\t function runExpressions() {\n\t // must run on next tick to make sure that the current value is correct.\n\t return $timeout(function runExpressionsOnNextTick() {\n\t var field = $scope.options;\n\t var currentValue = valueGetterSetter();\n\t _angularFix2['default'].forEach(field.expressionProperties, function runExpression(expression, prop) {\n\t var setter = $parse(prop).assign;\n\t var promise = $q.when(formlyUtil.formlyEval($scope, expression, currentValue, currentValue));\n\t promise.then(function setFieldValue(value) {\n\t setter(field, value);\n\t });\n\t });\n\t }, 0, false);\n\t }\n\t\n\t function watchExpressions() {\n\t if ($scope.formOptions.watchAllExpressions) {\n\t (function () {\n\t var field = $scope.options;\n\t var currentValue = valueGetterSetter();\n\t _angularFix2['default'].forEach(field.expressionProperties, function watchExpression(expression, prop) {\n\t var setter = $parse(prop).assign;\n\t $scope.$watch(function expressionPropertyWatcher() {\n\t return formlyUtil.formlyEval($scope, expression, currentValue, currentValue);\n\t }, function expressionPropertyListener(value) {\n\t setter(field, value);\n\t }, true);\n\t });\n\t })();\n\t }\n\t }\n\t\n\t function valueGetterSetter(newVal) {\n\t if (!$scope.model || !$scope.options.key) {\n\t return undefined;\n\t }\n\t if (_angularFix2['default'].isDefined(newVal)) {\n\t parseSet($scope.options.key, $scope.model, newVal);\n\t }\n\t return parseGet($scope.options.key, $scope.model);\n\t }\n\t\n\t function shouldNotUseParseKey(key) {\n\t return _angularFix2['default'].isNumber(key) || !formlyUtil.containsSelector(key);\n\t }\n\t\n\t function parseSet(key, model, newVal) {\n\t // If either of these are null/undefined then just return undefined\n\t if (!key || !model) {\n\t return;\n\t }\n\t // If we are working with a number then $parse wont work, default back to the old way for now\n\t if (shouldNotUseParseKey(key)) {\n\t // TODO: Fix this so we can get several levels instead of just one with properties that are numeric\n\t model[key] = newVal;\n\t } else {\n\t var setter = $parse($scope.options.key).assign;\n\t if (setter) {\n\t setter($scope.model, newVal);\n\t }\n\t }\n\t }\n\t\n\t function parseGet(key, model) {\n\t // If either of these are null/undefined then just return undefined\n\t if (!key || !model) {\n\t return undefined;\n\t }\n\t\n\t // If we are working with a number then $parse wont work, default back to the old way for now\n\t if (shouldNotUseParseKey(key)) {\n\t // TODO: Fix this so we can get several levels instead of just one with properties that are numeric\n\t return model[key];\n\t } else {\n\t return $parse(key)(model);\n\t }\n\t }\n\t\n\t function simplifyLife(options) {\n\t // add a few empty objects (if they don't already exist) so you don't have to undefined check everywhere\n\t formlyUtil.reverseDeepMerge(options, {\n\t originalModel: options.model,\n\t extras: {},\n\t data: {},\n\t templateOptions: {},\n\t validation: {}\n\t });\n\t // create $scope.to so template authors can reference to instead of $scope.options.templateOptions\n\t $scope.to = $scope.options.templateOptions;\n\t $scope.formOptions = $scope.formOptions || {};\n\t }\n\t\n\t function setFieldIdAndName() {\n\t if (_angularFix2['default'].isFunction(formlyConfig.extras.getFieldId)) {\n\t $scope.id = formlyConfig.extras.getFieldId($scope.options, $scope.model, $scope);\n\t } else {\n\t var formName = $scope.form && $scope.form.$name || $scope.formId;\n\t $scope.id = formlyUtil.getFieldId(formName, $scope.options, $scope.index);\n\t }\n\t $scope.options.id = $scope.id;\n\t $scope.name = $scope.options.name || $scope.options.id;\n\t $scope.options.name = $scope.name;\n\t }\n\t\n\t function setDefaultValue() {\n\t if (_angularFix2['default'].isDefined($scope.options.defaultValue) && !_angularFix2['default'].isDefined(parseGet($scope.options.key, $scope.model))) {\n\t parseSet($scope.options.key, $scope.model, $scope.options.defaultValue);\n\t }\n\t }\n\t\n\t function setInitialValue() {\n\t $scope.options.initialValue = $scope.model && parseGet($scope.options.key, $scope.model);\n\t }\n\t\n\t function mergeFieldOptionsWithTypeDefaults(options, type) {\n\t if (type) {\n\t mergeOptions(options, type.defaultOptions);\n\t }\n\t var properOrder = arrayify(options.optionsTypes).reverse(); // so the right things are overridden\n\t _angularFix2['default'].forEach(properOrder, function (typeName) {\n\t mergeOptions(options, formlyConfig.getType(typeName, true, options).defaultOptions);\n\t });\n\t }\n\t\n\t function mergeOptions(options, extraOptions) {\n\t if (extraOptions) {\n\t if (_angularFix2['default'].isFunction(extraOptions)) {\n\t extraOptions = extraOptions(options, $scope);\n\t }\n\t formlyUtil.reverseDeepMerge(options, extraOptions);\n\t }\n\t }\n\t\n\t function extendOptionsWithDefaults(options, index) {\n\t var key = options.key || index || 0;\n\t _angularFix2['default'].extend(options, {\n\t // attach the key in case the formly-field directive is used directly\n\t key: key,\n\t value: options.value || valueGetterSetter,\n\t runExpressions: runExpressions,\n\t resetModel: resetModel,\n\t updateInitialValue: updateInitialValue\n\t });\n\t }\n\t\n\t function resetModel() {\n\t parseSet($scope.options.key, $scope.model, $scope.options.initialValue);\n\t if ($scope.options.formControl) {\n\t if (_angularFix2['default'].isArray($scope.options.formControl)) {\n\t _angularFix2['default'].forEach($scope.options.formControl, function (formControl) {\n\t resetFormControl(formControl, true);\n\t });\n\t } else {\n\t resetFormControl($scope.options.formControl);\n\t }\n\t }\n\t if ($scope.form) {\n\t $scope.form.$setUntouched && $scope.form.$setUntouched();\n\t $scope.form.$setPristine();\n\t }\n\t }\n\t\n\t function resetFormControl(formControl, isMultiNgModel) {\n\t if (!isMultiNgModel) {\n\t formControl.$setViewValue(parseGet($scope.options.key, $scope.model));\n\t }\n\t\n\t formControl.$render();\n\t formControl.$setUntouched && formControl.$setUntouched();\n\t formControl.$setPristine();\n\t\n\t // To prevent breaking change requiring a digest to reset $viewModel\n\t if (!$scope.$root.$$phase) {\n\t $scope.$digest();\n\t }\n\t }\n\t\n\t function updateInitialValue() {\n\t $scope.options.initialValue = parseGet($scope.options.key, $scope.model);\n\t }\n\t\n\t function addValidationMessages(options) {\n\t options.validation.messages = options.validation.messages || {};\n\t _angularFix2['default'].forEach(formlyValidationMessages.messages, function createFunctionForMessage(expression, name) {\n\t if (!options.validation.messages[name]) {\n\t options.validation.messages[name] = function evaluateMessage(viewValue, modelValue, scope) {\n\t return formlyUtil.formlyEval(scope, expression, modelValue, viewValue);\n\t };\n\t }\n\t });\n\t }\n\t\n\t function invokeControllers(scope) {\n\t var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n\t var type = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\t\n\t _angularFix2['default'].forEach([type.controller, options.controller], function (controller) {\n\t if (controller) {\n\t $controller(controller, { $scope: scope });\n\t }\n\t });\n\t }\n\t\n\t function setupFieldGroup() {\n\t $scope.options.options = $scope.options.options || {};\n\t $scope.options.options.formState = $scope.formState;\n\t $scope.to = $scope.options.templateOptions;\n\t }\n\t }\n\t\n\t // link function\n\t function fieldLink(scope, el, attrs, formlyFormCtrl) {\n\t if (scope.options.fieldGroup) {\n\t setFieldGroupTemplate();\n\t return;\n\t }\n\t\n\t // watch the field model (if exists) if there is no parent formly-form directive (that would watch it instead)\n\t if (!formlyFormCtrl && scope.options.model) {\n\t scope.$watch('options.model', function () {\n\t return scope.options.runExpressions();\n\t }, true);\n\t }\n\t\n\t addAttributes();\n\t addClasses();\n\t\n\t var type = getFieldType(scope.options);\n\t var args = arguments;\n\t var thusly = this;\n\t var fieldCount = 0;\n\t var fieldManipulators = getManipulators(scope.options, scope.formOptions);\n\t getFieldTemplate(scope.options).then(runManipulators(fieldManipulators.preWrapper)).then(transcludeInWrappers(scope.options, scope.formOptions)).then(runManipulators(fieldManipulators.postWrapper)).then(setElementTemplate).then(watchFormControl).then(callLinkFunctions)['catch'](function (error) {\n\t formlyWarn('there-was-a-problem-setting-the-template-for-this-field', 'There was a problem setting the template for this field ', scope.options, error);\n\t });\n\t\n\t function setFieldGroupTemplate() {\n\t checkFieldGroupApi(scope.options);\n\t el.addClass('formly-field-group');\n\t var extraAttributes = '';\n\t if (scope.options.elementAttributes) {\n\t extraAttributes = Object.keys(scope.options.elementAttributes).map(function (key) {\n\t return key + '=\"' + scope.options.elementAttributes[key] + '\"';\n\t }).join(' ');\n\t }\n\t var modelValue = 'model';\n\t scope.options.form = scope.form;\n\t if (scope.options.key) {\n\t modelValue = 'model[\\'' + scope.options.key + '\\']';\n\t }\n\t getTemplate('\\n \\n \\n ').then(transcludeInWrappers(scope.options, scope.formOptions)).then(setElementTemplate);\n\t }\n\t\n\t function addAttributes() {\n\t if (scope.options.elementAttributes) {\n\t el.attr(scope.options.elementAttributes);\n\t }\n\t }\n\t\n\t function addClasses() {\n\t if (scope.options.className) {\n\t el.addClass(scope.options.className);\n\t }\n\t if (scope.options.type) {\n\t el.addClass('formly-field-' + scope.options.type);\n\t }\n\t }\n\t\n\t function setElementTemplate(templateString) {\n\t el.html(asHtml(templateString));\n\t $compile(el.contents())(scope);\n\t return templateString;\n\t }\n\t\n\t function watchFormControl(templateString) {\n\t var stopWatchingShowError = _angularFix2['default'].noop;\n\t if (scope.options.noFormControl) {\n\t return;\n\t }\n\t var templateEl = _angularFix2['default'].element('' + templateString + '
');\n\t var ngModelNodes = templateEl[0].querySelectorAll('[ng-model],[data-ng-model]');\n\t\n\t if (ngModelNodes.length) {\n\t _angularFix2['default'].forEach(ngModelNodes, function (ngModelNode) {\n\t fieldCount++;\n\t watchFieldNameOrExistence(ngModelNode.getAttribute('name'));\n\t });\n\t }\n\t\n\t function watchFieldNameOrExistence(name) {\n\t var nameExpressionRegex = /\\{\\{(.*?)}}/;\n\t var nameExpression = nameExpressionRegex.exec(name);\n\t if (nameExpression) {\n\t name = $interpolate(name)(scope);\n\t }\n\t watchFieldExistence(name);\n\t }\n\t\n\t function watchFieldExistence(name) {\n\t scope.$watch('form[\"' + name + '\"]', function formControlChange(formControl) {\n\t if (formControl) {\n\t if (fieldCount > 1) {\n\t if (!scope.options.formControl) {\n\t scope.options.formControl = [];\n\t }\n\t scope.options.formControl.push(formControl);\n\t } else {\n\t scope.options.formControl = formControl;\n\t }\n\t scope.fc = scope.options.formControl; // shortcut for template authors\n\t stopWatchingShowError();\n\t addShowMessagesWatcher();\n\t addParsers();\n\t addFormatters();\n\t }\n\t });\n\t }\n\t\n\t function addShowMessagesWatcher() {\n\t stopWatchingShowError = scope.$watch(function watchShowValidationChange() {\n\t var customExpression = formlyConfig.extras.errorExistsAndShouldBeVisibleExpression;\n\t var options = scope.options;\n\t var formControls = arrayify(scope.fc);\n\t if (!formControls.some(function (fc) {\n\t return fc.$invalid;\n\t })) {\n\t return false;\n\t } else if (typeof options.validation.show === 'boolean') {\n\t return options.validation.show;\n\t } else if (customExpression) {\n\t return formControls.some(function (fc) {\n\t return formlyUtil.formlyEval(scope, customExpression, fc.$modelValue, fc.$viewValue);\n\t });\n\t } else {\n\t return formControls.some(function (fc) {\n\t var noTouchedButDirty = _angularFix2['default'].isUndefined(fc.$touched) && fc.$dirty;\n\t return fc.$touched || noTouchedButDirty;\n\t });\n\t }\n\t }, function onShowValidationChange(show) {\n\t scope.options.validation.errorExistsAndShouldBeVisible = show;\n\t scope.showError = show; // shortcut for template authors\n\t });\n\t }\n\t\n\t function addParsers() {\n\t setParsersOrFormatters('parsers');\n\t }\n\t\n\t function addFormatters() {\n\t setParsersOrFormatters('formatters');\n\t var ctrl = scope.fc;\n\t var formWasPristine = scope.form.$pristine;\n\t if (scope.options.formatters) {\n\t (function () {\n\t var value = ctrl.$modelValue;\n\t ctrl.$formatters.forEach(function (formatter) {\n\t value = formatter(value);\n\t });\n\t\n\t ctrl.$setViewValue(value);\n\t ctrl.$render();\n\t ctrl.$setPristine();\n\t if (formWasPristine) {\n\t scope.form.$setPristine();\n\t }\n\t })();\n\t }\n\t }\n\t\n\t function setParsersOrFormatters(which) {\n\t var originalThingProp = 'originalParser';\n\t if (which === 'formatters') {\n\t originalThingProp = 'originalFormatter';\n\t }\n\t\n\t // init with type's parsers\n\t var things = getThingsFromType(type);\n\t\n\t // get optionsTypes things\n\t things = formlyUtil.extendArray(things, getThingsFromOptionsTypes(scope.options.optionsTypes));\n\t\n\t // get field's things\n\t things = formlyUtil.extendArray(things, scope.options[which]);\n\t\n\t // convert things into formlyExpression things\n\t _angularFix2['default'].forEach(things, function (thing, index) {\n\t things[index] = getFormlyExpressionThing(thing);\n\t });\n\t\n\t var ngModelCtrls = scope.fc;\n\t if (!_angularFix2['default'].isArray(ngModelCtrls)) {\n\t ngModelCtrls = [ngModelCtrls];\n\t }\n\t\n\t _angularFix2['default'].forEach(ngModelCtrls, function (ngModelCtrl) {\n\t var _ngModelCtrl;\n\t\n\t ngModelCtrl['$' + which] = (_ngModelCtrl = ngModelCtrl['$' + which]).concat.apply(_ngModelCtrl, _toConsumableArray(things));\n\t });\n\t\n\t function getThingsFromType(theType) {\n\t if (!theType) {\n\t return [];\n\t }\n\t if (_angularFix2['default'].isString(theType)) {\n\t theType = formlyConfig.getType(theType, true, scope.options);\n\t }\n\t var typeThings = [];\n\t\n\t // get things from parent\n\t if (theType['extends']) {\n\t typeThings = formlyUtil.extendArray(typeThings, getThingsFromType(theType['extends']));\n\t }\n\t\n\t // get own type's things\n\t typeThings = formlyUtil.extendArray(typeThings, getDefaultOptionsProperty(theType, which, []));\n\t\n\t // get things from optionsTypes\n\t typeThings = formlyUtil.extendArray(typeThings, getThingsFromOptionsTypes(getDefaultOptionsOptionsTypes(theType)));\n\t\n\t return typeThings;\n\t }\n\t\n\t function getThingsFromOptionsTypes() {\n\t var optionsTypes = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\t\n\t var optionsTypesThings = [];\n\t _angularFix2['default'].forEach(_angularFix2['default'].copy(arrayify(optionsTypes)).reverse(), function (optionsTypeName) {\n\t optionsTypesThings = formlyUtil.extendArray(optionsTypesThings, getThingsFromType(optionsTypeName));\n\t });\n\t return optionsTypesThings;\n\t }\n\t\n\t function getFormlyExpressionThing(thing) {\n\t formlyExpressionParserOrFormatterFunction[originalThingProp] = thing;\n\t return formlyExpressionParserOrFormatterFunction;\n\t\n\t function formlyExpressionParserOrFormatterFunction($viewValue) {\n\t var $modelValue = scope.options.value();\n\t return formlyUtil.formlyEval(scope, thing, $modelValue, $viewValue);\n\t }\n\t }\n\t }\n\t }\n\t\n\t function callLinkFunctions() {\n\t if (type && type.link) {\n\t type.link.apply(thusly, args);\n\t }\n\t if (scope.options.link) {\n\t scope.options.link.apply(thusly, args);\n\t }\n\t }\n\t\n\t function runManipulators(manipulators) {\n\t return function runManipulatorsOnTemplate(templateToManipulate) {\n\t var chain = $q.when(templateToManipulate);\n\t _angularFix2['default'].forEach(manipulators, function (manipulator) {\n\t chain = chain.then(function (template) {\n\t return $q.when(manipulator(template, scope.options, scope)).then(function (newTemplate) {\n\t return _angularFix2['default'].isString(newTemplate) ? newTemplate : asHtml(newTemplate);\n\t });\n\t });\n\t });\n\t return chain;\n\t };\n\t }\n\t }\n\t\n\t // sort-of stateless util functions\n\t function asHtml(el) {\n\t var wrapper = _angularFix2['default'].element(' ');\n\t return wrapper.append(el).html();\n\t }\n\t\n\t function getFieldType(options) {\n\t return options.type && formlyConfig.getType(options.type);\n\t }\n\t\n\t function getManipulators(options, formOptions) {\n\t var preWrapper = [];\n\t var postWrapper = [];\n\t addManipulators(options.templateManipulators);\n\t addManipulators(formOptions.templateManipulators);\n\t addManipulators(formlyConfig.templateManipulators);\n\t return { preWrapper: preWrapper, postWrapper: postWrapper };\n\t\n\t function addManipulators(manipulators) {\n\t /* eslint-disable */ // it doesn't understand this :-(\n\t\n\t var _ref = manipulators || {};\n\t\n\t var _ref$preWrapper = _ref.preWrapper;\n\t var pre = _ref$preWrapper === undefined ? [] : _ref$preWrapper;\n\t var _ref$postWrapper = _ref.postWrapper;\n\t var post = _ref$postWrapper === undefined ? [] : _ref$postWrapper;\n\t\n\t preWrapper = preWrapper.concat(pre);\n\t postWrapper = postWrapper.concat(post);\n\t /* eslint-enable */\n\t }\n\t }\n\t\n\t function getFieldTemplate(options) {\n\t function fromOptionsOrType(key, fieldType) {\n\t if (_angularFix2['default'].isDefined(options[key])) {\n\t return options[key];\n\t } else if (fieldType && _angularFix2['default'].isDefined(fieldType[key])) {\n\t return fieldType[key];\n\t }\n\t }\n\t\n\t var type = formlyConfig.getType(options.type, true, options);\n\t var template = fromOptionsOrType('template', type);\n\t var templateUrl = fromOptionsOrType('templateUrl', type);\n\t if (_angularFix2['default'].isUndefined(template) && !templateUrl) {\n\t throw formlyUsability.getFieldError('type-type-has-no-template', 'Type \\'' + options.type + '\\' has no template. On element:', options);\n\t }\n\t\n\t return getTemplate(templateUrl || template, _angularFix2['default'].isUndefined(template), options);\n\t }\n\t\n\t function getTemplate(template, isUrl, options) {\n\t var templatePromise = undefined;\n\t if (_angularFix2['default'].isFunction(template)) {\n\t templatePromise = $q.when(template(options));\n\t } else {\n\t templatePromise = $q.when(template);\n\t }\n\t\n\t if (!isUrl) {\n\t return templatePromise;\n\t } else {\n\t var _ret3 = (function () {\n\t var httpOptions = { cache: $templateCache };\n\t return {\n\t v: templatePromise.then(function (url) {\n\t return $http.get(url, httpOptions);\n\t }).then(function (response) {\n\t return response.data;\n\t })['catch'](function handleErrorGettingATemplate(error) {\n\t formlyWarn('problem-loading-template-for-templateurl', 'Problem loading template for ' + template, error);\n\t })\n\t };\n\t })();\n\t\n\t if (typeof _ret3 === 'object') return _ret3.v;\n\t }\n\t }\n\t\n\t function transcludeInWrappers(options, formOptions) {\n\t var wrapper = getWrapperOption(options, formOptions);\n\t\n\t return function transcludeTemplate(template) {\n\t if (!wrapper.length) {\n\t return $q.when(template);\n\t }\n\t\n\t wrapper.forEach(function (aWrapper) {\n\t formlyUsability.checkWrapper(aWrapper, options);\n\t runApiCheck(aWrapper, options);\n\t });\n\t var promises = wrapper.map(function (w) {\n\t return getTemplate(w.template || w.templateUrl, !w.template);\n\t });\n\t return $q.all(promises).then(function (wrappersTemplates) {\n\t wrappersTemplates.forEach(function (wrapperTemplate, index) {\n\t formlyUsability.checkWrapperTemplate(wrapperTemplate, wrapper[index]);\n\t });\n\t wrappersTemplates.reverse(); // wrapper 0 is wrapped in wrapper 1 and so on...\n\t var totalWrapper = wrappersTemplates.shift();\n\t wrappersTemplates.forEach(function (wrapperTemplate) {\n\t totalWrapper = doTransclusion(totalWrapper, wrapperTemplate);\n\t });\n\t return doTransclusion(totalWrapper, template);\n\t });\n\t };\n\t }\n\t\n\t function doTransclusion(wrapper, template) {\n\t var superWrapper = _angularFix2['default'].element(' '); // this allows people not have to have a single root in wrappers\n\t superWrapper.append(wrapper);\n\t var transcludeEl = superWrapper.find('formly-transclude');\n\t if (!transcludeEl.length) {\n\t // try it using our custom find function\n\t transcludeEl = formlyUtil.findByNodeName(superWrapper, 'formly-transclude');\n\t }\n\t transcludeEl.replaceWith(template);\n\t return superWrapper.html();\n\t }\n\t\n\t function getWrapperOption(options, formOptions) {\n\t /* eslint complexity:[2, 6] */\n\t var wrapper = options.wrapper;\n\t // explicit null means no wrapper\n\t if (wrapper === null) {\n\t return [];\n\t }\n\t\n\t // nothing specified means use the default wrapper for the type\n\t if (!wrapper) {\n\t // get all wrappers that specify they apply to this type\n\t wrapper = arrayify(formlyConfig.getWrapperByType(options.type));\n\t } else {\n\t wrapper = arrayify(wrapper).map(formlyConfig.getWrapper);\n\t }\n\t\n\t // get all wrappers for that the type specified that it uses.\n\t var type = formlyConfig.getType(options.type, true, options);\n\t if (type && type.wrapper) {\n\t var typeWrappers = arrayify(type.wrapper).map(formlyConfig.getWrapper);\n\t wrapper = wrapper.concat(typeWrappers);\n\t }\n\t\n\t // add form wrappers\n\t if (formOptions.wrapper) {\n\t var formWrappers = arrayify(formOptions.wrapper).map(formlyConfig.getWrapper);\n\t wrapper = wrapper.concat(formWrappers);\n\t }\n\t\n\t // add the default wrapper last\n\t var defaultWrapper = formlyConfig.getWrapper();\n\t if (defaultWrapper) {\n\t wrapper.push(defaultWrapper);\n\t }\n\t return wrapper;\n\t }\n\t\n\t function checkApi(options) {\n\t formlyApiCheck['throw'](formlyApiCheck.formlyFieldOptions, options, {\n\t prefix: 'formly-field directive',\n\t url: 'formly-field-directive-validation-failed'\n\t });\n\t // validate with the type\n\t var type = options.type && formlyConfig.getType(options.type);\n\t if (type) {\n\t runApiCheck(type, options, true);\n\t }\n\t if (options.expressionProperties && options.expressionProperties.hide) {\n\t formlyWarn('dont-use-expressionproperties.hide-use-hideexpression-instead', 'You have specified `hide` in `expressionProperties`. Use `hideExpression` instead', options);\n\t }\n\t }\n\t\n\t function checkFieldGroupApi(options) {\n\t formlyApiCheck['throw'](formlyApiCheck.fieldGroup, options, {\n\t prefix: 'formly-field directive',\n\t url: 'formly-field-directive-validation-failed'\n\t });\n\t }\n\t\n\t function runApiCheck(_ref2, options, forType) {\n\t var apiCheck = _ref2.apiCheck;\n\t var apiCheckInstance = _ref2.apiCheckInstance;\n\t var apiCheckFunction = _ref2.apiCheckFunction;\n\t var apiCheckOptions = _ref2.apiCheckOptions;\n\t\n\t runApiCheckForType(apiCheck, apiCheckInstance, apiCheckFunction, apiCheckOptions, options);\n\t if (forType && options.type) {\n\t _angularFix2['default'].forEach(formlyConfig.getTypeHeritage(options.type), function (type) {\n\t runApiCheckForType(type.apiCheck, type.apiCheckInstance, type.apiCheckFunction, type.apiCheckOptions, options);\n\t });\n\t }\n\t }\n\t\n\t function runApiCheckForType(apiCheck, apiCheckInstance, apiCheckFunction, apiCheckOptions, options) {\n\t /* eslint complexity:[2, 9] */\n\t if (!apiCheck) {\n\t return;\n\t }\n\t var instance = apiCheckInstance || formlyConfig.extras.apiCheckInstance || formlyApiCheck;\n\t if (instance.config.disabled || _apiCheck2['default'].globalConfig.disabled) {\n\t return;\n\t }\n\t var fn = apiCheckFunction || 'warn';\n\t // this is the new API\n\t var checkerObjects = apiCheck(instance);\n\t _angularFix2['default'].forEach(checkerObjects, function (shape, name) {\n\t var checker = instance.shape(shape);\n\t var checkOptions = _angularFix2['default'].extend({\n\t prefix: 'formly-field type ' + options.type + ' for property ' + name,\n\t url: formlyApiCheck.config.output.docsBaseUrl + 'formly-field-type-apicheck-failed'\n\t }, apiCheckOptions);\n\t instance[fn](checker, options[name], checkOptions);\n\t });\n\t }\n\t}\n\tformlyField.$inject = [\"$http\", \"$q\", \"$compile\", \"$templateCache\", \"$interpolate\", \"formlyConfig\", \"formlyApiCheck\", \"formlyUtil\", \"formlyUsability\", \"formlyWarn\"];\n\t\n\t// Stateless util functions\n\tfunction getDefaultOptionsOptionsTypes(type) {\n\t return getDefaultOptionsProperty(type, 'optionsTypes', []);\n\t}\n\t\n\tfunction getDefaultOptionsProperty(type, prop, defaultValue) {\n\t return type.defaultOptions && type.defaultOptions[prop] || defaultValue;\n\t}\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\texports['default'] = formlyFocus;\n\t\n\t// @ngInject\n\tfunction formlyFocus($timeout, $document) {\n\t return {\n\t restrict: 'A',\n\t link: function formlyFocusLink(scope, element, attrs) {\n\t var previousEl = null;\n\t var el = element[0];\n\t var doc = $document[0];\n\t attrs.$observe('formlyFocus', function respondToFocusExpressionChange(value) {\n\t /* eslint no-bitwise:0 */ // I know what I'm doing. I promise...\n\t if (value === 'true') {\n\t $timeout(function setElementFocus() {\n\t previousEl = doc.activeElement;\n\t el.focus();\n\t }, ~ ~attrs.focusWait);\n\t } else if (value === 'false') {\n\t if (doc.activeElement === el) {\n\t el.blur();\n\t if (attrs.hasOwnProperty('refocus') && previousEl) {\n\t previousEl.focus();\n\t }\n\t }\n\t }\n\t });\n\t }\n\t };\n\t}\n\tformlyFocus.$inject = [\"$timeout\", \"$document\"];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 8 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\tvar _slice = Array.prototype.slice;\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\texports['default'] = formlyForm;\n\t\n\t/**\n\t * @ngdoc directive\n\t * @name formlyForm\n\t * @restrict AE\n\t */\n\t// @ngInject\n\tfunction formlyForm(formlyUsability, formlyWarn, $parse, formlyConfig, $interpolate) {\n\t var currentFormId = 1;\n\t FormlyFormController.$inject = [\"$scope\", \"formlyApiCheck\", \"formlyUtil\"];\n\t return {\n\t restrict: 'AE',\n\t template: formlyFormGetTemplate,\n\t replace: true,\n\t transclude: true,\n\t scope: {\n\t fields: '=',\n\t model: '=',\n\t form: '=?',\n\t options: '=?'\n\t },\n\t controller: FormlyFormController,\n\t link: formlyFormLink\n\t };\n\t\n\t function formlyFormGetTemplate(el, attrs) {\n\t var rootEl = getRootEl();\n\t var fieldRootEl = getFieldRootEl();\n\t var formId = 'formly_' + currentFormId++;\n\t var parentFormAttributes = '';\n\t if (attrs.hasOwnProperty('isFieldGroup') && el.parent().parent().hasClass('formly')) {\n\t parentFormAttributes = copyAttributes(el.parent().parent()[0].attributes);\n\t }\n\t return '\\n <' + rootEl + ' class=\"formly\"\\n name=\"' + getFormName() + '\"\\n role=\"form\" ' + parentFormAttributes + '>\\n <' + fieldRootEl + ' formly-field\\n ng-repeat=\"field in fields ' + getTrackBy() + '\"\\n ' + getHideDirective() + '=\"!field.hide\"\\n class=\"formly-field\"\\n options=\"field\"\\n model=\"field.model || model\"\\n original-model=\"model\"\\n fields=\"fields\"\\n form=\"theFormlyForm\"\\n form-id=\"' + getFormName() + '\"\\n form-state=\"options.formState\"\\n form-options=\"options\"\\n index=\"$index\">\\n ' + fieldRootEl + '>\\n
\\n ' + rootEl + '>\\n ';\n\t\n\t function getRootEl() {\n\t return attrs.rootEl || 'ng-form';\n\t }\n\t\n\t function getFieldRootEl() {\n\t return attrs.fieldRootEl || 'div';\n\t }\n\t\n\t function getHideDirective() {\n\t return attrs.hideDirective || formlyConfig.extras.defaultHideDirective || 'ng-if';\n\t }\n\t\n\t function getTrackBy() {\n\t if (!attrs.trackBy) {\n\t return '';\n\t } else {\n\t return 'track by ' + attrs.trackBy;\n\t }\n\t }\n\t\n\t function getFormName() {\n\t var formName = formId;\n\t var bindName = attrs.bindName;\n\t if (bindName) {\n\t if (_angularFix2['default'].version.minor < 3) {\n\t throw formlyUsability.getFormlyError('bind-name attribute on formly-form not allowed in < angular 1.3');\n\t }\n\t // we can do a one-time binding here because we know we're in 1.3.x territory\n\t formName = $interpolate.startSymbol() + '::\\'formly_\\' + ' + bindName + $interpolate.endSymbol();\n\t }\n\t return formName;\n\t }\n\t\n\t function getTranscludeClass() {\n\t return attrs.transcludeClass || '';\n\t }\n\t\n\t function copyAttributes(attributes) {\n\t var excluded = ['model', 'form', 'fields', 'options', 'name', 'role', 'class', 'data-model', 'data-form', 'data-fields', 'data-options', 'data-name'];\n\t var arrayAttrs = [];\n\t _angularFix2['default'].forEach(attributes, function (_ref) {\n\t var nodeName = _ref.nodeName;\n\t var value = _ref.value;\n\t\n\t if (nodeName !== 'undefined' && excluded.indexOf(nodeName) === -1) {\n\t arrayAttrs.push(toKebabCase(nodeName) + '=\"' + value + '\"');\n\t }\n\t });\n\t return arrayAttrs.join(' ');\n\t }\n\t }\n\t\n\t // @ngInject\n\t function FormlyFormController($scope, formlyApiCheck, formlyUtil) {\n\t setupOptions();\n\t $scope.model = $scope.model || {};\n\t setupFields();\n\t\n\t // watch the model and evaluate watch expressions that depend on it.\n\t if (!$scope.options.manualModelWatcher) {\n\t $scope.$watch('model', onModelOrFormStateChange, true);\n\t } else if (_angularFix2['default'].isFunction($scope.options.manualModelWatcher)) {\n\t $scope.$watch($scope.options.manualModelWatcher, onModelOrFormStateChange, true);\n\t }\n\t\n\t if ($scope.options.formState) {\n\t $scope.$watch('options.formState', onModelOrFormStateChange, true);\n\t }\n\t\n\t function onModelOrFormStateChange() {\n\t _angularFix2['default'].forEach($scope.fields, runFieldExpressionProperties);\n\t }\n\t\n\t function validateFormControl(formControl, promise) {\n\t var validate = formControl.$validate;\n\t if (promise) {\n\t promise.then(validate);\n\t } else {\n\t validate();\n\t }\n\t }\n\t\n\t function runFieldExpressionProperties(field, index) {\n\t var model = field.model || $scope.model;\n\t var promise = field.runExpressions && field.runExpressions();\n\t if (field.hideExpression) {\n\t // can't use hide with expressionProperties reliably\n\t var val = model[field.key];\n\t field.hide = evalCloseToFormlyExpression(field.hideExpression, val, field, index, { model: model });\n\t }\n\t if (field.extras && field.extras.validateOnModelChange && field.formControl) {\n\t if (_angularFix2['default'].isArray(field.formControl)) {\n\t _angularFix2['default'].forEach(field.formControl, function (formControl) {\n\t validateFormControl(formControl, promise);\n\t });\n\t } else {\n\t validateFormControl(field.formControl, promise);\n\t }\n\t }\n\t }\n\t\n\t function setupFields() {\n\t $scope.fields = $scope.fields || [];\n\t\n\t checkDeprecatedOptions($scope.options);\n\t\n\t var fieldTransforms = $scope.options.fieldTransform || formlyConfig.extras.fieldTransform;\n\t\n\t if (!_angularFix2['default'].isArray(fieldTransforms)) {\n\t fieldTransforms = [fieldTransforms];\n\t }\n\t\n\t _angularFix2['default'].forEach(fieldTransforms, function transformFields(fieldTransform) {\n\t if (fieldTransform) {\n\t $scope.fields = fieldTransform($scope.fields, $scope.model, $scope.options, $scope.form);\n\t if (!$scope.fields) {\n\t throw formlyUsability.getFormlyError('fieldTransform must return an array of fields');\n\t }\n\t }\n\t });\n\t\n\t setupModels();\n\t\n\t if ($scope.options.watchAllExpressions) {\n\t _angularFix2['default'].forEach($scope.fields, setupHideExpressionWatcher);\n\t }\n\t\n\t _angularFix2['default'].forEach($scope.fields, attachKey); // attaches a key based on the index if a key isn't specified\n\t _angularFix2['default'].forEach($scope.fields, setupWatchers); // setup watchers for all fields\n\t }\n\t\n\t function checkDeprecatedOptions(options) {\n\t if (formlyConfig.extras.fieldTransform && _angularFix2['default'].isFunction(formlyConfig.extras.fieldTransform)) {\n\t formlyWarn('fieldtransform-as-a-function-deprecated', 'fieldTransform as a function has been deprecated.', 'Attempted for formlyConfig.extras: ' + formlyConfig.extras.fieldTransform.name, formlyConfig.extras);\n\t } else if (options.fieldTransform && _angularFix2['default'].isFunction(options.fieldTransform)) {\n\t formlyWarn('fieldtransform-as-a-function-deprecated', 'fieldTransform as a function has been deprecated.', 'Attempted for form', options);\n\t }\n\t }\n\t\n\t function setupOptions() {\n\t formlyApiCheck['throw']([formlyApiCheck.formOptionsApi.optional], [$scope.options], { prefix: 'formly-form options check' });\n\t $scope.options = $scope.options || {};\n\t $scope.options.formState = $scope.options.formState || {};\n\t\n\t _angularFix2['default'].extend($scope.options, {\n\t updateInitialValue: updateInitialValue,\n\t resetModel: resetModel\n\t });\n\t }\n\t\n\t function updateInitialValue() {\n\t _angularFix2['default'].forEach($scope.fields, function (field) {\n\t if (isFieldGroup(field) && field.options) {\n\t field.options.updateInitialValue();\n\t } else {\n\t field.updateInitialValue();\n\t }\n\t });\n\t }\n\t\n\t function resetModel() {\n\t _angularFix2['default'].forEach($scope.fields, function (field) {\n\t if (isFieldGroup(field) && field.options) {\n\t field.options.resetModel();\n\t } else if (field.resetModel) {\n\t field.resetModel();\n\t }\n\t });\n\t }\n\t\n\t function setupModels() {\n\t // a set of field models that are already watched (the $scope.model will have its own watcher)\n\t var watchedModels = [$scope.model];\n\t // we will not set up automatic model watchers if manual mode is set\n\t var manualModelWatcher = $scope.options.manualModelWatcher;\n\t\n\t if ($scope.options.formState) {\n\t // $scope.options.formState will have its own watcher\n\t watchedModels.push($scope.options.formState);\n\t }\n\t\n\t _angularFix2['default'].forEach($scope.fields, function (field) {\n\t var isNewModel = initModel(field);\n\t\n\t if (field.model && isNewModel && watchedModels.indexOf(field.model) === -1 && !manualModelWatcher) {\n\t $scope.$watch(function () {\n\t return field.model;\n\t }, onModelOrFormStateChange, true);\n\t watchedModels.push(field.model);\n\t }\n\t });\n\t }\n\t\n\t function setupHideExpressionWatcher(field, index) {\n\t if (field.hideExpression) {\n\t (function () {\n\t // can't use hide with expressionProperties reliably\n\t var model = field.model || $scope.model;\n\t $scope.$watch(function hideExpressionWatcher() {\n\t var val = model[field.key];\n\t return evalCloseToFormlyExpression(field.hideExpression, val, field, index, { model: model });\n\t }, function (hide) {\n\t return field.hide = hide;\n\t }, true);\n\t })();\n\t }\n\t }\n\t\n\t function initModel(field) {\n\t var isNewModel = true;\n\t\n\t if (_angularFix2['default'].isString(field.model)) {\n\t (function () {\n\t var expression = field.model;\n\t\n\t isNewModel = !referencesCurrentlyWatchedModel(expression);\n\t\n\t field.model = resolveStringModel(expression);\n\t\n\t $scope.$watch(function () {\n\t return resolveStringModel(expression);\n\t }, function (model) {\n\t return field.model = model;\n\t });\n\t })();\n\t }\n\t\n\t return isNewModel;\n\t\n\t function resolveStringModel(expression) {\n\t var index = $scope.fields.indexOf(field);\n\t var model = evalCloseToFormlyExpression(expression, undefined, field, index, { model: $scope.model });\n\t\n\t if (!model) {\n\t throw formlyUsability.getFieldError('field-model-must-be-initialized', 'Field model must be initialized. When specifying a model as a string for a field, the result of the' + ' expression must have been initialized ahead of time.', field);\n\t }\n\t\n\t return model;\n\t }\n\t }\n\t\n\t function referencesCurrentlyWatchedModel(expression) {\n\t return ['model', 'formState'].some(function (item) {\n\t return formlyUtil.startsWith(expression, item + '.') || formlyUtil.startsWith(expression, item + '[');\n\t });\n\t }\n\t\n\t function attachKey(field, index) {\n\t if (!isFieldGroup(field)) {\n\t field.key = field.key || index || 0;\n\t }\n\t }\n\t\n\t function setupWatchers(field, index) {\n\t if (!_angularFix2['default'].isDefined(field.watcher)) {\n\t return;\n\t }\n\t var watchers = field.watcher;\n\t if (!_angularFix2['default'].isArray(watchers)) {\n\t watchers = [watchers];\n\t }\n\t _angularFix2['default'].forEach(watchers, function setupWatcher(watcher) {\n\t if (!_angularFix2['default'].isDefined(watcher.listener) && !watcher.runFieldExpressions) {\n\t throw formlyUsability.getFieldError('all-field-watchers-must-have-a-listener', 'All field watchers must have a listener', field);\n\t }\n\t var watchExpression = getWatchExpression(watcher, field, index);\n\t var watchListener = getWatchListener(watcher, field, index);\n\t\n\t var type = watcher.type || '$watch';\n\t watcher.stopWatching = $scope[type](watchExpression, watchListener, watcher.watchDeep);\n\t });\n\t }\n\t\n\t function getWatchExpression(watcher, field, index) {\n\t var watchExpression = undefined;\n\t if (!_angularFix2['default'].isUndefined(watcher.expression)) {\n\t watchExpression = watcher.expression;\n\t } else if (field.key) {\n\t watchExpression = 'model[\\'' + field.key.toString().split('.').join('\\'][\\'') + '\\']';\n\t }\n\t if (_angularFix2['default'].isFunction(watchExpression)) {\n\t (function () {\n\t // wrap the field's watch expression so we can call it with the field as the first arg\n\t // and the stop function as the last arg as a helper\n\t var originalExpression = watchExpression;\n\t watchExpression = function formlyWatchExpression() {\n\t var args = modifyArgs.apply(undefined, [watcher, index].concat(_slice.call(arguments)));\n\t return originalExpression.apply(undefined, _toConsumableArray(args));\n\t };\n\t watchExpression.displayName = 'Formly Watch Expression for field for ' + field.key;\n\t })();\n\t } else if (field.model) {\n\t watchExpression = $parse(watchExpression).bind(null, $scope, { model: field.model });\n\t }\n\t return watchExpression;\n\t }\n\t\n\t function getWatchListener(watcher, field, index) {\n\t var watchListener = watcher.listener;\n\t if (_angularFix2['default'].isFunction(watchListener) || watcher.runFieldExpressions) {\n\t (function () {\n\t // wrap the field's watch listener so we can call it with the field as the first arg\n\t // and the stop function as the last arg as a helper\n\t var originalListener = watchListener;\n\t watchListener = function formlyWatchListener() {\n\t var value = undefined;\n\t if (originalListener) {\n\t var args = modifyArgs.apply(undefined, [watcher, index].concat(_slice.call(arguments)));\n\t value = originalListener.apply(undefined, _toConsumableArray(args));\n\t }\n\t if (watcher.runFieldExpressions) {\n\t runFieldExpressionProperties(field, index);\n\t }\n\t return value;\n\t };\n\t watchListener.displayName = 'Formly Watch Listener for field for ' + field.key;\n\t })();\n\t }\n\t return watchListener;\n\t }\n\t\n\t function modifyArgs(watcher, index) {\n\t for (var _len = arguments.length, originalArgs = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n\t originalArgs[_key - 2] = arguments[_key];\n\t }\n\t\n\t return [$scope.fields[index]].concat(originalArgs, [watcher.stopWatching]);\n\t }\n\t\n\t function evalCloseToFormlyExpression(expression, val, field, index) {\n\t var extraLocals = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];\n\t\n\t extraLocals = _angularFix2['default'].extend(getFormlyFieldLikeLocals(field, index), extraLocals);\n\t return formlyUtil.formlyEval($scope, expression, val, val, extraLocals);\n\t }\n\t\n\t function getFormlyFieldLikeLocals(field, index) {\n\t // this makes it closer to what a regular formlyExpression would be\n\t return {\n\t model: field.model,\n\t options: field,\n\t index: index,\n\t formState: $scope.options.formState,\n\t originalModel: $scope.model,\n\t formOptions: $scope.options,\n\t formId: $scope.formId\n\t };\n\t }\n\t }\n\t\n\t function formlyFormLink(scope, el, attrs) {\n\t setFormController();\n\t fixChromeAutocomplete();\n\t\n\t function setFormController() {\n\t var formId = attrs.name;\n\t scope.formId = formId;\n\t scope.theFormlyForm = scope[formId];\n\t if (attrs.form) {\n\t var getter = $parse(attrs.form);\n\t var setter = getter.assign;\n\t var parentForm = getter(scope.$parent);\n\t if (parentForm) {\n\t scope.theFormlyForm = parentForm;\n\t if (scope[formId]) {\n\t scope.theFormlyForm.$removeControl(scope[formId]);\n\t }\n\t\n\t // this next line is probably one of the more dangerous things that angular-formly does to improve the\n\t // API for angular-formly forms. It ensures that the NgModelControllers inside of formly-form will be\n\t // attached to the form that is passed to formly-form rather than the one that formly-form creates\n\t // this is necessary because it's confusing to have a step between the form you pass in\n\t // and the fields in that form. It also is because angular doesn't propagate properties like $submitted down\n\t // to children forms :-( This line was added to solve this issue:\n\t // https://github.com/formly-js/angular-formly/issues/287\n\t // luckily, this is how the formController has been accessed by the NgModelController since angular 1.0.0\n\t // so I expect it will remain this way for the life of angular 1.x\n\t el.removeData('$formController');\n\t } else {\n\t setter(scope.$parent, scope[formId]);\n\t }\n\t }\n\t if (!scope.theFormlyForm && !formlyConfig.disableWarnings) {\n\t /* eslint no-console:0 */\n\t formlyWarn('formly-form-has-no-formcontroller', 'Your formly-form does not have a `form` property. Many functions of the form (like validation) may not work', el, scope);\n\t }\n\t }\n\t\n\t /*\n\t * chrome autocomplete lameness\n\t * see https://code.google.com/p/chromium/issues/detail?id=468153#c14\n\t * ლ(ಠ益ಠლ) (╯°□°)╯︵ ┻━┻ (◞‸◟;)\n\t */\n\t function fixChromeAutocomplete() {\n\t var global = formlyConfig.extras.removeChromeAutoComplete === true;\n\t var offInstance = scope.options && scope.options.removeChromeAutoComplete === false;\n\t var onInstance = scope.options && scope.options.removeChromeAutoComplete === true;\n\t if (global && !offInstance || onInstance) {\n\t var input = document.createElement('input');\n\t input.setAttribute('autocomplete', 'address-level4');\n\t input.setAttribute('hidden', 'true');\n\t el[0].appendChild(input);\n\t }\n\t }\n\t }\n\t\n\t // stateless util functions\n\t function toKebabCase(string) {\n\t if (string) {\n\t return string.replace(/([A-Z])/g, function ($1) {\n\t return '-' + $1.toLowerCase();\n\t });\n\t } else {\n\t return '';\n\t }\n\t }\n\t\n\t function isFieldGroup(field) {\n\t return field && !!field.fieldGroup;\n\t }\n\t}\n\tformlyForm.$inject = [\"formlyUsability\", \"formlyWarn\", \"$parse\", \"formlyConfig\", \"$interpolate\"];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 9 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\tvar _providersFormlyApiCheck = __webpack_require__(10);\n\t\n\tvar _providersFormlyApiCheck2 = _interopRequireDefault(_providersFormlyApiCheck);\n\t\n\tvar _otherDocsBaseUrl = __webpack_require__(3);\n\t\n\tvar _otherDocsBaseUrl2 = _interopRequireDefault(_otherDocsBaseUrl);\n\t\n\tvar _providersFormlyUsability = __webpack_require__(12);\n\t\n\tvar _providersFormlyUsability2 = _interopRequireDefault(_providersFormlyUsability);\n\t\n\tvar _providersFormlyConfig = __webpack_require__(11);\n\t\n\tvar _providersFormlyConfig2 = _interopRequireDefault(_providersFormlyConfig);\n\t\n\tvar _providersFormlyValidationMessages = __webpack_require__(13);\n\t\n\tvar _providersFormlyValidationMessages2 = _interopRequireDefault(_providersFormlyValidationMessages);\n\t\n\tvar _servicesFormlyUtil = __webpack_require__(16);\n\t\n\tvar _servicesFormlyUtil2 = _interopRequireDefault(_servicesFormlyUtil);\n\t\n\tvar _servicesFormlyWarn = __webpack_require__(17);\n\t\n\tvar _servicesFormlyWarn2 = _interopRequireDefault(_servicesFormlyWarn);\n\t\n\tvar _directivesFormlyCustomValidation = __webpack_require__(5);\n\t\n\tvar _directivesFormlyCustomValidation2 = _interopRequireDefault(_directivesFormlyCustomValidation);\n\t\n\tvar _directivesFormlyField = __webpack_require__(6);\n\t\n\tvar _directivesFormlyField2 = _interopRequireDefault(_directivesFormlyField);\n\t\n\tvar _directivesFormlyFocus = __webpack_require__(7);\n\t\n\tvar _directivesFormlyFocus2 = _interopRequireDefault(_directivesFormlyFocus);\n\t\n\tvar _directivesFormlyForm = __webpack_require__(8);\n\t\n\tvar _directivesFormlyForm2 = _interopRequireDefault(_directivesFormlyForm);\n\t\n\tvar _runFormlyNgModelAttrsManipulator = __webpack_require__(15);\n\t\n\tvar _runFormlyNgModelAttrsManipulator2 = _interopRequireDefault(_runFormlyNgModelAttrsManipulator);\n\t\n\tvar _runFormlyCustomTags = __webpack_require__(14);\n\t\n\tvar _runFormlyCustomTags2 = _interopRequireDefault(_runFormlyCustomTags);\n\t\n\tvar ngModuleName = 'formly';\n\t\n\texports['default'] = ngModuleName;\n\t\n\tvar ngModule = _angularFix2['default'].module(ngModuleName, []);\n\t\n\tngModule.constant('formlyApiCheck', _providersFormlyApiCheck2['default']);\n\tngModule.constant('formlyErrorAndWarningsUrlPrefix', _otherDocsBaseUrl2['default']);\n\tngModule.constant('formlyVersion', (\"8.0.4\")); // <-- webpack variable\n\t\n\tngModule.provider('formlyUsability', _providersFormlyUsability2['default']);\n\tngModule.provider('formlyConfig', _providersFormlyConfig2['default']);\n\t\n\tngModule.factory('formlyValidationMessages', _providersFormlyValidationMessages2['default']);\n\tngModule.factory('formlyUtil', _servicesFormlyUtil2['default']);\n\tngModule.factory('formlyWarn', _servicesFormlyWarn2['default']);\n\t\n\tngModule.directive('formlyCustomValidation', _directivesFormlyCustomValidation2['default']);\n\tngModule.directive('formlyField', _directivesFormlyField2['default']);\n\tngModule.directive('formlyFocus', _directivesFormlyFocus2['default']);\n\tngModule.directive('formlyForm', _directivesFormlyForm2['default']);\n\t\n\tngModule.run(_runFormlyNgModelAttrsManipulator2['default']);\n\tngModule.run(_runFormlyCustomTags2['default']);\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 10 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\tvar _apiCheck = __webpack_require__(4);\n\t\n\tvar _apiCheck2 = _interopRequireDefault(_apiCheck);\n\t\n\tvar apiCheck = (0, _apiCheck2['default'])({\n\t output: {\n\t prefix: 'angular-formly:',\n\t docsBaseUrl: __webpack_require__(3)\n\t }\n\t});\n\t\n\tfunction shapeRequiredIfNot(otherProps, propChecker) {\n\t if (!_angularFix2['default'].isArray(otherProps)) {\n\t otherProps = [otherProps];\n\t }\n\t var type = 'specified if these are not specified: `' + otherProps.join(', ') + '` (otherwise it\\'s optional)';\n\t\n\t function shapeRequiredIfNotDefinition(prop, propName, location, obj) {\n\t var propExists = obj && obj.hasOwnProperty(propName);\n\t var otherPropsExist = otherProps.some(function (otherProp) {\n\t return obj && obj.hasOwnProperty(otherProp);\n\t });\n\t if (!otherPropsExist && !propExists) {\n\t return apiCheck.utils.getError(propName, location, type);\n\t } else if (propExists) {\n\t return propChecker(prop, propName, location, obj);\n\t }\n\t }\n\t\n\t shapeRequiredIfNotDefinition.type = type;\n\t return apiCheck.utils.checkerHelpers.setupChecker(shapeRequiredIfNotDefinition);\n\t}\n\t\n\tvar formlyExpression = apiCheck.oneOfType([apiCheck.string, apiCheck.func]);\n\tvar specifyWrapperType = apiCheck.typeOrArrayOf(apiCheck.string).nullable;\n\t\n\tvar apiCheckProperty = apiCheck.func;\n\t\n\tvar apiCheckInstanceProperty = apiCheck.shape.onlyIf('apiCheck', apiCheck.func.withProperties({\n\t warn: apiCheck.func,\n\t 'throw': apiCheck.func,\n\t shape: apiCheck.func\n\t}));\n\t\n\tvar apiCheckFunctionProperty = apiCheck.shape.onlyIf('apiCheck', apiCheck.oneOf(['throw', 'warn']));\n\t\n\tvar formlyWrapperType = apiCheck.shape({\n\t name: shapeRequiredIfNot('types', apiCheck.string).optional,\n\t template: apiCheck.shape.ifNot('templateUrl', apiCheck.string).optional,\n\t templateUrl: apiCheck.shape.ifNot('template', apiCheck.string).optional,\n\t types: apiCheck.typeOrArrayOf(apiCheck.string).optional,\n\t overwriteOk: apiCheck.bool.optional,\n\t apiCheck: apiCheckProperty.optional,\n\t apiCheckInstance: apiCheckInstanceProperty.optional,\n\t apiCheckFunction: apiCheckFunctionProperty.optional,\n\t apiCheckOptions: apiCheck.object.optional\n\t}).strict;\n\t\n\tvar expressionProperties = apiCheck.objectOf(apiCheck.oneOfType([formlyExpression, apiCheck.shape({\n\t expression: formlyExpression,\n\t message: formlyExpression.optional\n\t}).strict]));\n\t\n\tvar modelChecker = apiCheck.oneOfType([apiCheck.string, apiCheck.object]);\n\t\n\tvar templateManipulators = apiCheck.shape({\n\t preWrapper: apiCheck.arrayOf(apiCheck.func).nullable.optional,\n\t postWrapper: apiCheck.arrayOf(apiCheck.func).nullable.optional\n\t}).strict.nullable;\n\t\n\tvar validatorChecker = apiCheck.objectOf(apiCheck.oneOfType([formlyExpression, apiCheck.shape({\n\t expression: formlyExpression,\n\t message: formlyExpression.optional\n\t}).strict]));\n\t\n\tvar watcherChecker = apiCheck.typeOrArrayOf(apiCheck.shape({\n\t expression: formlyExpression.optional,\n\t listener: formlyExpression.optional,\n\t runFieldExpressions: apiCheck.bool.optional\n\t}));\n\t\n\tvar fieldOptionsApiShape = {\n\t $$hashKey: apiCheck.any.optional,\n\t type: apiCheck.shape.ifNot(['template', 'templateUrl'], apiCheck.string).optional,\n\t template: apiCheck.shape.ifNot(['type', 'templateUrl'], apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n\t templateUrl: apiCheck.shape.ifNot(['type', 'template'], apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n\t key: apiCheck.oneOfType([apiCheck.string, apiCheck.number]).optional,\n\t model: modelChecker.optional,\n\t originalModel: modelChecker.optional,\n\t className: apiCheck.string.optional,\n\t id: apiCheck.string.optional,\n\t name: apiCheck.string.optional,\n\t expressionProperties: expressionProperties.optional,\n\t extras: apiCheck.shape({\n\t validateOnModelChange: apiCheck.bool.optional,\n\t skipNgModelAttrsManipulator: apiCheck.oneOfType([apiCheck.string, apiCheck.bool]).optional\n\t }).strict.optional,\n\t data: apiCheck.object.optional,\n\t templateOptions: apiCheck.object.optional,\n\t wrapper: specifyWrapperType.optional,\n\t modelOptions: apiCheck.shape({\n\t updateOn: apiCheck.string.optional,\n\t debounce: apiCheck.oneOfType([apiCheck.objectOf(apiCheck.number), apiCheck.number]).optional,\n\t allowInvalid: apiCheck.bool.optional,\n\t getterSetter: apiCheck.bool.optional,\n\t timezone: apiCheck.string.optional\n\t }).optional,\n\t watcher: watcherChecker.optional,\n\t validators: validatorChecker.optional,\n\t asyncValidators: validatorChecker.optional,\n\t parsers: apiCheck.arrayOf(formlyExpression).optional,\n\t formatters: apiCheck.arrayOf(formlyExpression).optional,\n\t noFormControl: apiCheck.bool.optional,\n\t hide: apiCheck.bool.optional,\n\t hideExpression: formlyExpression.optional,\n\t ngModelElAttrs: apiCheck.objectOf(apiCheck.string).optional,\n\t ngModelAttrs: apiCheck.objectOf(apiCheck.shape({\n\t statement: apiCheck.shape.ifNot(['value', 'attribute', 'bound', 'boolean'], apiCheck.any).optional,\n\t value: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n\t attribute: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n\t bound: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n\t boolean: apiCheck.shape.ifNot('statement', apiCheck.any).optional\n\t }).strict).optional,\n\t elementAttributes: apiCheck.objectOf(apiCheck.string).optional,\n\t optionsTypes: apiCheck.typeOrArrayOf(apiCheck.string).optional,\n\t link: apiCheck.func.optional,\n\t controller: apiCheck.oneOfType([apiCheck.string, apiCheck.func, apiCheck.array]).optional,\n\t validation: apiCheck.shape({\n\t show: apiCheck.bool.nullable.optional,\n\t messages: apiCheck.objectOf(formlyExpression).optional,\n\t errorExistsAndShouldBeVisible: apiCheck.bool.optional\n\t }).optional,\n\t formControl: apiCheck.typeOrArrayOf(apiCheck.object).optional,\n\t value: apiCheck.func.optional,\n\t runExpressions: apiCheck.func.optional,\n\t templateManipulators: templateManipulators.optional,\n\t resetModel: apiCheck.func.optional,\n\t updateInitialValue: apiCheck.func.optional,\n\t initialValue: apiCheck.any.optional,\n\t defaultValue: apiCheck.any.optional\n\t};\n\t\n\tvar formlyFieldOptions = apiCheck.shape(fieldOptionsApiShape).strict;\n\t\n\tvar formOptionsApi = apiCheck.shape({\n\t formState: apiCheck.object.optional,\n\t resetModel: apiCheck.func.optional,\n\t updateInitialValue: apiCheck.func.optional,\n\t removeChromeAutoComplete: apiCheck.bool.optional,\n\t templateManipulators: templateManipulators.optional,\n\t manualModelWatcher: apiCheck.oneOfType([apiCheck.bool, apiCheck.func]).optional,\n\t watchAllExpressions: apiCheck.bool.optional,\n\t wrapper: specifyWrapperType.optional,\n\t fieldTransform: apiCheck.oneOfType([apiCheck.func, apiCheck.array]).optional,\n\t data: apiCheck.object.optional\n\t}).strict;\n\t\n\tvar fieldGroup = apiCheck.shape({\n\t $$hashKey: apiCheck.any.optional,\n\t key: apiCheck.oneOfType([apiCheck.string, apiCheck.number]).optional,\n\t // danger. Nested field groups wont get api-checked...\n\t fieldGroup: apiCheck.arrayOf(apiCheck.oneOfType([formlyFieldOptions, apiCheck.object])),\n\t className: apiCheck.string.optional,\n\t options: formOptionsApi.optional,\n\t templateOptions: apiCheck.object.optional,\n\t wrapper: specifyWrapperType.optional,\n\t watcher: watcherChecker.optional,\n\t hide: apiCheck.bool.optional,\n\t hideExpression: formlyExpression.optional,\n\t data: apiCheck.object.optional,\n\t model: modelChecker.optional,\n\t form: apiCheck.object.optional,\n\t elementAttributes: apiCheck.objectOf(apiCheck.string).optional\n\t}).strict;\n\t\n\tvar typeOptionsDefaultOptions = _angularFix2['default'].copy(fieldOptionsApiShape);\n\ttypeOptionsDefaultOptions.key = apiCheck.string.optional;\n\t\n\tvar formlyTypeOptions = apiCheck.shape({\n\t name: apiCheck.string,\n\t template: apiCheck.shape.ifNot('templateUrl', apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n\t templateUrl: apiCheck.shape.ifNot('template', apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n\t controller: apiCheck.oneOfType([apiCheck.func, apiCheck.string, apiCheck.array]).optional,\n\t link: apiCheck.func.optional,\n\t defaultOptions: apiCheck.oneOfType([apiCheck.func, apiCheck.shape(typeOptionsDefaultOptions)]).optional,\n\t 'extends': apiCheck.string.optional,\n\t wrapper: specifyWrapperType.optional,\n\t data: apiCheck.object.optional,\n\t apiCheck: apiCheckProperty.optional,\n\t apiCheckInstance: apiCheckInstanceProperty.optional,\n\t apiCheckFunction: apiCheckFunctionProperty.optional,\n\t apiCheckOptions: apiCheck.object.optional,\n\t overwriteOk: apiCheck.bool.optional\n\t}).strict;\n\t\n\t_angularFix2['default'].extend(apiCheck, {\n\t formlyTypeOptions: formlyTypeOptions, formlyFieldOptions: formlyFieldOptions, formlyExpression: formlyExpression, formlyWrapperType: formlyWrapperType, fieldGroup: fieldGroup, formOptionsApi: formOptionsApi\n\t});\n\t\n\texports['default'] = apiCheck;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 11 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\tvar _otherUtils = __webpack_require__(2);\n\t\n\tvar _otherUtils2 = _interopRequireDefault(_otherUtils);\n\t\n\texports['default'] = formlyConfig;\n\t\n\t// @ngInject\n\tfunction formlyConfig(formlyUsabilityProvider, formlyErrorAndWarningsUrlPrefix, formlyApiCheck) {\n\t var _this2 = this;\n\t\n\t var typeMap = {};\n\t var templateWrappersMap = {};\n\t var defaultWrapperName = 'default';\n\t var _this = this;\n\t var getError = formlyUsabilityProvider.getFormlyError;\n\t\n\t _angularFix2['default'].extend(this, {\n\t setType: setType,\n\t getType: getType,\n\t getTypeHeritage: getTypeHeritage,\n\t setWrapper: setWrapper,\n\t getWrapper: getWrapper,\n\t getWrapperByType: getWrapperByType,\n\t removeWrapperByName: removeWrapperByName,\n\t removeWrappersForType: removeWrappersForType,\n\t disableWarnings: false,\n\t extras: {\n\t disableNgModelAttrsManipulator: false,\n\t fieldTransform: [],\n\t ngModelAttrsManipulatorPreferUnbound: false,\n\t removeChromeAutoComplete: false,\n\t defaultHideDirective: 'ng-if',\n\t getFieldId: null\n\t },\n\t templateManipulators: {\n\t preWrapper: [],\n\t postWrapper: []\n\t },\n\t $get: function $get() {\n\t return _this2;\n\t }\n\t });\n\t\n\t function setType(options) {\n\t if (_angularFix2['default'].isArray(options)) {\n\t var _ret = (function () {\n\t var allTypes = [];\n\t _angularFix2['default'].forEach(options, function (item) {\n\t allTypes.push(setType(item));\n\t });\n\t return {\n\t v: allTypes\n\t };\n\t })();\n\t\n\t if (typeof _ret === 'object') return _ret.v;\n\t } else if (_angularFix2['default'].isObject(options)) {\n\t checkType(options);\n\t if (options['extends']) {\n\t extendTypeOptions(options);\n\t }\n\t typeMap[options.name] = options;\n\t return typeMap[options.name];\n\t } else {\n\t throw getError('You must provide an object or array for setType. You provided: ' + JSON.stringify(arguments));\n\t }\n\t }\n\t\n\t function checkType(options) {\n\t formlyApiCheck['throw'](formlyApiCheck.formlyTypeOptions, options, {\n\t prefix: 'formlyConfig.setType',\n\t url: 'settype-validation-failed'\n\t });\n\t if (!options.overwriteOk) {\n\t checkOverwrite(options.name, typeMap, options, 'types');\n\t } else {\n\t options.overwriteOk = undefined;\n\t }\n\t }\n\t\n\t function extendTypeOptions(options) {\n\t var extendsType = getType(options['extends'], true, options);\n\t extendTypeControllerFunction(options, extendsType);\n\t extendTypeLinkFunction(options, extendsType);\n\t extendTypeDefaultOptions(options, extendsType);\n\t _otherUtils2['default'].reverseDeepMerge(options, extendsType);\n\t extendTemplate(options, extendsType);\n\t }\n\t\n\t function extendTemplate(options, extendsType) {\n\t if (options.template && extendsType.templateUrl) {\n\t delete options.templateUrl;\n\t } else if (options.templateUrl && extendsType.template) {\n\t delete options.template;\n\t }\n\t }\n\t\n\t function extendTypeControllerFunction(options, extendsType) {\n\t var extendsCtrl = extendsType.controller;\n\t if (!_angularFix2['default'].isDefined(extendsCtrl)) {\n\t return;\n\t }\n\t var optionsCtrl = options.controller;\n\t if (_angularFix2['default'].isDefined(optionsCtrl)) {\n\t options.controller = function ($scope, $controller) {\n\t $controller(extendsCtrl, { $scope: $scope });\n\t $controller(optionsCtrl, { $scope: $scope });\n\t };\n\t options.controller.$inject = ['$scope', '$controller'];\n\t } else {\n\t options.controller = extendsCtrl;\n\t }\n\t }\n\t\n\t function extendTypeLinkFunction(options, extendsType) {\n\t var extendsFn = extendsType.link;\n\t if (!_angularFix2['default'].isDefined(extendsFn)) {\n\t return;\n\t }\n\t var optionsFn = options.link;\n\t if (_angularFix2['default'].isDefined(optionsFn)) {\n\t options.link = function () {\n\t extendsFn.apply(undefined, arguments);\n\t optionsFn.apply(undefined, arguments);\n\t };\n\t } else {\n\t options.link = extendsFn;\n\t }\n\t }\n\t\n\t function extendTypeDefaultOptions(options, extendsType) {\n\t var extendsDO = extendsType.defaultOptions;\n\t if (!_angularFix2['default'].isDefined(extendsDO)) {\n\t return;\n\t }\n\t var optionsDO = options.defaultOptions;\n\t var optionsDOIsFn = _angularFix2['default'].isFunction(optionsDO);\n\t var extendsDOIsFn = _angularFix2['default'].isFunction(extendsDO);\n\t if (extendsDOIsFn) {\n\t options.defaultOptions = function defaultOptions(opts, scope) {\n\t var extendsDefaultOptions = extendsDO(opts, scope);\n\t var mergedDefaultOptions = {};\n\t _otherUtils2['default'].reverseDeepMerge(mergedDefaultOptions, opts, extendsDefaultOptions);\n\t var extenderOptionsDefaultOptions = optionsDO;\n\t if (optionsDOIsFn) {\n\t extenderOptionsDefaultOptions = extenderOptionsDefaultOptions(mergedDefaultOptions, scope);\n\t }\n\t _otherUtils2['default'].reverseDeepMerge(extendsDefaultOptions, extenderOptionsDefaultOptions);\n\t return extendsDefaultOptions;\n\t };\n\t } else if (optionsDOIsFn) {\n\t options.defaultOptions = function defaultOptions(opts, scope) {\n\t var newDefaultOptions = {};\n\t _otherUtils2['default'].reverseDeepMerge(newDefaultOptions, opts, extendsDO);\n\t return optionsDO(newDefaultOptions, scope);\n\t };\n\t }\n\t }\n\t\n\t function getType(name, throwError, errorContext) {\n\t if (!name) {\n\t return undefined;\n\t }\n\t var type = typeMap[name];\n\t if (!type && throwError === true) {\n\t throw getError('There is no type by the name of \"' + name + '\": ' + JSON.stringify(errorContext));\n\t } else {\n\t return type;\n\t }\n\t }\n\t\n\t function getTypeHeritage(parent) {\n\t var heritage = [];\n\t var type = parent;\n\t if (_angularFix2['default'].isString(type)) {\n\t type = getType(parent);\n\t }\n\t parent = type['extends'];\n\t while (parent) {\n\t type = getType(parent);\n\t heritage.push(type);\n\t parent = type['extends'];\n\t }\n\t return heritage;\n\t }\n\t\n\t function setWrapper(_x, _x2) {\n\t var _again = true;\n\t\n\t _function: while (_again) {\n\t var options = _x,\n\t name = _x2;\n\t _again = false;\n\t\n\t if (_angularFix2['default'].isArray(options)) {\n\t return options.map(function (wrapperOptions) {\n\t return setWrapper(wrapperOptions);\n\t });\n\t } else if (_angularFix2['default'].isObject(options)) {\n\t options.types = getOptionsTypes(options);\n\t options.name = getOptionsName(options, name);\n\t checkWrapperAPI(options);\n\t templateWrappersMap[options.name] = options;\n\t return options;\n\t } else if (_angularFix2['default'].isString(options)) {\n\t _x = {\n\t template: options,\n\t name: name\n\t };\n\t _x2 = undefined;\n\t _again = true;\n\t continue _function;\n\t }\n\t }\n\t }\n\t\n\t function getOptionsTypes(options) {\n\t if (_angularFix2['default'].isString(options.types)) {\n\t return [options.types];\n\t }\n\t if (!_angularFix2['default'].isDefined(options.types)) {\n\t return [];\n\t } else {\n\t return options.types;\n\t }\n\t }\n\t\n\t function getOptionsName(options, name) {\n\t return options.name || name || options.types.join(' ') || defaultWrapperName;\n\t }\n\t\n\t function checkWrapperAPI(options) {\n\t formlyUsabilityProvider.checkWrapper(options);\n\t if (options.template) {\n\t formlyUsabilityProvider.checkWrapperTemplate(options.template, options);\n\t }\n\t if (!options.overwriteOk) {\n\t checkOverwrite(options.name, templateWrappersMap, options, 'templateWrappers');\n\t } else {\n\t delete options.overwriteOk;\n\t }\n\t checkWrapperTypes(options);\n\t }\n\t\n\t function checkWrapperTypes(options) {\n\t var shouldThrow = !_angularFix2['default'].isArray(options.types) || !options.types.every(_angularFix2['default'].isString);\n\t if (shouldThrow) {\n\t throw getError('Attempted to create a template wrapper with types that is not a string or an array of strings');\n\t }\n\t }\n\t\n\t function checkOverwrite(property, object, newValue, objectName) {\n\t if (object.hasOwnProperty(property)) {\n\t warn('overwriting-types-or-wrappers', ['Attempting to overwrite ' + property + ' on ' + objectName + ' which is currently', JSON.stringify(object[property]) + ' with ' + JSON.stringify(newValue), 'To supress this warning, specify the property \"overwriteOk: true\"'].join(' '));\n\t }\n\t }\n\t\n\t function getWrapper(name) {\n\t return templateWrappersMap[name || defaultWrapperName];\n\t }\n\t\n\t function getWrapperByType(type) {\n\t /* eslint prefer-const:0 */\n\t var wrappers = [];\n\t for (var _name in templateWrappersMap) {\n\t if (templateWrappersMap.hasOwnProperty(_name)) {\n\t if (templateWrappersMap[_name].types && templateWrappersMap[_name].types.indexOf(type) !== -1) {\n\t wrappers.push(templateWrappersMap[_name]);\n\t }\n\t }\n\t }\n\t return wrappers;\n\t }\n\t\n\t function removeWrapperByName(name) {\n\t var wrapper = templateWrappersMap[name];\n\t delete templateWrappersMap[name];\n\t return wrapper;\n\t }\n\t\n\t function removeWrappersForType(type) {\n\t var wrappers = getWrapperByType(type);\n\t if (!wrappers) {\n\t return undefined;\n\t }\n\t if (!_angularFix2['default'].isArray(wrappers)) {\n\t return removeWrapperByName(wrappers.name);\n\t } else {\n\t wrappers.forEach(function (wrapper) {\n\t return removeWrapperByName(wrapper.name);\n\t });\n\t return wrappers;\n\t }\n\t }\n\t\n\t function warn() {\n\t if (!_this.disableWarnings && console.warn) {\n\t /* eslint no-console:0 */\n\t var args = Array.prototype.slice.call(arguments);\n\t var warnInfoSlug = args.shift();\n\t args.unshift('Formly Warning:');\n\t args.push('' + formlyErrorAndWarningsUrlPrefix + warnInfoSlug);\n\t console.warn.apply(console, _toConsumableArray(args));\n\t }\n\t }\n\t}\n\tformlyConfig.$inject = [\"formlyUsabilityProvider\", \"formlyErrorAndWarningsUrlPrefix\", \"formlyApiCheck\"];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 12 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\texports['default'] = formlyUsability;\n\t\n\t// @ngInject\n\tfunction formlyUsability(formlyApiCheck, formlyErrorAndWarningsUrlPrefix) {\n\t var _this = this;\n\t\n\t _angularFix2['default'].extend(this, {\n\t getFormlyError: getFormlyError,\n\t getFieldError: getFieldError,\n\t checkWrapper: checkWrapper,\n\t checkWrapperTemplate: checkWrapperTemplate,\n\t getErrorMessage: getErrorMessage,\n\t $get: function $get() {\n\t return _this;\n\t }\n\t });\n\t\n\t function getFieldError(errorInfoSlug, message, field) {\n\t if (arguments.length < 3) {\n\t field = message;\n\t message = errorInfoSlug;\n\t errorInfoSlug = null;\n\t }\n\t return new Error(getErrorMessage(errorInfoSlug, message) + (' Field definition: ' + _angularFix2['default'].toJson(field)));\n\t }\n\t\n\t function getFormlyError(errorInfoSlug, message) {\n\t if (!message) {\n\t message = errorInfoSlug;\n\t errorInfoSlug = null;\n\t }\n\t return new Error(getErrorMessage(errorInfoSlug, message));\n\t }\n\t\n\t function getErrorMessage(errorInfoSlug, message) {\n\t var url = '';\n\t if (errorInfoSlug !== null) {\n\t url = '' + formlyErrorAndWarningsUrlPrefix + errorInfoSlug;\n\t }\n\t return 'Formly Error: ' + message + '. ' + url;\n\t }\n\t\n\t function checkWrapper(wrapper) {\n\t formlyApiCheck['throw'](formlyApiCheck.formlyWrapperType, wrapper, {\n\t prefix: 'formlyConfig.setWrapper',\n\t urlSuffix: 'setwrapper-validation-failed'\n\t });\n\t }\n\t\n\t function checkWrapperTemplate(template, additionalInfo) {\n\t var formlyTransclude = ' ';\n\t if (template.indexOf(formlyTransclude) === -1) {\n\t throw getFormlyError('Template wrapper templates must use \"' + formlyTransclude + '\" somewhere in them. ' + ('This one does not have \" \" in it: ' + template) + '\\n' + ('Additional information: ' + JSON.stringify(additionalInfo)));\n\t }\n\t }\n\t}\n\tformlyUsability.$inject = [\"formlyApiCheck\", \"formlyErrorAndWarningsUrlPrefix\"];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 13 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\texports['default'] = formlyValidationMessages;\n\t\n\t// @ngInject\n\tfunction formlyValidationMessages() {\n\t\n\t var validationMessages = {\n\t addTemplateOptionValueMessage: addTemplateOptionValueMessage,\n\t addStringMessage: addStringMessage,\n\t messages: {}\n\t };\n\t\n\t return validationMessages;\n\t\n\t function addTemplateOptionValueMessage(name, prop, prefix, suffix, alternate) {\n\t validationMessages.messages[name] = templateOptionValue(prop, prefix, suffix, alternate);\n\t }\n\t\n\t function addStringMessage(name, string) {\n\t validationMessages.messages[name] = function () {\n\t return string;\n\t };\n\t }\n\t\n\t function templateOptionValue(prop, prefix, suffix, alternate) {\n\t return function getValidationMessage(viewValue, modelValue, scope) {\n\t if (typeof scope.options.templateOptions[prop] !== 'undefined') {\n\t return prefix + ' ' + scope.options.templateOptions[prop] + ' ' + suffix;\n\t } else {\n\t return alternate;\n\t }\n\t };\n\t }\n\t}\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 14 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\texports['default'] = addCustomTags;\n\t\n\t// @ngInject\n\tfunction addCustomTags($document) {\n\t // IE8 check ->\n\t // https://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx\n\t if ($document && $document.documentMode < 9) {\n\t (function () {\n\t var document = $document.get(0);\n\t // add the custom elements that we need for formly\n\t var customElements = ['formly-field', 'formly-form'];\n\t _angularFix2['default'].forEach(customElements, function (el) {\n\t document.createElement(el);\n\t });\n\t })();\n\t }\n\t}\n\taddCustomTags.$inject = [\"$document\"];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 15 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _angularFix = __webpack_require__(1);\n\t\n\tvar _angularFix2 = _interopRequireDefault(_angularFix);\n\t\n\tvar _otherUtils = __webpack_require__(2);\n\t\n\texports['default'] = addFormlyNgModelAttrsManipulator;\n\t\n\t// @ngInject\n\tfunction addFormlyNgModelAttrsManipulator(formlyConfig, $interpolate) {\n\t if (formlyConfig.extras.disableNgModelAttrsManipulator) {\n\t return;\n\t }\n\t formlyConfig.templateManipulators.preWrapper.push(ngModelAttrsManipulator);\n\t\n\t function ngModelAttrsManipulator(template, options, scope) {\n\t var node = document.createElement('div');\n\t var skip = options.extras && options.extras.skipNgModelAttrsManipulator;\n\t if (skip === true) {\n\t return template;\n\t }\n\t node.innerHTML = template;\n\t\n\t var modelNodes = getNgModelNodes(node, skip);\n\t if (!modelNodes || !modelNodes.length) {\n\t return template;\n\t }\n\t\n\t addIfNotPresent(modelNodes, 'id', scope.id);\n\t addIfNotPresent(modelNodes, 'name', scope.name || scope.id);\n\t\n\t addValidation();\n\t alterNgModelAttr();\n\t addModelOptions();\n\t addTemplateOptionsAttrs();\n\t addNgModelElAttrs();\n\t\n\t return node.innerHTML;\n\t\n\t function addValidation() {\n\t if (_angularFix2['default'].isDefined(options.validators) || _angularFix2['default'].isDefined(options.validation.messages)) {\n\t addIfNotPresent(modelNodes, 'formly-custom-validation', '');\n\t }\n\t }\n\t\n\t function alterNgModelAttr() {\n\t if (isPropertyAccessor(options.key)) {\n\t addRegardlessOfPresence(modelNodes, 'ng-model', 'model.' + options.key);\n\t }\n\t }\n\t\n\t function addModelOptions() {\n\t if (_angularFix2['default'].isDefined(options.modelOptions)) {\n\t addIfNotPresent(modelNodes, 'ng-model-options', 'options.modelOptions');\n\t if (options.modelOptions.getterSetter) {\n\t addRegardlessOfPresence(modelNodes, 'ng-model', 'options.value');\n\t }\n\t }\n\t }\n\t\n\t function addTemplateOptionsAttrs() {\n\t if (!options.templateOptions && !options.expressionProperties) {\n\t // no need to run these if there are no templateOptions or expressionProperties\n\t return;\n\t }\n\t var to = options.templateOptions || {};\n\t var ep = options.expressionProperties || {};\n\t\n\t var ngModelAttributes = getBuiltInAttributes();\n\t\n\t // extend with the user's specifications winning\n\t _angularFix2['default'].extend(ngModelAttributes, options.ngModelAttrs);\n\t\n\t // Feel free to make this more simple :-)\n\t _angularFix2['default'].forEach(ngModelAttributes, function (val, name) {\n\t /* eslint complexity:[2, 14] */\n\t var attrVal = undefined,\n\t attrName = undefined;\n\t var ref = 'options.templateOptions[\\'' + name + '\\']';\n\t var toVal = to[name];\n\t var epVal = getEpValue(ep, name);\n\t\n\t var inTo = _angularFix2['default'].isDefined(toVal);\n\t var inEp = _angularFix2['default'].isDefined(epVal);\n\t if (val.value) {\n\t // I realize this looks backwards, but it's right, trust me...\n\t attrName = val.value;\n\t attrVal = name;\n\t } else if (val.statement && inTo) {\n\t attrName = val.statement;\n\t if (_angularFix2['default'].isString(to[name])) {\n\t attrVal = '$eval(' + ref + ')';\n\t } else if (_angularFix2['default'].isFunction(to[name])) {\n\t attrVal = ref + '(model[options.key], options, this, $event)';\n\t } else {\n\t throw new Error('options.templateOptions.' + name + ' must be a string or function: ' + JSON.stringify(options));\n\t }\n\t } else if (val.bound && inEp) {\n\t attrName = val.bound;\n\t attrVal = ref;\n\t } else if ((val.attribute || val.boolean) && inEp) {\n\t attrName = val.attribute || val.boolean;\n\t attrVal = '' + $interpolate.startSymbol() + ref + $interpolate.endSymbol();\n\t } else if (val.attribute && inTo) {\n\t attrName = val.attribute;\n\t attrVal = toVal;\n\t } else if (val.boolean) {\n\t if (inTo && !inEp && toVal) {\n\t attrName = val.boolean;\n\t attrVal = true;\n\t } else {\n\t /* eslint no-empty:0 */\n\t // empty to illustrate that a boolean will not be added via val.bound\n\t // if you want it added via val.bound, then put it in expressionProperties\n\t }\n\t } else if (val.bound && inTo) {\n\t attrName = val.bound;\n\t attrVal = ref;\n\t }\n\t\n\t if (_angularFix2['default'].isDefined(attrName) && _angularFix2['default'].isDefined(attrVal)) {\n\t addIfNotPresent(modelNodes, attrName, attrVal);\n\t }\n\t });\n\t }\n\t\n\t function addNgModelElAttrs() {\n\t _angularFix2['default'].forEach(options.ngModelElAttrs, function (val, name) {\n\t addRegardlessOfPresence(modelNodes, name, val);\n\t });\n\t }\n\t }\n\t\n\t // Utility functions\n\t function getNgModelNodes(node, skip) {\n\t var selectorNot = _angularFix2['default'].isString(skip) ? ':not(' + skip + ')' : '';\n\t var skipNot = ':not([formly-skip-ng-model-attrs-manipulator])';\n\t var query = '[ng-model]' + selectorNot + skipNot + ', [data-ng-model]' + selectorNot + skipNot;\n\t try {\n\t return node.querySelectorAll(query);\n\t } catch (e) {\n\t //this code is needed for IE8, as it does not support the CSS3 ':not' selector\n\t //it should be removed when IE8 support is dropped\n\t return getNgModelNodesFallback(node, skip);\n\t }\n\t }\n\t\n\t function getNgModelNodesFallback(node, skip) {\n\t var allNgModelNodes = node.querySelectorAll('[ng-model], [data-ng-model]');\n\t var matchingNgModelNodes = [];\n\t\n\t //make sure this array is compatible with NodeList type by adding an 'item' function\n\t matchingNgModelNodes.item = function (i) {\n\t return this[i];\n\t };\n\t\n\t for (var i = 0; i < allNgModelNodes.length; i++) {\n\t var ngModelNode = allNgModelNodes[i];\n\t if (!ngModelNode.hasAttribute('formly-skip-ng-model-attrs-manipulator') && !(_angularFix2['default'].isString(skip) && nodeMatches(ngModelNode, skip))) {\n\t matchingNgModelNodes.push(ngModelNode);\n\t }\n\t }\n\t\n\t return matchingNgModelNodes;\n\t }\n\t\n\t function nodeMatches(node, selector) {\n\t var div = document.createElement('div');\n\t div.innerHTML = node.outerHTML;\n\t return div.querySelector(selector);\n\t }\n\t\n\t function getBuiltInAttributes() {\n\t var ngModelAttributes = {\n\t focus: {\n\t attribute: 'formly-focus'\n\t }\n\t };\n\t var boundOnly = [];\n\t var bothBooleanAndBound = ['required', 'disabled'];\n\t var bothAttributeAndBound = ['pattern', 'minlength'];\n\t var statementOnly = ['change', 'keydown', 'keyup', 'keypress', 'click', 'focus', 'blur'];\n\t var attributeOnly = ['placeholder', 'min', 'max', 'step', 'tabindex', 'type'];\n\t if (formlyConfig.extras.ngModelAttrsManipulatorPreferUnbound) {\n\t bothAttributeAndBound.push('maxlength');\n\t } else {\n\t boundOnly.push('maxlength');\n\t }\n\t\n\t _angularFix2['default'].forEach(boundOnly, function (item) {\n\t ngModelAttributes[item] = { bound: 'ng-' + item };\n\t });\n\t\n\t _angularFix2['default'].forEach(bothBooleanAndBound, function (item) {\n\t ngModelAttributes[item] = { boolean: item, bound: 'ng-' + item };\n\t });\n\t\n\t _angularFix2['default'].forEach(bothAttributeAndBound, function (item) {\n\t ngModelAttributes[item] = { attribute: item, bound: 'ng-' + item };\n\t });\n\t\n\t _angularFix2['default'].forEach(statementOnly, function (item) {\n\t var propName = 'on' + item.substr(0, 1).toUpperCase() + item.substr(1);\n\t ngModelAttributes[propName] = { statement: 'ng-' + item };\n\t });\n\t\n\t _angularFix2['default'].forEach(attributeOnly, function (item) {\n\t ngModelAttributes[item] = { attribute: item };\n\t });\n\t return ngModelAttributes;\n\t }\n\t\n\t function getEpValue(ep, name) {\n\t return ep['templateOptions.' + name] || ep['templateOptions[\\'' + name + '\\']'] || ep['templateOptions[\"' + name + '\"]'];\n\t }\n\t\n\t function addIfNotPresent(nodes, attr, val) {\n\t _angularFix2['default'].forEach(nodes, function (node) {\n\t if (!node.getAttribute(attr)) {\n\t node.setAttribute(attr, val);\n\t }\n\t });\n\t }\n\t\n\t function addRegardlessOfPresence(nodes, attr, val) {\n\t _angularFix2['default'].forEach(nodes, function (node) {\n\t node.setAttribute(attr, val);\n\t });\n\t }\n\t\n\t function isPropertyAccessor(key) {\n\t return (0, _otherUtils.contains)(key, '.') || (0, _otherUtils.contains)(key, '[') && (0, _otherUtils.contains)(key, ']');\n\t }\n\t}\n\taddFormlyNgModelAttrsManipulator.$inject = [\"formlyConfig\", \"$interpolate\"];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 16 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _otherUtils = __webpack_require__(2);\n\t\n\tvar _otherUtils2 = _interopRequireDefault(_otherUtils);\n\t\n\texports['default'] = formlyUtil;\n\t\n\t// @ngInject\n\tfunction formlyUtil() {\n\t return _otherUtils2['default'];\n\t}\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 17 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\t\n\texports['default'] = formlyWarn;\n\t\n\t// @ngInject\n\tfunction formlyWarn(formlyConfig, formlyErrorAndWarningsUrlPrefix, $log) {\n\t return function warn() {\n\t if (!formlyConfig.disableWarnings) {\n\t var args = Array.prototype.slice.call(arguments);\n\t var warnInfoSlug = args.shift();\n\t args.unshift('Formly Warning:');\n\t args.push('' + formlyErrorAndWarningsUrlPrefix + warnInfoSlug);\n\t $log.warn.apply($log, _toConsumableArray(args));\n\t }\n\t };\n\t}\n\tformlyWarn.$inject = [\"formlyConfig\", \"formlyErrorAndWarningsUrlPrefix\", \"$log\"];\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 18 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_18__;\n\n/***/ }\n/******/ ])\n});\n;\n\n\n/** WEBPACK FOOTER **\n ** dist/formly.min.js\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 539c6f6fd2eef6d95854\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _indexCommon = require('./index.common');\n\nvar _indexCommon2 = _interopRequireDefault(_indexCommon);\n\nexports['default'] = _indexCommon2['default'];\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./index.js\n **/","import index from './index.common'\nexport default index\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./index.js\n **/","// some versions of angular don't export the angular module properly,\n// so we get it from window in this case.\n'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\nvar angular = require('angular');\n\n/* istanbul ignore next */\nif (!angular.version) {\n angular = window.angular;\n}\nexports['default'] = angular;\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./angular-fix/index.js\n **/","// some versions of angular don't export the angular module properly,\n// so we get it from window in this case.\nlet angular = require('angular')\n\n/* istanbul ignore next */\nif (!angular.version) {\n angular = window.angular\n}\nexport default angular\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./angular-fix/index.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nexports['default'] = {\n containsSelector: containsSelector, containsSpecialChar: containsSpecialChar, formlyEval: formlyEval, getFieldId: getFieldId, reverseDeepMerge: reverseDeepMerge, findByNodeName: findByNodeName,\n arrayify: arrayify, extendFunction: extendFunction, extendArray: extendArray, startsWith: startsWith, contains: contains\n};\n\nfunction containsSelector(string) {\n return containsSpecialChar(string, '.') || containsSpecialChar(string, '[') && containsSpecialChar(string, ']');\n}\n\nfunction containsSpecialChar(a, b) {\n if (!a || !a.indexOf) {\n return false;\n }\n return a.indexOf(b) !== -1;\n}\n\nfunction formlyEval(scope, expression, $modelValue, $viewValue, extraLocals) {\n if (_angularFix2['default'].isFunction(expression)) {\n return expression($viewValue, $modelValue, scope, extraLocals);\n } else {\n return scope.$eval(expression, _angularFix2['default'].extend({ $viewValue: $viewValue, $modelValue: $modelValue }, extraLocals));\n }\n}\n\nfunction getFieldId(formId, options, index) {\n if (options.id) {\n return options.id;\n }\n var type = options.type;\n if (!type && options.template) {\n type = 'template';\n } else if (!type && options.templateUrl) {\n type = 'templateUrl';\n }\n\n return [formId, type, options.key, index].join('_');\n}\n\nfunction reverseDeepMerge(dest) {\n _angularFix2['default'].forEach(arguments, function (src, index) {\n if (!index) {\n return;\n }\n _angularFix2['default'].forEach(src, function (val, prop) {\n if (!_angularFix2['default'].isDefined(dest[prop])) {\n dest[prop] = _angularFix2['default'].copy(val);\n } else if (objAndSameType(dest[prop], val)) {\n reverseDeepMerge(dest[prop], val);\n }\n });\n });\n return dest;\n}\n\nfunction objAndSameType(obj1, obj2) {\n return _angularFix2['default'].isObject(obj1) && _angularFix2['default'].isObject(obj2) && Object.getPrototypeOf(obj1) === Object.getPrototypeOf(obj2);\n}\n\n// recurse down a node tree to find a node with matching nodeName, for custom tags jQuery.find doesn't work in IE8\nfunction findByNodeName(el, nodeName) {\n if (!el.prop) {\n // not a jQuery or jqLite object -> wrap it\n el = _angularFix2['default'].element(el);\n }\n\n if (el.prop('nodeName') === nodeName.toUpperCase()) {\n return el;\n }\n\n var c = el.children();\n for (var i = 0; c && i < c.length; i++) {\n var node = findByNodeName(c[i], nodeName);\n if (node) {\n return node;\n }\n }\n}\n\nfunction arrayify(obj) {\n if (obj && !_angularFix2['default'].isArray(obj)) {\n obj = [obj];\n } else if (!obj) {\n obj = [];\n }\n return obj;\n}\n\nfunction extendFunction() {\n for (var _len = arguments.length, fns = Array(_len), _key = 0; _key < _len; _key++) {\n fns[_key] = arguments[_key];\n }\n\n return function extendedFunction() {\n var args = arguments;\n fns.forEach(function (fn) {\n return fn.apply(null, args);\n });\n };\n}\n\nfunction extendArray(primary, secondary, property) {\n if (property) {\n primary = primary[property];\n secondary = secondary[property];\n }\n if (secondary && primary) {\n _angularFix2['default'].forEach(secondary, function (item) {\n if (primary.indexOf(item) === -1) {\n primary.push(item);\n }\n });\n return primary;\n } else if (secondary) {\n return secondary;\n } else {\n return primary;\n }\n}\n\nfunction startsWith(str, search) {\n if (_angularFix2['default'].isString(str) && _angularFix2['default'].isString(search)) {\n return str.length >= search.length && str.substring(0, search.length) === search;\n } else {\n return false;\n }\n}\n\nfunction contains(str, search) {\n if (_angularFix2['default'].isString(str) && _angularFix2['default'].isString(search)) {\n return str.length >= search.length && str.indexOf(search) !== -1;\n } else {\n return false;\n }\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./other/utils.js\n **/","import angular from 'angular-fix'\n\nexport default {\n containsSelector, containsSpecialChar, formlyEval, getFieldId, reverseDeepMerge, findByNodeName,\n arrayify, extendFunction, extendArray, startsWith, contains,\n}\n\nfunction containsSelector(string) {\n return containsSpecialChar(string, '.') || (containsSpecialChar(string, '[') && containsSpecialChar(string, ']'))\n}\n\nfunction containsSpecialChar(a, b) {\n if (!a || !a.indexOf) {\n return false\n }\n return a.indexOf(b) !== -1\n}\n\n\nfunction formlyEval(scope, expression, $modelValue, $viewValue, extraLocals) {\n if (angular.isFunction(expression)) {\n return expression($viewValue, $modelValue, scope, extraLocals)\n } else {\n return scope.$eval(expression, angular.extend({$viewValue, $modelValue}, extraLocals))\n }\n}\n\nfunction getFieldId(formId, options, index) {\n if (options.id) {\n return options.id\n }\n let type = options.type\n if (!type && options.template) {\n type = 'template'\n } else if (!type && options.templateUrl) {\n type = 'templateUrl'\n }\n\n return [formId, type, options.key, index].join('_')\n}\n\n\nfunction reverseDeepMerge(dest) {\n angular.forEach(arguments, (src, index) => {\n if (!index) {\n return\n }\n angular.forEach(src, (val, prop) => {\n if (!angular.isDefined(dest[prop])) {\n dest[prop] = angular.copy(val)\n } else if (objAndSameType(dest[prop], val)) {\n reverseDeepMerge(dest[prop], val)\n }\n })\n })\n return dest\n}\n\nfunction objAndSameType(obj1, obj2) {\n return angular.isObject(obj1) && angular.isObject(obj2) &&\n Object.getPrototypeOf(obj1) === Object.getPrototypeOf(obj2)\n}\n\n// recurse down a node tree to find a node with matching nodeName, for custom tags jQuery.find doesn't work in IE8\nfunction findByNodeName(el, nodeName) {\n if (!el.prop) { // not a jQuery or jqLite object -> wrap it\n el = angular.element(el)\n }\n\n if (el.prop('nodeName') === nodeName.toUpperCase()) {\n return el\n }\n\n const c = el.children()\n for (let i = 0; c && i < c.length; i++) {\n const node = findByNodeName(c[i], nodeName)\n if (node) {\n return node\n }\n }\n}\n\n\nfunction arrayify(obj) {\n if (obj && !angular.isArray(obj)) {\n obj = [obj]\n } else if (!obj) {\n obj = []\n }\n return obj\n}\n\n\nfunction extendFunction(...fns) {\n return function extendedFunction() {\n const args = arguments\n fns.forEach(fn => fn.apply(null, args))\n }\n}\n\nfunction extendArray(primary, secondary, property) {\n if (property) {\n primary = primary[property]\n secondary = secondary[property]\n }\n if (secondary && primary) {\n angular.forEach(secondary, function(item) {\n if (primary.indexOf(item) === -1) {\n primary.push(item)\n }\n })\n return primary\n } else if (secondary) {\n return secondary\n } else {\n return primary\n }\n}\n\nfunction startsWith(str, search) {\n if (angular.isString(str) && angular.isString(search)) {\n return str.length >= search.length && str.substring(0, search.length) === search\n } else {\n return false\n }\n}\n\nfunction contains(str, search) {\n if (angular.isString(str) && angular.isString(search)) {\n return str.length >= search.length && str.indexOf(search) !== -1\n } else {\n return false\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./other/utils.js\n **/","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = \"https://github.com/formly-js/angular-formly/blob/\" + VERSION + \"/other/ERRORS_AND_WARNINGS.md#\";\nmodule.exports = exports[\"default\"];\n\n\n/** WEBPACK FOOTER **\n ** ./other/docsBaseUrl.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_4__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"root\":\"apiCheck\",\"amd\":\"api-check\",\"commonjs2\":\"api-check\",\"commonjs\":\"api-check\"}\n ** module id = 4\n ** module chunks = 0\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nexports['default'] = formlyCustomValidation;\n\n// @ngInject\nfunction formlyCustomValidation(formlyUtil) {\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function formlyCustomValidationLink(scope, el, attrs, ctrl) {\n var opts = scope.options;\n opts.validation.messages = opts.validation.messages || {};\n _angularFix2['default'].forEach(opts.validation.messages, function (message, key) {\n opts.validation.messages[key] = function () {\n return formlyUtil.formlyEval(scope, message, ctrl.$modelValue, ctrl.$viewValue);\n };\n });\n\n var useNewValidatorsApi = ctrl.hasOwnProperty('$validators') && !attrs.hasOwnProperty('useParsers');\n _angularFix2['default'].forEach(opts.validators, _angularFix2['default'].bind(null, addValidatorToPipeline, false));\n _angularFix2['default'].forEach(opts.asyncValidators, _angularFix2['default'].bind(null, addValidatorToPipeline, true));\n\n function addValidatorToPipeline(isAsync, validator, name) {\n setupMessage(validator, name);\n validator = _angularFix2['default'].isObject(validator) ? validator.expression : validator;\n if (useNewValidatorsApi) {\n setupWithValidators(validator, name, isAsync);\n } else {\n setupWithParsers(validator, name, isAsync);\n }\n }\n\n function setupMessage(validator, name) {\n var message = validator.message;\n if (message) {\n opts.validation.messages[name] = function () {\n return formlyUtil.formlyEval(scope, message, ctrl.$modelValue, ctrl.$viewValue);\n };\n }\n }\n\n function setupWithValidators(validator, name, isAsync) {\n var validatorCollection = isAsync ? '$asyncValidators' : '$validators';\n\n ctrl[validatorCollection][name] = function evalValidity(modelValue, viewValue) {\n return formlyUtil.formlyEval(scope, validator, modelValue, viewValue);\n };\n }\n\n function setupWithParsers(validator, name, isAsync) {\n var inFlightValidator = undefined;\n ctrl.$parsers.unshift(function evalValidityOfParser(viewValue) {\n var isValid = formlyUtil.formlyEval(scope, validator, ctrl.$modelValue, viewValue);\n if (isAsync) {\n ctrl.$pending = ctrl.$pending || {};\n ctrl.$pending[name] = true;\n inFlightValidator = isValid;\n isValid.then(function () {\n if (inFlightValidator === isValid) {\n ctrl.$setValidity(name, true);\n }\n })['catch'](function () {\n if (inFlightValidator === isValid) {\n ctrl.$setValidity(name, false);\n }\n })['finally'](function () {\n var $pending = ctrl.$pending || {};\n if (Object.keys($pending).length === 1) {\n delete ctrl.$pending;\n } else {\n delete ctrl.$pending[name];\n }\n });\n } else {\n ctrl.$setValidity(name, isValid);\n }\n return viewValue;\n });\n }\n }\n };\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./directives/formly-custom-validation.js\n **/","import angular from 'angular-fix'\nexport default formlyCustomValidation\n\n// @ngInject\nfunction formlyCustomValidation(formlyUtil) {\n return {\n restrict: 'A',\n require: 'ngModel',\n link: function formlyCustomValidationLink(scope, el, attrs, ctrl) {\n const opts = scope.options\n opts.validation.messages = opts.validation.messages || {}\n angular.forEach(opts.validation.messages, (message, key) => {\n opts.validation.messages[key] = () => {\n return formlyUtil.formlyEval(scope, message, ctrl.$modelValue, ctrl.$viewValue)\n }\n })\n\n\n const useNewValidatorsApi = ctrl.hasOwnProperty('$validators') && !attrs.hasOwnProperty('useParsers')\n angular.forEach(opts.validators, angular.bind(null, addValidatorToPipeline, false))\n angular.forEach(opts.asyncValidators, angular.bind(null, addValidatorToPipeline, true))\n\n function addValidatorToPipeline(isAsync, validator, name) {\n setupMessage(validator, name)\n validator = angular.isObject(validator) ? validator.expression : validator\n if (useNewValidatorsApi) {\n setupWithValidators(validator, name, isAsync)\n } else {\n setupWithParsers(validator, name, isAsync)\n }\n }\n\n function setupMessage(validator, name) {\n const message = validator.message\n if (message) {\n opts.validation.messages[name] = () => {\n return formlyUtil.formlyEval(scope, message, ctrl.$modelValue, ctrl.$viewValue)\n }\n }\n }\n\n function setupWithValidators(validator, name, isAsync) {\n const validatorCollection = isAsync ? '$asyncValidators' : '$validators'\n\n ctrl[validatorCollection][name] = function evalValidity(modelValue, viewValue) {\n return formlyUtil.formlyEval(scope, validator, modelValue, viewValue)\n }\n }\n\n function setupWithParsers(validator, name, isAsync) {\n let inFlightValidator\n ctrl.$parsers.unshift(function evalValidityOfParser(viewValue) {\n const isValid = formlyUtil.formlyEval(scope, validator, ctrl.$modelValue, viewValue)\n if (isAsync) {\n ctrl.$pending = ctrl.$pending || {}\n ctrl.$pending[name] = true\n inFlightValidator = isValid\n isValid.then(() => {\n if (inFlightValidator === isValid) {\n ctrl.$setValidity(name, true)\n }\n }).catch(() => {\n if (inFlightValidator === isValid) {\n ctrl.$setValidity(name, false)\n }\n }).finally(() => {\n const $pending = ctrl.$pending || {}\n if (Object.keys($pending).length === 1) {\n delete ctrl.$pending\n } else {\n delete ctrl.$pending[name]\n }\n })\n } else {\n ctrl.$setValidity(name, isValid)\n }\n return viewValue\n })\n }\n },\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./directives/formly-custom-validation.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nvar _apiCheck = require('api-check');\n\nvar _apiCheck2 = _interopRequireDefault(_apiCheck);\n\nexports['default'] = formlyField;\n\n/**\n * @ngdoc directive\n * @name formlyField\n * @restrict AE\n */\n// @ngInject\nfunction formlyField($http, $q, $compile, $templateCache, $interpolate, formlyConfig, formlyApiCheck, formlyUtil, formlyUsability, formlyWarn) {\n var arrayify = formlyUtil.arrayify;\n\n return {\n restrict: 'AE',\n transclude: true,\n require: '?^formlyForm',\n scope: {\n options: '=',\n model: '=',\n originalModel: '=?',\n formId: '@', // TODO remove formId in a breaking release\n index: '=?',\n fields: '=?',\n formState: '=?',\n formOptions: '=?',\n form: '=?' },\n // TODO require form in a breaking release\n controller: FormlyFieldController,\n link: fieldLink\n };\n\n // @ngInject\n function FormlyFieldController($scope, $timeout, $parse, $controller, formlyValidationMessages) {\n /* eslint max-statements:[2, 34] */\n if ($scope.options.fieldGroup) {\n setupFieldGroup();\n return;\n }\n\n var fieldType = getFieldType($scope.options);\n simplifyLife($scope.options);\n mergeFieldOptionsWithTypeDefaults($scope.options, fieldType);\n extendOptionsWithDefaults($scope.options, $scope.index);\n checkApi($scope.options);\n // set field id to link labels and fields\n\n // initalization\n setFieldIdAndName();\n setDefaultValue();\n setInitialValue();\n runExpressions();\n watchExpressions();\n addValidationMessages($scope.options);\n invokeControllers($scope, $scope.options, fieldType);\n\n // function definitions\n function runExpressions() {\n // must run on next tick to make sure that the current value is correct.\n return $timeout(function runExpressionsOnNextTick() {\n var field = $scope.options;\n var currentValue = valueGetterSetter();\n _angularFix2['default'].forEach(field.expressionProperties, function runExpression(expression, prop) {\n var setter = $parse(prop).assign;\n var promise = $q.when(formlyUtil.formlyEval($scope, expression, currentValue, currentValue));\n promise.then(function setFieldValue(value) {\n setter(field, value);\n });\n });\n }, 0, false);\n }\n\n function watchExpressions() {\n if ($scope.formOptions.watchAllExpressions) {\n (function () {\n var field = $scope.options;\n var currentValue = valueGetterSetter();\n _angularFix2['default'].forEach(field.expressionProperties, function watchExpression(expression, prop) {\n var setter = $parse(prop).assign;\n $scope.$watch(function expressionPropertyWatcher() {\n return formlyUtil.formlyEval($scope, expression, currentValue, currentValue);\n }, function expressionPropertyListener(value) {\n setter(field, value);\n }, true);\n });\n })();\n }\n }\n\n function valueGetterSetter(newVal) {\n if (!$scope.model || !$scope.options.key) {\n return undefined;\n }\n if (_angularFix2['default'].isDefined(newVal)) {\n parseSet($scope.options.key, $scope.model, newVal);\n }\n return parseGet($scope.options.key, $scope.model);\n }\n\n function shouldNotUseParseKey(key) {\n return _angularFix2['default'].isNumber(key) || !formlyUtil.containsSelector(key);\n }\n\n function parseSet(key, model, newVal) {\n // If either of these are null/undefined then just return undefined\n if (!key || !model) {\n return;\n }\n // If we are working with a number then $parse wont work, default back to the old way for now\n if (shouldNotUseParseKey(key)) {\n // TODO: Fix this so we can get several levels instead of just one with properties that are numeric\n model[key] = newVal;\n } else {\n var setter = $parse($scope.options.key).assign;\n if (setter) {\n setter($scope.model, newVal);\n }\n }\n }\n\n function parseGet(key, model) {\n // If either of these are null/undefined then just return undefined\n if (!key || !model) {\n return undefined;\n }\n\n // If we are working with a number then $parse wont work, default back to the old way for now\n if (shouldNotUseParseKey(key)) {\n // TODO: Fix this so we can get several levels instead of just one with properties that are numeric\n return model[key];\n } else {\n return $parse(key)(model);\n }\n }\n\n function simplifyLife(options) {\n // add a few empty objects (if they don't already exist) so you don't have to undefined check everywhere\n formlyUtil.reverseDeepMerge(options, {\n originalModel: options.model,\n extras: {},\n data: {},\n templateOptions: {},\n validation: {}\n });\n // create $scope.to so template authors can reference to instead of $scope.options.templateOptions\n $scope.to = $scope.options.templateOptions;\n $scope.formOptions = $scope.formOptions || {};\n }\n\n function setFieldIdAndName() {\n if (_angularFix2['default'].isFunction(formlyConfig.extras.getFieldId)) {\n $scope.id = formlyConfig.extras.getFieldId($scope.options, $scope.model, $scope);\n } else {\n var formName = $scope.form && $scope.form.$name || $scope.formId;\n $scope.id = formlyUtil.getFieldId(formName, $scope.options, $scope.index);\n }\n $scope.options.id = $scope.id;\n $scope.name = $scope.options.name || $scope.options.id;\n $scope.options.name = $scope.name;\n }\n\n function setDefaultValue() {\n if (_angularFix2['default'].isDefined($scope.options.defaultValue) && !_angularFix2['default'].isDefined(parseGet($scope.options.key, $scope.model))) {\n parseSet($scope.options.key, $scope.model, $scope.options.defaultValue);\n }\n }\n\n function setInitialValue() {\n $scope.options.initialValue = $scope.model && parseGet($scope.options.key, $scope.model);\n }\n\n function mergeFieldOptionsWithTypeDefaults(options, type) {\n if (type) {\n mergeOptions(options, type.defaultOptions);\n }\n var properOrder = arrayify(options.optionsTypes).reverse(); // so the right things are overridden\n _angularFix2['default'].forEach(properOrder, function (typeName) {\n mergeOptions(options, formlyConfig.getType(typeName, true, options).defaultOptions);\n });\n }\n\n function mergeOptions(options, extraOptions) {\n if (extraOptions) {\n if (_angularFix2['default'].isFunction(extraOptions)) {\n extraOptions = extraOptions(options, $scope);\n }\n formlyUtil.reverseDeepMerge(options, extraOptions);\n }\n }\n\n function extendOptionsWithDefaults(options, index) {\n var key = options.key || index || 0;\n _angularFix2['default'].extend(options, {\n // attach the key in case the formly-field directive is used directly\n key: key,\n value: options.value || valueGetterSetter,\n runExpressions: runExpressions,\n resetModel: resetModel,\n updateInitialValue: updateInitialValue\n });\n }\n\n function resetModel() {\n parseSet($scope.options.key, $scope.model, $scope.options.initialValue);\n if ($scope.options.formControl) {\n if (_angularFix2['default'].isArray($scope.options.formControl)) {\n _angularFix2['default'].forEach($scope.options.formControl, function (formControl) {\n resetFormControl(formControl, true);\n });\n } else {\n resetFormControl($scope.options.formControl);\n }\n }\n if ($scope.form) {\n $scope.form.$setUntouched && $scope.form.$setUntouched();\n $scope.form.$setPristine();\n }\n }\n\n function resetFormControl(formControl, isMultiNgModel) {\n if (!isMultiNgModel) {\n formControl.$setViewValue(parseGet($scope.options.key, $scope.model));\n }\n\n formControl.$render();\n formControl.$setUntouched && formControl.$setUntouched();\n formControl.$setPristine();\n\n // To prevent breaking change requiring a digest to reset $viewModel\n if (!$scope.$root.$$phase) {\n $scope.$digest();\n }\n }\n\n function updateInitialValue() {\n $scope.options.initialValue = parseGet($scope.options.key, $scope.model);\n }\n\n function addValidationMessages(options) {\n options.validation.messages = options.validation.messages || {};\n _angularFix2['default'].forEach(formlyValidationMessages.messages, function createFunctionForMessage(expression, name) {\n if (!options.validation.messages[name]) {\n options.validation.messages[name] = function evaluateMessage(viewValue, modelValue, scope) {\n return formlyUtil.formlyEval(scope, expression, modelValue, viewValue);\n };\n }\n });\n }\n\n function invokeControllers(scope) {\n var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];\n var type = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];\n\n _angularFix2['default'].forEach([type.controller, options.controller], function (controller) {\n if (controller) {\n $controller(controller, { $scope: scope });\n }\n });\n }\n\n function setupFieldGroup() {\n $scope.options.options = $scope.options.options || {};\n $scope.options.options.formState = $scope.formState;\n $scope.to = $scope.options.templateOptions;\n }\n }\n\n // link function\n function fieldLink(scope, el, attrs, formlyFormCtrl) {\n if (scope.options.fieldGroup) {\n setFieldGroupTemplate();\n return;\n }\n\n // watch the field model (if exists) if there is no parent formly-form directive (that would watch it instead)\n if (!formlyFormCtrl && scope.options.model) {\n scope.$watch('options.model', function () {\n return scope.options.runExpressions();\n }, true);\n }\n\n addAttributes();\n addClasses();\n\n var type = getFieldType(scope.options);\n var args = arguments;\n var thusly = this;\n var fieldCount = 0;\n var fieldManipulators = getManipulators(scope.options, scope.formOptions);\n getFieldTemplate(scope.options).then(runManipulators(fieldManipulators.preWrapper)).then(transcludeInWrappers(scope.options, scope.formOptions)).then(runManipulators(fieldManipulators.postWrapper)).then(setElementTemplate).then(watchFormControl).then(callLinkFunctions)['catch'](function (error) {\n formlyWarn('there-was-a-problem-setting-the-template-for-this-field', 'There was a problem setting the template for this field ', scope.options, error);\n });\n\n function setFieldGroupTemplate() {\n checkFieldGroupApi(scope.options);\n el.addClass('formly-field-group');\n var extraAttributes = '';\n if (scope.options.elementAttributes) {\n extraAttributes = Object.keys(scope.options.elementAttributes).map(function (key) {\n return key + '=\"' + scope.options.elementAttributes[key] + '\"';\n }).join(' ');\n }\n var modelValue = 'model';\n scope.options.form = scope.form;\n if (scope.options.key) {\n modelValue = 'model[\\'' + scope.options.key + '\\']';\n }\n getTemplate('\\n \\n \\n ').then(transcludeInWrappers(scope.options, scope.formOptions)).then(setElementTemplate);\n }\n\n function addAttributes() {\n if (scope.options.elementAttributes) {\n el.attr(scope.options.elementAttributes);\n }\n }\n\n function addClasses() {\n if (scope.options.className) {\n el.addClass(scope.options.className);\n }\n if (scope.options.type) {\n el.addClass('formly-field-' + scope.options.type);\n }\n }\n\n function setElementTemplate(templateString) {\n el.html(asHtml(templateString));\n $compile(el.contents())(scope);\n return templateString;\n }\n\n function watchFormControl(templateString) {\n var stopWatchingShowError = _angularFix2['default'].noop;\n if (scope.options.noFormControl) {\n return;\n }\n var templateEl = _angularFix2['default'].element('' + templateString + '
');\n var ngModelNodes = templateEl[0].querySelectorAll('[ng-model],[data-ng-model]');\n\n if (ngModelNodes.length) {\n _angularFix2['default'].forEach(ngModelNodes, function (ngModelNode) {\n fieldCount++;\n watchFieldNameOrExistence(ngModelNode.getAttribute('name'));\n });\n }\n\n function watchFieldNameOrExistence(name) {\n var nameExpressionRegex = /\\{\\{(.*?)}}/;\n var nameExpression = nameExpressionRegex.exec(name);\n if (nameExpression) {\n name = $interpolate(name)(scope);\n }\n watchFieldExistence(name);\n }\n\n function watchFieldExistence(name) {\n scope.$watch('form[\"' + name + '\"]', function formControlChange(formControl) {\n if (formControl) {\n if (fieldCount > 1) {\n if (!scope.options.formControl) {\n scope.options.formControl = [];\n }\n scope.options.formControl.push(formControl);\n } else {\n scope.options.formControl = formControl;\n }\n scope.fc = scope.options.formControl; // shortcut for template authors\n stopWatchingShowError();\n addShowMessagesWatcher();\n addParsers();\n addFormatters();\n }\n });\n }\n\n function addShowMessagesWatcher() {\n stopWatchingShowError = scope.$watch(function watchShowValidationChange() {\n var customExpression = formlyConfig.extras.errorExistsAndShouldBeVisibleExpression;\n var options = scope.options;\n var formControls = arrayify(scope.fc);\n if (!formControls.some(function (fc) {\n return fc.$invalid;\n })) {\n return false;\n } else if (typeof options.validation.show === 'boolean') {\n return options.validation.show;\n } else if (customExpression) {\n return formControls.some(function (fc) {\n return formlyUtil.formlyEval(scope, customExpression, fc.$modelValue, fc.$viewValue);\n });\n } else {\n return formControls.some(function (fc) {\n var noTouchedButDirty = _angularFix2['default'].isUndefined(fc.$touched) && fc.$dirty;\n return fc.$touched || noTouchedButDirty;\n });\n }\n }, function onShowValidationChange(show) {\n scope.options.validation.errorExistsAndShouldBeVisible = show;\n scope.showError = show; // shortcut for template authors\n });\n }\n\n function addParsers() {\n setParsersOrFormatters('parsers');\n }\n\n function addFormatters() {\n setParsersOrFormatters('formatters');\n var ctrl = scope.fc;\n var formWasPristine = scope.form.$pristine;\n if (scope.options.formatters) {\n (function () {\n var value = ctrl.$modelValue;\n ctrl.$formatters.forEach(function (formatter) {\n value = formatter(value);\n });\n\n ctrl.$setViewValue(value);\n ctrl.$render();\n ctrl.$setPristine();\n if (formWasPristine) {\n scope.form.$setPristine();\n }\n })();\n }\n }\n\n function setParsersOrFormatters(which) {\n var originalThingProp = 'originalParser';\n if (which === 'formatters') {\n originalThingProp = 'originalFormatter';\n }\n\n // init with type's parsers\n var things = getThingsFromType(type);\n\n // get optionsTypes things\n things = formlyUtil.extendArray(things, getThingsFromOptionsTypes(scope.options.optionsTypes));\n\n // get field's things\n things = formlyUtil.extendArray(things, scope.options[which]);\n\n // convert things into formlyExpression things\n _angularFix2['default'].forEach(things, function (thing, index) {\n things[index] = getFormlyExpressionThing(thing);\n });\n\n var ngModelCtrls = scope.fc;\n if (!_angularFix2['default'].isArray(ngModelCtrls)) {\n ngModelCtrls = [ngModelCtrls];\n }\n\n _angularFix2['default'].forEach(ngModelCtrls, function (ngModelCtrl) {\n var _ngModelCtrl;\n\n ngModelCtrl['$' + which] = (_ngModelCtrl = ngModelCtrl['$' + which]).concat.apply(_ngModelCtrl, _toConsumableArray(things));\n });\n\n function getThingsFromType(theType) {\n if (!theType) {\n return [];\n }\n if (_angularFix2['default'].isString(theType)) {\n theType = formlyConfig.getType(theType, true, scope.options);\n }\n var typeThings = [];\n\n // get things from parent\n if (theType['extends']) {\n typeThings = formlyUtil.extendArray(typeThings, getThingsFromType(theType['extends']));\n }\n\n // get own type's things\n typeThings = formlyUtil.extendArray(typeThings, getDefaultOptionsProperty(theType, which, []));\n\n // get things from optionsTypes\n typeThings = formlyUtil.extendArray(typeThings, getThingsFromOptionsTypes(getDefaultOptionsOptionsTypes(theType)));\n\n return typeThings;\n }\n\n function getThingsFromOptionsTypes() {\n var optionsTypes = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];\n\n var optionsTypesThings = [];\n _angularFix2['default'].forEach(_angularFix2['default'].copy(arrayify(optionsTypes)).reverse(), function (optionsTypeName) {\n optionsTypesThings = formlyUtil.extendArray(optionsTypesThings, getThingsFromType(optionsTypeName));\n });\n return optionsTypesThings;\n }\n\n function getFormlyExpressionThing(thing) {\n formlyExpressionParserOrFormatterFunction[originalThingProp] = thing;\n return formlyExpressionParserOrFormatterFunction;\n\n function formlyExpressionParserOrFormatterFunction($viewValue) {\n var $modelValue = scope.options.value();\n return formlyUtil.formlyEval(scope, thing, $modelValue, $viewValue);\n }\n }\n }\n }\n\n function callLinkFunctions() {\n if (type && type.link) {\n type.link.apply(thusly, args);\n }\n if (scope.options.link) {\n scope.options.link.apply(thusly, args);\n }\n }\n\n function runManipulators(manipulators) {\n return function runManipulatorsOnTemplate(templateToManipulate) {\n var chain = $q.when(templateToManipulate);\n _angularFix2['default'].forEach(manipulators, function (manipulator) {\n chain = chain.then(function (template) {\n return $q.when(manipulator(template, scope.options, scope)).then(function (newTemplate) {\n return _angularFix2['default'].isString(newTemplate) ? newTemplate : asHtml(newTemplate);\n });\n });\n });\n return chain;\n };\n }\n }\n\n // sort-of stateless util functions\n function asHtml(el) {\n var wrapper = _angularFix2['default'].element(' ');\n return wrapper.append(el).html();\n }\n\n function getFieldType(options) {\n return options.type && formlyConfig.getType(options.type);\n }\n\n function getManipulators(options, formOptions) {\n var preWrapper = [];\n var postWrapper = [];\n addManipulators(options.templateManipulators);\n addManipulators(formOptions.templateManipulators);\n addManipulators(formlyConfig.templateManipulators);\n return { preWrapper: preWrapper, postWrapper: postWrapper };\n\n function addManipulators(manipulators) {\n /* eslint-disable */ // it doesn't understand this :-(\n\n var _ref = manipulators || {};\n\n var _ref$preWrapper = _ref.preWrapper;\n var pre = _ref$preWrapper === undefined ? [] : _ref$preWrapper;\n var _ref$postWrapper = _ref.postWrapper;\n var post = _ref$postWrapper === undefined ? [] : _ref$postWrapper;\n\n preWrapper = preWrapper.concat(pre);\n postWrapper = postWrapper.concat(post);\n /* eslint-enable */\n }\n }\n\n function getFieldTemplate(options) {\n function fromOptionsOrType(key, fieldType) {\n if (_angularFix2['default'].isDefined(options[key])) {\n return options[key];\n } else if (fieldType && _angularFix2['default'].isDefined(fieldType[key])) {\n return fieldType[key];\n }\n }\n\n var type = formlyConfig.getType(options.type, true, options);\n var template = fromOptionsOrType('template', type);\n var templateUrl = fromOptionsOrType('templateUrl', type);\n if (_angularFix2['default'].isUndefined(template) && !templateUrl) {\n throw formlyUsability.getFieldError('type-type-has-no-template', 'Type \\'' + options.type + '\\' has no template. On element:', options);\n }\n\n return getTemplate(templateUrl || template, _angularFix2['default'].isUndefined(template), options);\n }\n\n function getTemplate(template, isUrl, options) {\n var templatePromise = undefined;\n if (_angularFix2['default'].isFunction(template)) {\n templatePromise = $q.when(template(options));\n } else {\n templatePromise = $q.when(template);\n }\n\n if (!isUrl) {\n return templatePromise;\n } else {\n var _ret3 = (function () {\n var httpOptions = { cache: $templateCache };\n return {\n v: templatePromise.then(function (url) {\n return $http.get(url, httpOptions);\n }).then(function (response) {\n return response.data;\n })['catch'](function handleErrorGettingATemplate(error) {\n formlyWarn('problem-loading-template-for-templateurl', 'Problem loading template for ' + template, error);\n })\n };\n })();\n\n if (typeof _ret3 === 'object') return _ret3.v;\n }\n }\n\n function transcludeInWrappers(options, formOptions) {\n var wrapper = getWrapperOption(options, formOptions);\n\n return function transcludeTemplate(template) {\n if (!wrapper.length) {\n return $q.when(template);\n }\n\n wrapper.forEach(function (aWrapper) {\n formlyUsability.checkWrapper(aWrapper, options);\n runApiCheck(aWrapper, options);\n });\n var promises = wrapper.map(function (w) {\n return getTemplate(w.template || w.templateUrl, !w.template);\n });\n return $q.all(promises).then(function (wrappersTemplates) {\n wrappersTemplates.forEach(function (wrapperTemplate, index) {\n formlyUsability.checkWrapperTemplate(wrapperTemplate, wrapper[index]);\n });\n wrappersTemplates.reverse(); // wrapper 0 is wrapped in wrapper 1 and so on...\n var totalWrapper = wrappersTemplates.shift();\n wrappersTemplates.forEach(function (wrapperTemplate) {\n totalWrapper = doTransclusion(totalWrapper, wrapperTemplate);\n });\n return doTransclusion(totalWrapper, template);\n });\n };\n }\n\n function doTransclusion(wrapper, template) {\n var superWrapper = _angularFix2['default'].element(' '); // this allows people not have to have a single root in wrappers\n superWrapper.append(wrapper);\n var transcludeEl = superWrapper.find('formly-transclude');\n if (!transcludeEl.length) {\n // try it using our custom find function\n transcludeEl = formlyUtil.findByNodeName(superWrapper, 'formly-transclude');\n }\n transcludeEl.replaceWith(template);\n return superWrapper.html();\n }\n\n function getWrapperOption(options, formOptions) {\n /* eslint complexity:[2, 6] */\n var wrapper = options.wrapper;\n // explicit null means no wrapper\n if (wrapper === null) {\n return [];\n }\n\n // nothing specified means use the default wrapper for the type\n if (!wrapper) {\n // get all wrappers that specify they apply to this type\n wrapper = arrayify(formlyConfig.getWrapperByType(options.type));\n } else {\n wrapper = arrayify(wrapper).map(formlyConfig.getWrapper);\n }\n\n // get all wrappers for that the type specified that it uses.\n var type = formlyConfig.getType(options.type, true, options);\n if (type && type.wrapper) {\n var typeWrappers = arrayify(type.wrapper).map(formlyConfig.getWrapper);\n wrapper = wrapper.concat(typeWrappers);\n }\n\n // add form wrappers\n if (formOptions.wrapper) {\n var formWrappers = arrayify(formOptions.wrapper).map(formlyConfig.getWrapper);\n wrapper = wrapper.concat(formWrappers);\n }\n\n // add the default wrapper last\n var defaultWrapper = formlyConfig.getWrapper();\n if (defaultWrapper) {\n wrapper.push(defaultWrapper);\n }\n return wrapper;\n }\n\n function checkApi(options) {\n formlyApiCheck['throw'](formlyApiCheck.formlyFieldOptions, options, {\n prefix: 'formly-field directive',\n url: 'formly-field-directive-validation-failed'\n });\n // validate with the type\n var type = options.type && formlyConfig.getType(options.type);\n if (type) {\n runApiCheck(type, options, true);\n }\n if (options.expressionProperties && options.expressionProperties.hide) {\n formlyWarn('dont-use-expressionproperties.hide-use-hideexpression-instead', 'You have specified `hide` in `expressionProperties`. Use `hideExpression` instead', options);\n }\n }\n\n function checkFieldGroupApi(options) {\n formlyApiCheck['throw'](formlyApiCheck.fieldGroup, options, {\n prefix: 'formly-field directive',\n url: 'formly-field-directive-validation-failed'\n });\n }\n\n function runApiCheck(_ref2, options, forType) {\n var apiCheck = _ref2.apiCheck;\n var apiCheckInstance = _ref2.apiCheckInstance;\n var apiCheckFunction = _ref2.apiCheckFunction;\n var apiCheckOptions = _ref2.apiCheckOptions;\n\n runApiCheckForType(apiCheck, apiCheckInstance, apiCheckFunction, apiCheckOptions, options);\n if (forType && options.type) {\n _angularFix2['default'].forEach(formlyConfig.getTypeHeritage(options.type), function (type) {\n runApiCheckForType(type.apiCheck, type.apiCheckInstance, type.apiCheckFunction, type.apiCheckOptions, options);\n });\n }\n }\n\n function runApiCheckForType(apiCheck, apiCheckInstance, apiCheckFunction, apiCheckOptions, options) {\n /* eslint complexity:[2, 9] */\n if (!apiCheck) {\n return;\n }\n var instance = apiCheckInstance || formlyConfig.extras.apiCheckInstance || formlyApiCheck;\n if (instance.config.disabled || _apiCheck2['default'].globalConfig.disabled) {\n return;\n }\n var fn = apiCheckFunction || 'warn';\n // this is the new API\n var checkerObjects = apiCheck(instance);\n _angularFix2['default'].forEach(checkerObjects, function (shape, name) {\n var checker = instance.shape(shape);\n var checkOptions = _angularFix2['default'].extend({\n prefix: 'formly-field type ' + options.type + ' for property ' + name,\n url: formlyApiCheck.config.output.docsBaseUrl + 'formly-field-type-apicheck-failed'\n }, apiCheckOptions);\n instance[fn](checker, options[name], checkOptions);\n });\n }\n}\n\n// Stateless util functions\nfunction getDefaultOptionsOptionsTypes(type) {\n return getDefaultOptionsProperty(type, 'optionsTypes', []);\n}\n\nfunction getDefaultOptionsProperty(type, prop, defaultValue) {\n return type.defaultOptions && type.defaultOptions[prop] || defaultValue;\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./directives/formly-field.js\n **/","import angular from 'angular-fix'\nimport apiCheckFactory from 'api-check'\n\nexport default formlyField\n\n/**\n * @ngdoc directive\n * @name formlyField\n * @restrict AE\n */\n// @ngInject\nfunction formlyField($http, $q, $compile, $templateCache, $interpolate, formlyConfig,\n formlyApiCheck, formlyUtil, formlyUsability, formlyWarn) {\n const {arrayify} = formlyUtil\n\n return {\n restrict: 'AE',\n transclude: true,\n require: '?^formlyForm',\n scope: {\n options: '=',\n model: '=',\n originalModel: '=?',\n formId: '@', // TODO remove formId in a breaking release\n index: '=?',\n fields: '=?',\n formState: '=?',\n formOptions: '=?',\n form: '=?', // TODO require form in a breaking release\n },\n controller: FormlyFieldController,\n link: fieldLink,\n }\n\n\n // @ngInject\n function FormlyFieldController($scope, $timeout, $parse, $controller, formlyValidationMessages) {\n /* eslint max-statements:[2, 34] */\n if ($scope.options.fieldGroup) {\n setupFieldGroup()\n return\n }\n\n const fieldType = getFieldType($scope.options)\n simplifyLife($scope.options)\n mergeFieldOptionsWithTypeDefaults($scope.options, fieldType)\n extendOptionsWithDefaults($scope.options, $scope.index)\n checkApi($scope.options)\n // set field id to link labels and fields\n\n // initalization\n setFieldIdAndName()\n setDefaultValue()\n setInitialValue()\n runExpressions()\n watchExpressions()\n addValidationMessages($scope.options)\n invokeControllers($scope, $scope.options, fieldType)\n\n // function definitions\n function runExpressions() {\n // must run on next tick to make sure that the current value is correct.\n return $timeout(function runExpressionsOnNextTick() {\n const field = $scope.options\n const currentValue = valueGetterSetter()\n angular.forEach(field.expressionProperties, function runExpression(expression, prop) {\n const setter = $parse(prop).assign\n const promise = $q.when(formlyUtil.formlyEval($scope, expression, currentValue, currentValue))\n promise.then(function setFieldValue(value) {\n setter(field, value)\n })\n })\n }, 0, false)\n }\n\n function watchExpressions() {\n if ($scope.formOptions.watchAllExpressions) {\n const field = $scope.options\n const currentValue = valueGetterSetter()\n angular.forEach(field.expressionProperties, function watchExpression(expression, prop) {\n const setter = $parse(prop).assign\n $scope.$watch(function expressionPropertyWatcher() {\n return formlyUtil.formlyEval($scope, expression, currentValue, currentValue)\n }, function expressionPropertyListener(value) {\n setter(field, value)\n }, true)\n })\n }\n }\n\n function valueGetterSetter(newVal) {\n if (!$scope.model || !$scope.options.key) {\n return undefined\n }\n if (angular.isDefined(newVal)) {\n parseSet($scope.options.key, $scope.model, newVal)\n }\n return parseGet($scope.options.key, $scope.model)\n }\n\n function shouldNotUseParseKey(key) {\n return angular.isNumber(key) || !formlyUtil.containsSelector(key)\n }\n\n function parseSet(key, model, newVal) {\n // If either of these are null/undefined then just return undefined\n if (!key || !model) {\n return\n }\n // If we are working with a number then $parse wont work, default back to the old way for now\n if (shouldNotUseParseKey(key)) {\n // TODO: Fix this so we can get several levels instead of just one with properties that are numeric\n model[key] = newVal\n } else {\n const setter = $parse($scope.options.key).assign\n if (setter) {\n setter($scope.model, newVal)\n }\n }\n }\n\n function parseGet(key, model) {\n // If either of these are null/undefined then just return undefined\n if (!key || !model) {\n return undefined\n }\n\n // If we are working with a number then $parse wont work, default back to the old way for now\n if (shouldNotUseParseKey(key)) {\n // TODO: Fix this so we can get several levels instead of just one with properties that are numeric\n return model[key]\n } else {\n return $parse(key)(model)\n }\n }\n\n function simplifyLife(options) {\n // add a few empty objects (if they don't already exist) so you don't have to undefined check everywhere\n formlyUtil.reverseDeepMerge(options, {\n originalModel: options.model,\n extras: {},\n data: {},\n templateOptions: {},\n validation: {},\n })\n // create $scope.to so template authors can reference to instead of $scope.options.templateOptions\n $scope.to = $scope.options.templateOptions\n $scope.formOptions = $scope.formOptions || {}\n }\n\n function setFieldIdAndName() {\n if (angular.isFunction(formlyConfig.extras.getFieldId)) {\n $scope.id = formlyConfig.extras.getFieldId($scope.options, $scope.model, $scope)\n } else {\n const formName = ($scope.form && $scope.form.$name) || $scope.formId\n $scope.id = formlyUtil.getFieldId(formName, $scope.options, $scope.index)\n }\n $scope.options.id = $scope.id\n $scope.name = $scope.options.name || $scope.options.id\n $scope.options.name = $scope.name\n }\n\n function setDefaultValue() {\n if (angular.isDefined($scope.options.defaultValue) &&\n !angular.isDefined(parseGet($scope.options.key, $scope.model))) {\n parseSet($scope.options.key, $scope.model, $scope.options.defaultValue)\n }\n }\n\n function setInitialValue() {\n $scope.options.initialValue = $scope.model && parseGet($scope.options.key, $scope.model)\n }\n\n function mergeFieldOptionsWithTypeDefaults(options, type) {\n if (type) {\n mergeOptions(options, type.defaultOptions)\n }\n const properOrder = arrayify(options.optionsTypes).reverse() // so the right things are overridden\n angular.forEach(properOrder, typeName => {\n mergeOptions(options, formlyConfig.getType(typeName, true, options).defaultOptions)\n })\n }\n\n function mergeOptions(options, extraOptions) {\n if (extraOptions) {\n if (angular.isFunction(extraOptions)) {\n extraOptions = extraOptions(options, $scope)\n }\n formlyUtil.reverseDeepMerge(options, extraOptions)\n }\n }\n\n function extendOptionsWithDefaults(options, index) {\n const key = options.key || index || 0\n angular.extend(options, {\n // attach the key in case the formly-field directive is used directly\n key,\n value: options.value || valueGetterSetter,\n runExpressions,\n resetModel,\n updateInitialValue,\n })\n }\n\n function resetModel() {\n parseSet($scope.options.key, $scope.model, $scope.options.initialValue)\n if ($scope.options.formControl) {\n if (angular.isArray($scope.options.formControl)) {\n angular.forEach($scope.options.formControl, function(formControl) {\n resetFormControl(formControl, true)\n })\n } else {\n resetFormControl($scope.options.formControl)\n }\n }\n if ($scope.form) {\n $scope.form.$setUntouched && $scope.form.$setUntouched()\n $scope.form.$setPristine()\n }\n }\n\n function resetFormControl(formControl, isMultiNgModel) {\n if (!isMultiNgModel) {\n formControl.$setViewValue(parseGet($scope.options.key, $scope.model))\n }\n\n formControl.$render()\n formControl.$setUntouched && formControl.$setUntouched()\n formControl.$setPristine()\n\n // To prevent breaking change requiring a digest to reset $viewModel\n if (!$scope.$root.$$phase) {\n $scope.$digest()\n }\n }\n\n function updateInitialValue() {\n $scope.options.initialValue = parseGet($scope.options.key, $scope.model)\n }\n\n function addValidationMessages(options) {\n options.validation.messages = options.validation.messages || {}\n angular.forEach(formlyValidationMessages.messages, function createFunctionForMessage(expression, name) {\n if (!options.validation.messages[name]) {\n options.validation.messages[name] = function evaluateMessage(viewValue, modelValue, scope) {\n return formlyUtil.formlyEval(scope, expression, modelValue, viewValue)\n }\n }\n })\n }\n\n function invokeControllers(scope, options = {}, type = {}) {\n angular.forEach([type.controller, options.controller], controller => {\n if (controller) {\n $controller(controller, {$scope: scope})\n }\n })\n }\n\n function setupFieldGroup() {\n $scope.options.options = $scope.options.options || {}\n $scope.options.options.formState = $scope.formState\n $scope.to = $scope.options.templateOptions\n }\n }\n\n\n // link function\n function fieldLink(scope, el, attrs, formlyFormCtrl) {\n if (scope.options.fieldGroup) {\n setFieldGroupTemplate()\n return\n }\n\n // watch the field model (if exists) if there is no parent formly-form directive (that would watch it instead)\n if (!formlyFormCtrl && scope.options.model) {\n scope.$watch('options.model', () => scope.options.runExpressions(), true)\n }\n\n addAttributes()\n addClasses()\n\n const type = getFieldType(scope.options)\n const args = arguments\n const thusly = this\n let fieldCount = 0\n const fieldManipulators = getManipulators(scope.options, scope.formOptions)\n getFieldTemplate(scope.options)\n .then(runManipulators(fieldManipulators.preWrapper))\n .then(transcludeInWrappers(scope.options, scope.formOptions))\n .then(runManipulators(fieldManipulators.postWrapper))\n .then(setElementTemplate)\n .then(watchFormControl)\n .then(callLinkFunctions)\n .catch(error => {\n formlyWarn(\n 'there-was-a-problem-setting-the-template-for-this-field',\n 'There was a problem setting the template for this field ',\n scope.options,\n error\n )\n })\n\n function setFieldGroupTemplate() {\n checkFieldGroupApi(scope.options)\n el.addClass('formly-field-group')\n let extraAttributes = ''\n if (scope.options.elementAttributes) {\n extraAttributes = Object.keys(scope.options.elementAttributes).map(key => {\n return `${key}=\"${scope.options.elementAttributes[key]}\"`\n }).join(' ')\n }\n let modelValue = 'model'\n scope.options.form = scope.form\n if (scope.options.key) {\n modelValue = `model['${scope.options.key}']`\n }\n getTemplate(`\n \n \n `)\n .then(transcludeInWrappers(scope.options, scope.formOptions))\n .then(setElementTemplate)\n }\n\n function addAttributes() {\n if (scope.options.elementAttributes) {\n el.attr(scope.options.elementAttributes)\n }\n }\n\n function addClasses() {\n if (scope.options.className) {\n el.addClass(scope.options.className)\n }\n if (scope.options.type) {\n el.addClass(`formly-field-${scope.options.type}`)\n }\n }\n\n function setElementTemplate(templateString) {\n el.html(asHtml(templateString))\n $compile(el.contents())(scope)\n return templateString\n }\n\n function watchFormControl(templateString) {\n let stopWatchingShowError = angular.noop\n if (scope.options.noFormControl) {\n return\n }\n const templateEl = angular.element(`${templateString}
`)\n const ngModelNodes = templateEl[0].querySelectorAll('[ng-model],[data-ng-model]')\n\n\n if (ngModelNodes.length) {\n angular.forEach(ngModelNodes, function(ngModelNode) {\n fieldCount++\n watchFieldNameOrExistence(ngModelNode.getAttribute('name'))\n })\n }\n\n function watchFieldNameOrExistence(name) {\n const nameExpressionRegex = /\\{\\{(.*?)}}/\n const nameExpression = nameExpressionRegex.exec(name)\n if (nameExpression) {\n name = $interpolate(name)(scope)\n }\n watchFieldExistence(name)\n }\n\n function watchFieldExistence(name) {\n scope.$watch(`form[\"${name}\"]`, function formControlChange(formControl) {\n if (formControl) {\n if (fieldCount > 1) {\n if (!scope.options.formControl) {\n scope.options.formControl = []\n }\n scope.options.formControl.push(formControl)\n } else {\n scope.options.formControl = formControl\n }\n scope.fc = scope.options.formControl // shortcut for template authors\n stopWatchingShowError()\n addShowMessagesWatcher()\n addParsers()\n addFormatters()\n }\n })\n }\n\n function addShowMessagesWatcher() {\n stopWatchingShowError = scope.$watch(function watchShowValidationChange() {\n const customExpression = formlyConfig.extras.errorExistsAndShouldBeVisibleExpression\n const options = scope.options\n const formControls = arrayify(scope.fc)\n if (!formControls.some(fc => fc.$invalid)) {\n return false\n } else if (typeof options.validation.show === 'boolean') {\n return options.validation.show\n } else if (customExpression) {\n return formControls.some(fc =>\n formlyUtil.formlyEval(scope, customExpression, fc.$modelValue, fc.$viewValue))\n } else {\n return formControls.some(fc => {\n const noTouchedButDirty = (angular.isUndefined(fc.$touched) && fc.$dirty)\n return (fc.$touched || noTouchedButDirty)\n })\n }\n }, function onShowValidationChange(show) {\n scope.options.validation.errorExistsAndShouldBeVisible = show\n scope.showError = show // shortcut for template authors\n })\n }\n\n function addParsers() {\n setParsersOrFormatters('parsers')\n }\n\n function addFormatters() {\n setParsersOrFormatters('formatters')\n const ctrl = scope.fc\n const formWasPristine = scope.form.$pristine\n if (scope.options.formatters) {\n let value = ctrl.$modelValue\n ctrl.$formatters.forEach((formatter) => {\n value = formatter(value)\n })\n\n ctrl.$setViewValue(value)\n ctrl.$render()\n ctrl.$setPristine()\n if (formWasPristine) {\n scope.form.$setPristine()\n }\n }\n }\n\n function setParsersOrFormatters(which) {\n let originalThingProp = 'originalParser'\n if (which === 'formatters') {\n originalThingProp = 'originalFormatter'\n }\n\n // init with type's parsers\n let things = getThingsFromType(type)\n\n // get optionsTypes things\n things = formlyUtil.extendArray(things, getThingsFromOptionsTypes(scope.options.optionsTypes))\n\n // get field's things\n things = formlyUtil.extendArray(things, scope.options[which])\n\n // convert things into formlyExpression things\n angular.forEach(things, (thing, index) => {\n things[index] = getFormlyExpressionThing(thing)\n })\n\n let ngModelCtrls = scope.fc\n if (!angular.isArray(ngModelCtrls)) {\n ngModelCtrls = [ngModelCtrls]\n }\n\n angular.forEach(ngModelCtrls, ngModelCtrl => {\n ngModelCtrl['$' + which] = ngModelCtrl['$' + which].concat(...things)\n })\n\n function getThingsFromType(theType) {\n if (!theType) {\n return []\n }\n if (angular.isString(theType)) {\n theType = formlyConfig.getType(theType, true, scope.options)\n }\n let typeThings = []\n\n // get things from parent\n if (theType.extends) {\n typeThings = formlyUtil.extendArray(typeThings, getThingsFromType(theType.extends))\n }\n\n // get own type's things\n typeThings = formlyUtil.extendArray(typeThings, getDefaultOptionsProperty(theType, which, []))\n\n // get things from optionsTypes\n typeThings = formlyUtil.extendArray(\n typeThings,\n getThingsFromOptionsTypes(getDefaultOptionsOptionsTypes(theType))\n )\n\n return typeThings\n }\n\n function getThingsFromOptionsTypes(optionsTypes = []) {\n let optionsTypesThings = []\n angular.forEach(angular.copy(arrayify(optionsTypes)).reverse(), optionsTypeName => {\n optionsTypesThings = formlyUtil.extendArray(optionsTypesThings, getThingsFromType(optionsTypeName))\n })\n return optionsTypesThings\n }\n\n function getFormlyExpressionThing(thing) {\n formlyExpressionParserOrFormatterFunction[originalThingProp] = thing\n return formlyExpressionParserOrFormatterFunction\n\n function formlyExpressionParserOrFormatterFunction($viewValue) {\n const $modelValue = scope.options.value()\n return formlyUtil.formlyEval(scope, thing, $modelValue, $viewValue)\n }\n }\n\n }\n }\n\n function callLinkFunctions() {\n if (type && type.link) {\n type.link.apply(thusly, args)\n }\n if (scope.options.link) {\n scope.options.link.apply(thusly, args)\n }\n }\n\n\n function runManipulators(manipulators) {\n return function runManipulatorsOnTemplate(templateToManipulate) {\n let chain = $q.when(templateToManipulate)\n angular.forEach(manipulators, manipulator => {\n chain = chain.then(template => {\n return $q.when(manipulator(template, scope.options, scope)).then(newTemplate => {\n return angular.isString(newTemplate) ? newTemplate : asHtml(newTemplate)\n })\n })\n })\n return chain\n }\n }\n }\n\n // sort-of stateless util functions\n function asHtml(el) {\n const wrapper = angular.element(' ')\n return wrapper.append(el).html()\n }\n\n function getFieldType(options) {\n return options.type && formlyConfig.getType(options.type)\n }\n\n function getManipulators(options, formOptions) {\n let preWrapper = []\n let postWrapper = []\n addManipulators(options.templateManipulators)\n addManipulators(formOptions.templateManipulators)\n addManipulators(formlyConfig.templateManipulators)\n return {preWrapper, postWrapper}\n\n function addManipulators(manipulators) {\n /* eslint-disable */ // it doesn't understand this :-(\n const {preWrapper:pre = [], postWrapper:post = []} = (manipulators || {});\n preWrapper = preWrapper.concat(pre);\n postWrapper = postWrapper.concat(post);\n /* eslint-enable */\n }\n }\n\n function getFieldTemplate(options) {\n function fromOptionsOrType(key, fieldType) {\n if (angular.isDefined(options[key])) {\n return options[key]\n } else if (fieldType && angular.isDefined(fieldType[key])) {\n return fieldType[key]\n }\n }\n\n const type = formlyConfig.getType(options.type, true, options)\n const template = fromOptionsOrType('template', type)\n const templateUrl = fromOptionsOrType('templateUrl', type)\n if (angular.isUndefined(template) && !templateUrl) {\n throw formlyUsability.getFieldError(\n 'type-type-has-no-template',\n `Type '${options.type}' has no template. On element:`, options\n )\n }\n\n return getTemplate(templateUrl || template, angular.isUndefined(template), options)\n }\n\n\n function getTemplate(template, isUrl, options) {\n let templatePromise\n if (angular.isFunction(template)) {\n templatePromise = $q.when(template(options))\n } else {\n templatePromise = $q.when(template)\n }\n\n if (!isUrl) {\n return templatePromise\n } else {\n const httpOptions = {cache: $templateCache}\n return templatePromise\n .then((url) => $http.get(url, httpOptions))\n .then((response) => response.data)\n .catch(function handleErrorGettingATemplate(error) {\n formlyWarn(\n 'problem-loading-template-for-templateurl',\n 'Problem loading template for ' + template,\n error\n )\n })\n }\n }\n\n function transcludeInWrappers(options, formOptions) {\n const wrapper = getWrapperOption(options, formOptions)\n\n return function transcludeTemplate(template) {\n if (!wrapper.length) {\n return $q.when(template)\n }\n\n wrapper.forEach((aWrapper) => {\n formlyUsability.checkWrapper(aWrapper, options)\n runApiCheck(aWrapper, options)\n })\n const promises = wrapper.map(w => getTemplate(w.template || w.templateUrl, !w.template))\n return $q.all(promises).then(wrappersTemplates => {\n wrappersTemplates.forEach((wrapperTemplate, index) => {\n formlyUsability.checkWrapperTemplate(wrapperTemplate, wrapper[index])\n })\n wrappersTemplates.reverse() // wrapper 0 is wrapped in wrapper 1 and so on...\n let totalWrapper = wrappersTemplates.shift()\n wrappersTemplates.forEach(wrapperTemplate => {\n totalWrapper = doTransclusion(totalWrapper, wrapperTemplate)\n })\n return doTransclusion(totalWrapper, template)\n })\n }\n }\n\n function doTransclusion(wrapper, template) {\n const superWrapper = angular.element(' ') // this allows people not have to have a single root in wrappers\n superWrapper.append(wrapper)\n let transcludeEl = superWrapper.find('formly-transclude')\n if (!transcludeEl.length) {\n // try it using our custom find function\n transcludeEl = formlyUtil.findByNodeName(superWrapper, 'formly-transclude')\n }\n transcludeEl.replaceWith(template)\n return superWrapper.html()\n }\n\n function getWrapperOption(options, formOptions) {\n /* eslint complexity:[2, 6] */\n let wrapper = options.wrapper\n // explicit null means no wrapper\n if (wrapper === null) {\n return []\n }\n\n // nothing specified means use the default wrapper for the type\n if (!wrapper) {\n // get all wrappers that specify they apply to this type\n wrapper = arrayify(formlyConfig.getWrapperByType(options.type))\n } else {\n wrapper = arrayify(wrapper).map(formlyConfig.getWrapper)\n }\n\n // get all wrappers for that the type specified that it uses.\n const type = formlyConfig.getType(options.type, true, options)\n if (type && type.wrapper) {\n const typeWrappers = arrayify(type.wrapper).map(formlyConfig.getWrapper)\n wrapper = wrapper.concat(typeWrappers)\n }\n\n // add form wrappers\n if (formOptions.wrapper) {\n const formWrappers = arrayify(formOptions.wrapper).map(formlyConfig.getWrapper)\n wrapper = wrapper.concat(formWrappers)\n }\n\n // add the default wrapper last\n const defaultWrapper = formlyConfig.getWrapper()\n if (defaultWrapper) {\n wrapper.push(defaultWrapper)\n }\n return wrapper\n }\n\n function checkApi(options) {\n formlyApiCheck.throw(formlyApiCheck.formlyFieldOptions, options, {\n prefix: 'formly-field directive',\n url: 'formly-field-directive-validation-failed',\n })\n // validate with the type\n const type = options.type && formlyConfig.getType(options.type)\n if (type) {\n runApiCheck(type, options, true)\n }\n if (options.expressionProperties && options.expressionProperties.hide) {\n formlyWarn(\n 'dont-use-expressionproperties.hide-use-hideexpression-instead',\n 'You have specified `hide` in `expressionProperties`. Use `hideExpression` instead',\n options\n )\n }\n }\n\n function checkFieldGroupApi(options) {\n formlyApiCheck.throw(formlyApiCheck.fieldGroup, options, {\n prefix: 'formly-field directive',\n url: 'formly-field-directive-validation-failed',\n })\n }\n\n function runApiCheck({apiCheck, apiCheckInstance, apiCheckFunction, apiCheckOptions}, options, forType) {\n runApiCheckForType(apiCheck, apiCheckInstance, apiCheckFunction, apiCheckOptions, options)\n if (forType && options.type) {\n angular.forEach(formlyConfig.getTypeHeritage(options.type), function(type) {\n runApiCheckForType(type.apiCheck, type.apiCheckInstance, type.apiCheckFunction, type.apiCheckOptions, options)\n })\n }\n }\n\n function runApiCheckForType(apiCheck, apiCheckInstance, apiCheckFunction, apiCheckOptions, options) {\n /* eslint complexity:[2, 9] */\n if (!apiCheck) {\n return\n }\n const instance = apiCheckInstance || formlyConfig.extras.apiCheckInstance || formlyApiCheck\n if (instance.config.disabled || apiCheckFactory.globalConfig.disabled) {\n return\n }\n const fn = apiCheckFunction || 'warn'\n // this is the new API\n const checkerObjects = apiCheck(instance)\n angular.forEach(checkerObjects, (shape, name) => {\n const checker = instance.shape(shape)\n const checkOptions = angular.extend({\n prefix: `formly-field type ${options.type} for property ${name}`,\n url: formlyApiCheck.config.output.docsBaseUrl + 'formly-field-type-apicheck-failed',\n }, apiCheckOptions)\n instance[fn](checker, options[name], checkOptions)\n })\n }\n\n\n}\n\n\n// Stateless util functions\nfunction getDefaultOptionsOptionsTypes(type) {\n return getDefaultOptionsProperty(type, 'optionsTypes', [])\n}\n\nfunction getDefaultOptionsProperty(type, prop, defaultValue) {\n return type.defaultOptions && type.defaultOptions[prop] || defaultValue\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./directives/formly-field.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\nexports['default'] = formlyFocus;\n\n// @ngInject\nfunction formlyFocus($timeout, $document) {\n return {\n restrict: 'A',\n link: function formlyFocusLink(scope, element, attrs) {\n var previousEl = null;\n var el = element[0];\n var doc = $document[0];\n attrs.$observe('formlyFocus', function respondToFocusExpressionChange(value) {\n /* eslint no-bitwise:0 */ // I know what I'm doing. I promise...\n if (value === 'true') {\n $timeout(function setElementFocus() {\n previousEl = doc.activeElement;\n el.focus();\n }, ~ ~attrs.focusWait);\n } else if (value === 'false') {\n if (doc.activeElement === el) {\n el.blur();\n if (attrs.hasOwnProperty('refocus') && previousEl) {\n previousEl.focus();\n }\n }\n }\n });\n }\n };\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./directives/formly-focus.js\n **/","export default formlyFocus\n\n// @ngInject\nfunction formlyFocus($timeout, $document) {\n return {\n restrict: 'A',\n link: function formlyFocusLink(scope, element, attrs) {\n let previousEl = null\n const el = element[0]\n const doc = $document[0]\n attrs.$observe('formlyFocus', function respondToFocusExpressionChange(value) {\n /* eslint no-bitwise:0 */ // I know what I'm doing. I promise...\n if (value === 'true') {\n $timeout(function setElementFocus() {\n previousEl = doc.activeElement\n el.focus()\n }, ~~attrs.focusWait)\n } else if (value === 'false') {\n if (doc.activeElement === el) {\n el.blur()\n if (attrs.hasOwnProperty('refocus') && previousEl) {\n previousEl.focus()\n }\n }\n }\n })\n },\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./directives/formly-focus.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\nvar _slice = Array.prototype.slice;\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nexports['default'] = formlyForm;\n\n/**\n * @ngdoc directive\n * @name formlyForm\n * @restrict AE\n */\n// @ngInject\nfunction formlyForm(formlyUsability, formlyWarn, $parse, formlyConfig, $interpolate) {\n var currentFormId = 1;\n return {\n restrict: 'AE',\n template: formlyFormGetTemplate,\n replace: true,\n transclude: true,\n scope: {\n fields: '=',\n model: '=',\n form: '=?',\n options: '=?'\n },\n controller: FormlyFormController,\n link: formlyFormLink\n };\n\n function formlyFormGetTemplate(el, attrs) {\n var rootEl = getRootEl();\n var fieldRootEl = getFieldRootEl();\n var formId = 'formly_' + currentFormId++;\n var parentFormAttributes = '';\n if (attrs.hasOwnProperty('isFieldGroup') && el.parent().parent().hasClass('formly')) {\n parentFormAttributes = copyAttributes(el.parent().parent()[0].attributes);\n }\n return '\\n <' + rootEl + ' class=\"formly\"\\n name=\"' + getFormName() + '\"\\n role=\"form\" ' + parentFormAttributes + '>\\n <' + fieldRootEl + ' formly-field\\n ng-repeat=\"field in fields ' + getTrackBy() + '\"\\n ' + getHideDirective() + '=\"!field.hide\"\\n class=\"formly-field\"\\n options=\"field\"\\n model=\"field.model || model\"\\n original-model=\"model\"\\n fields=\"fields\"\\n form=\"theFormlyForm\"\\n form-id=\"' + getFormName() + '\"\\n form-state=\"options.formState\"\\n form-options=\"options\"\\n index=\"$index\">\\n ' + fieldRootEl + '>\\n
\\n ' + rootEl + '>\\n ';\n\n function getRootEl() {\n return attrs.rootEl || 'ng-form';\n }\n\n function getFieldRootEl() {\n return attrs.fieldRootEl || 'div';\n }\n\n function getHideDirective() {\n return attrs.hideDirective || formlyConfig.extras.defaultHideDirective || 'ng-if';\n }\n\n function getTrackBy() {\n if (!attrs.trackBy) {\n return '';\n } else {\n return 'track by ' + attrs.trackBy;\n }\n }\n\n function getFormName() {\n var formName = formId;\n var bindName = attrs.bindName;\n if (bindName) {\n if (_angularFix2['default'].version.minor < 3) {\n throw formlyUsability.getFormlyError('bind-name attribute on formly-form not allowed in < angular 1.3');\n }\n // we can do a one-time binding here because we know we're in 1.3.x territory\n formName = $interpolate.startSymbol() + '::\\'formly_\\' + ' + bindName + $interpolate.endSymbol();\n }\n return formName;\n }\n\n function getTranscludeClass() {\n return attrs.transcludeClass || '';\n }\n\n function copyAttributes(attributes) {\n var excluded = ['model', 'form', 'fields', 'options', 'name', 'role', 'class', 'data-model', 'data-form', 'data-fields', 'data-options', 'data-name'];\n var arrayAttrs = [];\n _angularFix2['default'].forEach(attributes, function (_ref) {\n var nodeName = _ref.nodeName;\n var value = _ref.value;\n\n if (nodeName !== 'undefined' && excluded.indexOf(nodeName) === -1) {\n arrayAttrs.push(toKebabCase(nodeName) + '=\"' + value + '\"');\n }\n });\n return arrayAttrs.join(' ');\n }\n }\n\n // @ngInject\n function FormlyFormController($scope, formlyApiCheck, formlyUtil) {\n setupOptions();\n $scope.model = $scope.model || {};\n setupFields();\n\n // watch the model and evaluate watch expressions that depend on it.\n if (!$scope.options.manualModelWatcher) {\n $scope.$watch('model', onModelOrFormStateChange, true);\n } else if (_angularFix2['default'].isFunction($scope.options.manualModelWatcher)) {\n $scope.$watch($scope.options.manualModelWatcher, onModelOrFormStateChange, true);\n }\n\n if ($scope.options.formState) {\n $scope.$watch('options.formState', onModelOrFormStateChange, true);\n }\n\n function onModelOrFormStateChange() {\n _angularFix2['default'].forEach($scope.fields, runFieldExpressionProperties);\n }\n\n function validateFormControl(formControl, promise) {\n var validate = formControl.$validate;\n if (promise) {\n promise.then(validate);\n } else {\n validate();\n }\n }\n\n function runFieldExpressionProperties(field, index) {\n var model = field.model || $scope.model;\n var promise = field.runExpressions && field.runExpressions();\n if (field.hideExpression) {\n // can't use hide with expressionProperties reliably\n var val = model[field.key];\n field.hide = evalCloseToFormlyExpression(field.hideExpression, val, field, index, { model: model });\n }\n if (field.extras && field.extras.validateOnModelChange && field.formControl) {\n if (_angularFix2['default'].isArray(field.formControl)) {\n _angularFix2['default'].forEach(field.formControl, function (formControl) {\n validateFormControl(formControl, promise);\n });\n } else {\n validateFormControl(field.formControl, promise);\n }\n }\n }\n\n function setupFields() {\n $scope.fields = $scope.fields || [];\n\n checkDeprecatedOptions($scope.options);\n\n var fieldTransforms = $scope.options.fieldTransform || formlyConfig.extras.fieldTransform;\n\n if (!_angularFix2['default'].isArray(fieldTransforms)) {\n fieldTransforms = [fieldTransforms];\n }\n\n _angularFix2['default'].forEach(fieldTransforms, function transformFields(fieldTransform) {\n if (fieldTransform) {\n $scope.fields = fieldTransform($scope.fields, $scope.model, $scope.options, $scope.form);\n if (!$scope.fields) {\n throw formlyUsability.getFormlyError('fieldTransform must return an array of fields');\n }\n }\n });\n\n setupModels();\n\n if ($scope.options.watchAllExpressions) {\n _angularFix2['default'].forEach($scope.fields, setupHideExpressionWatcher);\n }\n\n _angularFix2['default'].forEach($scope.fields, attachKey); // attaches a key based on the index if a key isn't specified\n _angularFix2['default'].forEach($scope.fields, setupWatchers); // setup watchers for all fields\n }\n\n function checkDeprecatedOptions(options) {\n if (formlyConfig.extras.fieldTransform && _angularFix2['default'].isFunction(formlyConfig.extras.fieldTransform)) {\n formlyWarn('fieldtransform-as-a-function-deprecated', 'fieldTransform as a function has been deprecated.', 'Attempted for formlyConfig.extras: ' + formlyConfig.extras.fieldTransform.name, formlyConfig.extras);\n } else if (options.fieldTransform && _angularFix2['default'].isFunction(options.fieldTransform)) {\n formlyWarn('fieldtransform-as-a-function-deprecated', 'fieldTransform as a function has been deprecated.', 'Attempted for form', options);\n }\n }\n\n function setupOptions() {\n formlyApiCheck['throw']([formlyApiCheck.formOptionsApi.optional], [$scope.options], { prefix: 'formly-form options check' });\n $scope.options = $scope.options || {};\n $scope.options.formState = $scope.options.formState || {};\n\n _angularFix2['default'].extend($scope.options, {\n updateInitialValue: updateInitialValue,\n resetModel: resetModel\n });\n }\n\n function updateInitialValue() {\n _angularFix2['default'].forEach($scope.fields, function (field) {\n if (isFieldGroup(field) && field.options) {\n field.options.updateInitialValue();\n } else {\n field.updateInitialValue();\n }\n });\n }\n\n function resetModel() {\n _angularFix2['default'].forEach($scope.fields, function (field) {\n if (isFieldGroup(field) && field.options) {\n field.options.resetModel();\n } else if (field.resetModel) {\n field.resetModel();\n }\n });\n }\n\n function setupModels() {\n // a set of field models that are already watched (the $scope.model will have its own watcher)\n var watchedModels = [$scope.model];\n // we will not set up automatic model watchers if manual mode is set\n var manualModelWatcher = $scope.options.manualModelWatcher;\n\n if ($scope.options.formState) {\n // $scope.options.formState will have its own watcher\n watchedModels.push($scope.options.formState);\n }\n\n _angularFix2['default'].forEach($scope.fields, function (field) {\n var isNewModel = initModel(field);\n\n if (field.model && isNewModel && watchedModels.indexOf(field.model) === -1 && !manualModelWatcher) {\n $scope.$watch(function () {\n return field.model;\n }, onModelOrFormStateChange, true);\n watchedModels.push(field.model);\n }\n });\n }\n\n function setupHideExpressionWatcher(field, index) {\n if (field.hideExpression) {\n (function () {\n // can't use hide with expressionProperties reliably\n var model = field.model || $scope.model;\n $scope.$watch(function hideExpressionWatcher() {\n var val = model[field.key];\n return evalCloseToFormlyExpression(field.hideExpression, val, field, index, { model: model });\n }, function (hide) {\n return field.hide = hide;\n }, true);\n })();\n }\n }\n\n function initModel(field) {\n var isNewModel = true;\n\n if (_angularFix2['default'].isString(field.model)) {\n (function () {\n var expression = field.model;\n\n isNewModel = !referencesCurrentlyWatchedModel(expression);\n\n field.model = resolveStringModel(expression);\n\n $scope.$watch(function () {\n return resolveStringModel(expression);\n }, function (model) {\n return field.model = model;\n });\n })();\n }\n\n return isNewModel;\n\n function resolveStringModel(expression) {\n var index = $scope.fields.indexOf(field);\n var model = evalCloseToFormlyExpression(expression, undefined, field, index, { model: $scope.model });\n\n if (!model) {\n throw formlyUsability.getFieldError('field-model-must-be-initialized', 'Field model must be initialized. When specifying a model as a string for a field, the result of the' + ' expression must have been initialized ahead of time.', field);\n }\n\n return model;\n }\n }\n\n function referencesCurrentlyWatchedModel(expression) {\n return ['model', 'formState'].some(function (item) {\n return formlyUtil.startsWith(expression, item + '.') || formlyUtil.startsWith(expression, item + '[');\n });\n }\n\n function attachKey(field, index) {\n if (!isFieldGroup(field)) {\n field.key = field.key || index || 0;\n }\n }\n\n function setupWatchers(field, index) {\n if (!_angularFix2['default'].isDefined(field.watcher)) {\n return;\n }\n var watchers = field.watcher;\n if (!_angularFix2['default'].isArray(watchers)) {\n watchers = [watchers];\n }\n _angularFix2['default'].forEach(watchers, function setupWatcher(watcher) {\n if (!_angularFix2['default'].isDefined(watcher.listener) && !watcher.runFieldExpressions) {\n throw formlyUsability.getFieldError('all-field-watchers-must-have-a-listener', 'All field watchers must have a listener', field);\n }\n var watchExpression = getWatchExpression(watcher, field, index);\n var watchListener = getWatchListener(watcher, field, index);\n\n var type = watcher.type || '$watch';\n watcher.stopWatching = $scope[type](watchExpression, watchListener, watcher.watchDeep);\n });\n }\n\n function getWatchExpression(watcher, field, index) {\n var watchExpression = undefined;\n if (!_angularFix2['default'].isUndefined(watcher.expression)) {\n watchExpression = watcher.expression;\n } else if (field.key) {\n watchExpression = 'model[\\'' + field.key.toString().split('.').join('\\'][\\'') + '\\']';\n }\n if (_angularFix2['default'].isFunction(watchExpression)) {\n (function () {\n // wrap the field's watch expression so we can call it with the field as the first arg\n // and the stop function as the last arg as a helper\n var originalExpression = watchExpression;\n watchExpression = function formlyWatchExpression() {\n var args = modifyArgs.apply(undefined, [watcher, index].concat(_slice.call(arguments)));\n return originalExpression.apply(undefined, _toConsumableArray(args));\n };\n watchExpression.displayName = 'Formly Watch Expression for field for ' + field.key;\n })();\n } else if (field.model) {\n watchExpression = $parse(watchExpression).bind(null, $scope, { model: field.model });\n }\n return watchExpression;\n }\n\n function getWatchListener(watcher, field, index) {\n var watchListener = watcher.listener;\n if (_angularFix2['default'].isFunction(watchListener) || watcher.runFieldExpressions) {\n (function () {\n // wrap the field's watch listener so we can call it with the field as the first arg\n // and the stop function as the last arg as a helper\n var originalListener = watchListener;\n watchListener = function formlyWatchListener() {\n var value = undefined;\n if (originalListener) {\n var args = modifyArgs.apply(undefined, [watcher, index].concat(_slice.call(arguments)));\n value = originalListener.apply(undefined, _toConsumableArray(args));\n }\n if (watcher.runFieldExpressions) {\n runFieldExpressionProperties(field, index);\n }\n return value;\n };\n watchListener.displayName = 'Formly Watch Listener for field for ' + field.key;\n })();\n }\n return watchListener;\n }\n\n function modifyArgs(watcher, index) {\n for (var _len = arguments.length, originalArgs = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n originalArgs[_key - 2] = arguments[_key];\n }\n\n return [$scope.fields[index]].concat(originalArgs, [watcher.stopWatching]);\n }\n\n function evalCloseToFormlyExpression(expression, val, field, index) {\n var extraLocals = arguments.length <= 4 || arguments[4] === undefined ? {} : arguments[4];\n\n extraLocals = _angularFix2['default'].extend(getFormlyFieldLikeLocals(field, index), extraLocals);\n return formlyUtil.formlyEval($scope, expression, val, val, extraLocals);\n }\n\n function getFormlyFieldLikeLocals(field, index) {\n // this makes it closer to what a regular formlyExpression would be\n return {\n model: field.model,\n options: field,\n index: index,\n formState: $scope.options.formState,\n originalModel: $scope.model,\n formOptions: $scope.options,\n formId: $scope.formId\n };\n }\n }\n\n function formlyFormLink(scope, el, attrs) {\n setFormController();\n fixChromeAutocomplete();\n\n function setFormController() {\n var formId = attrs.name;\n scope.formId = formId;\n scope.theFormlyForm = scope[formId];\n if (attrs.form) {\n var getter = $parse(attrs.form);\n var setter = getter.assign;\n var parentForm = getter(scope.$parent);\n if (parentForm) {\n scope.theFormlyForm = parentForm;\n if (scope[formId]) {\n scope.theFormlyForm.$removeControl(scope[formId]);\n }\n\n // this next line is probably one of the more dangerous things that angular-formly does to improve the\n // API for angular-formly forms. It ensures that the NgModelControllers inside of formly-form will be\n // attached to the form that is passed to formly-form rather than the one that formly-form creates\n // this is necessary because it's confusing to have a step between the form you pass in\n // and the fields in that form. It also is because angular doesn't propagate properties like $submitted down\n // to children forms :-( This line was added to solve this issue:\n // https://github.com/formly-js/angular-formly/issues/287\n // luckily, this is how the formController has been accessed by the NgModelController since angular 1.0.0\n // so I expect it will remain this way for the life of angular 1.x\n el.removeData('$formController');\n } else {\n setter(scope.$parent, scope[formId]);\n }\n }\n if (!scope.theFormlyForm && !formlyConfig.disableWarnings) {\n /* eslint no-console:0 */\n formlyWarn('formly-form-has-no-formcontroller', 'Your formly-form does not have a `form` property. Many functions of the form (like validation) may not work', el, scope);\n }\n }\n\n /*\n * chrome autocomplete lameness\n * see https://code.google.com/p/chromium/issues/detail?id=468153#c14\n * ლ(ಠ益ಠლ) (╯°□°)╯︵ ┻━┻ (◞‸◟;)\n */\n function fixChromeAutocomplete() {\n var global = formlyConfig.extras.removeChromeAutoComplete === true;\n var offInstance = scope.options && scope.options.removeChromeAutoComplete === false;\n var onInstance = scope.options && scope.options.removeChromeAutoComplete === true;\n if (global && !offInstance || onInstance) {\n var input = document.createElement('input');\n input.setAttribute('autocomplete', 'address-level4');\n input.setAttribute('hidden', 'true');\n el[0].appendChild(input);\n }\n }\n }\n\n // stateless util functions\n function toKebabCase(string) {\n if (string) {\n return string.replace(/([A-Z])/g, function ($1) {\n return '-' + $1.toLowerCase();\n });\n } else {\n return '';\n }\n }\n\n function isFieldGroup(field) {\n return field && !!field.fieldGroup;\n }\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./directives/formly-form.js\n **/","import angular from 'angular-fix'\n\nexport default formlyForm\n\n/**\n * @ngdoc directive\n * @name formlyForm\n * @restrict AE\n */\n// @ngInject\nfunction formlyForm(formlyUsability, formlyWarn, $parse, formlyConfig, $interpolate) {\n let currentFormId = 1\n return {\n restrict: 'AE',\n template: formlyFormGetTemplate,\n replace: true,\n transclude: true,\n scope: {\n fields: '=',\n model: '=',\n form: '=?',\n options: '=?',\n },\n controller: FormlyFormController,\n link: formlyFormLink,\n }\n\n function formlyFormGetTemplate(el, attrs) {\n const rootEl = getRootEl()\n const fieldRootEl = getFieldRootEl()\n const formId = `formly_${currentFormId++}`\n let parentFormAttributes = ''\n if (attrs.hasOwnProperty('isFieldGroup') && el.parent().parent().hasClass('formly')) {\n parentFormAttributes = copyAttributes(el.parent().parent()[0].attributes)\n }\n return `\n <${rootEl} class=\"formly\"\n name=\"${getFormName()}\"\n role=\"form\" ${parentFormAttributes}>\n <${fieldRootEl} formly-field\n ng-repeat=\"field in fields ${getTrackBy()}\"\n ${getHideDirective()}=\"!field.hide\"\n class=\"formly-field\"\n options=\"field\"\n model=\"field.model || model\"\n original-model=\"model\"\n fields=\"fields\"\n form=\"theFormlyForm\"\n form-id=\"${getFormName()}\"\n form-state=\"options.formState\"\n form-options=\"options\"\n index=\"$index\">\n ${fieldRootEl}>\n
\n ${rootEl}>\n `\n\n function getRootEl() {\n return attrs.rootEl || 'ng-form'\n }\n\n function getFieldRootEl() {\n return attrs.fieldRootEl || 'div'\n }\n\n function getHideDirective() {\n return attrs.hideDirective || formlyConfig.extras.defaultHideDirective || 'ng-if'\n }\n\n function getTrackBy() {\n if (!attrs.trackBy) {\n return ''\n } else {\n return `track by ${attrs.trackBy}`\n }\n }\n\n function getFormName() {\n let formName = formId\n const bindName = attrs.bindName\n if (bindName) {\n if (angular.version.minor < 3) {\n throw formlyUsability.getFormlyError('bind-name attribute on formly-form not allowed in < angular 1.3')\n }\n // we can do a one-time binding here because we know we're in 1.3.x territory\n formName = `${$interpolate.startSymbol()}::'formly_' + ${bindName}${$interpolate.endSymbol()}`\n }\n return formName\n }\n\n function getTranscludeClass() {\n return attrs.transcludeClass || ''\n }\n\n function copyAttributes(attributes) {\n const excluded = ['model', 'form', 'fields', 'options', 'name', 'role', 'class',\n 'data-model', 'data-form', 'data-fields', 'data-options', 'data-name']\n const arrayAttrs = []\n angular.forEach(attributes, ({nodeName, value}) => {\n if (nodeName !== 'undefined' && excluded.indexOf(nodeName) === -1) {\n arrayAttrs.push(`${toKebabCase(nodeName)}=\"${value}\"`)\n }\n })\n return arrayAttrs.join(' ')\n }\n }\n\n // @ngInject\n function FormlyFormController($scope, formlyApiCheck, formlyUtil) {\n setupOptions()\n $scope.model = $scope.model || {}\n setupFields()\n\n // watch the model and evaluate watch expressions that depend on it.\n if (!$scope.options.manualModelWatcher) {\n $scope.$watch('model', onModelOrFormStateChange, true)\n } else if (angular.isFunction($scope.options.manualModelWatcher)) {\n $scope.$watch($scope.options.manualModelWatcher, onModelOrFormStateChange, true)\n }\n\n if ($scope.options.formState) {\n $scope.$watch('options.formState', onModelOrFormStateChange, true)\n }\n\n function onModelOrFormStateChange() {\n angular.forEach($scope.fields, runFieldExpressionProperties)\n }\n\n function validateFormControl(formControl, promise) {\n const validate = formControl.$validate\n if (promise) {\n promise.then(validate)\n } else {\n validate()\n }\n }\n\n function runFieldExpressionProperties(field, index) {\n const model = field.model || $scope.model\n const promise = field.runExpressions && field.runExpressions()\n if (field.hideExpression) { // can't use hide with expressionProperties reliably\n const val = model[field.key]\n field.hide = evalCloseToFormlyExpression(field.hideExpression, val, field, index, {model})\n }\n if (field.extras && field.extras.validateOnModelChange && field.formControl) {\n if (angular.isArray(field.formControl)) {\n angular.forEach(field.formControl, function(formControl) {\n validateFormControl(formControl, promise)\n })\n } else {\n validateFormControl(field.formControl, promise)\n }\n }\n }\n\n function setupFields() {\n $scope.fields = $scope.fields || []\n\n checkDeprecatedOptions($scope.options)\n\n let fieldTransforms = $scope.options.fieldTransform || formlyConfig.extras.fieldTransform\n\n if (!angular.isArray(fieldTransforms)) {\n fieldTransforms = [fieldTransforms]\n }\n\n angular.forEach(fieldTransforms, function transformFields(fieldTransform) {\n if (fieldTransform) {\n $scope.fields = fieldTransform($scope.fields, $scope.model, $scope.options, $scope.form)\n if (!$scope.fields) {\n throw formlyUsability.getFormlyError('fieldTransform must return an array of fields')\n }\n }\n })\n\n setupModels()\n\n if ($scope.options.watchAllExpressions) {\n angular.forEach($scope.fields, setupHideExpressionWatcher)\n }\n\n angular.forEach($scope.fields, attachKey) // attaches a key based on the index if a key isn't specified\n angular.forEach($scope.fields, setupWatchers) // setup watchers for all fields\n }\n\n function checkDeprecatedOptions(options) {\n if (formlyConfig.extras.fieldTransform && angular.isFunction(formlyConfig.extras.fieldTransform)) {\n formlyWarn(\n 'fieldtransform-as-a-function-deprecated',\n 'fieldTransform as a function has been deprecated.',\n `Attempted for formlyConfig.extras: ${formlyConfig.extras.fieldTransform.name}`,\n formlyConfig.extras\n )\n } else if (options.fieldTransform && angular.isFunction(options.fieldTransform)) {\n formlyWarn(\n 'fieldtransform-as-a-function-deprecated',\n 'fieldTransform as a function has been deprecated.',\n `Attempted for form`,\n options\n )\n }\n }\n\n function setupOptions() {\n formlyApiCheck.throw(\n [formlyApiCheck.formOptionsApi.optional], [$scope.options], {prefix: 'formly-form options check'}\n )\n $scope.options = $scope.options || {}\n $scope.options.formState = $scope.options.formState || {}\n\n angular.extend($scope.options, {\n updateInitialValue,\n resetModel,\n })\n\n }\n\n function updateInitialValue() {\n angular.forEach($scope.fields, field => {\n if (isFieldGroup(field) && field.options) {\n field.options.updateInitialValue()\n } else {\n field.updateInitialValue()\n }\n })\n }\n\n function resetModel() {\n angular.forEach($scope.fields, field => {\n if (isFieldGroup(field) && field.options) {\n field.options.resetModel()\n } else if (field.resetModel) {\n field.resetModel()\n }\n })\n }\n\n function setupModels() {\n // a set of field models that are already watched (the $scope.model will have its own watcher)\n const watchedModels = [$scope.model]\n // we will not set up automatic model watchers if manual mode is set\n const manualModelWatcher = $scope.options.manualModelWatcher\n\n if ($scope.options.formState) {\n // $scope.options.formState will have its own watcher\n watchedModels.push($scope.options.formState)\n }\n\n angular.forEach($scope.fields, (field) => {\n const isNewModel = initModel(field)\n\n if (field.model && isNewModel && watchedModels.indexOf(field.model) === -1 && !manualModelWatcher) {\n $scope.$watch(() => field.model, onModelOrFormStateChange, true)\n watchedModels.push(field.model)\n }\n })\n }\n\n function setupHideExpressionWatcher(field, index) {\n if (field.hideExpression) { // can't use hide with expressionProperties reliably\n const model = field.model || $scope.model\n $scope.$watch(function hideExpressionWatcher() {\n const val = model[field.key]\n return evalCloseToFormlyExpression(field.hideExpression, val, field, index, {model})\n }, (hide) => field.hide = hide, true)\n }\n }\n\n function initModel(field) {\n let isNewModel = true\n\n if (angular.isString(field.model)) {\n const expression = field.model\n\n isNewModel = !referencesCurrentlyWatchedModel(expression)\n\n field.model = resolveStringModel(expression)\n\n $scope.$watch(() => resolveStringModel(expression), (model) => field.model = model)\n }\n\n return isNewModel\n\n function resolveStringModel(expression) {\n const index = $scope.fields.indexOf(field)\n const model = evalCloseToFormlyExpression(expression, undefined, field, index, {model: $scope.model})\n\n if (!model) {\n throw formlyUsability.getFieldError(\n 'field-model-must-be-initialized',\n 'Field model must be initialized. When specifying a model as a string for a field, the result of the' +\n ' expression must have been initialized ahead of time.',\n field)\n }\n\n return model\n }\n }\n\n function referencesCurrentlyWatchedModel(expression) {\n return ['model', 'formState'].some(item => {\n return formlyUtil.startsWith(expression, `${item}.`) || formlyUtil.startsWith(expression, `${item}[`)\n })\n }\n\n function attachKey(field, index) {\n if (!isFieldGroup(field)) {\n field.key = field.key || index || 0\n }\n }\n\n function setupWatchers(field, index) {\n if (!angular.isDefined(field.watcher)) {\n return\n }\n let watchers = field.watcher\n if (!angular.isArray(watchers)) {\n watchers = [watchers]\n }\n angular.forEach(watchers, function setupWatcher(watcher) {\n if (!angular.isDefined(watcher.listener) && !watcher.runFieldExpressions) {\n throw formlyUsability.getFieldError(\n 'all-field-watchers-must-have-a-listener',\n 'All field watchers must have a listener', field\n )\n }\n const watchExpression = getWatchExpression(watcher, field, index)\n const watchListener = getWatchListener(watcher, field, index)\n\n const type = watcher.type || '$watch'\n watcher.stopWatching = $scope[type](watchExpression, watchListener, watcher.watchDeep)\n })\n }\n\n function getWatchExpression(watcher, field, index) {\n let watchExpression\n if (!angular.isUndefined(watcher.expression)) {\n watchExpression = watcher.expression\n } else if (field.key) {\n watchExpression = 'model[\\'' + field.key.toString().split('.').join('\\'][\\'') + '\\']'\n }\n if (angular.isFunction(watchExpression)) {\n // wrap the field's watch expression so we can call it with the field as the first arg\n // and the stop function as the last arg as a helper\n const originalExpression = watchExpression\n watchExpression = function formlyWatchExpression() {\n const args = modifyArgs(watcher, index, ...arguments)\n return originalExpression(...args)\n }\n watchExpression.displayName = `Formly Watch Expression for field for ${field.key}`\n } else if (field.model) {\n watchExpression = $parse(watchExpression).bind(null, $scope, {model: field.model})\n }\n return watchExpression\n }\n\n function getWatchListener(watcher, field, index) {\n let watchListener = watcher.listener\n if (angular.isFunction(watchListener) || watcher.runFieldExpressions) {\n // wrap the field's watch listener so we can call it with the field as the first arg\n // and the stop function as the last arg as a helper\n const originalListener = watchListener\n watchListener = function formlyWatchListener() {\n let value\n if (originalListener) {\n const args = modifyArgs(watcher, index, ...arguments)\n value = originalListener(...args)\n }\n if (watcher.runFieldExpressions) {\n runFieldExpressionProperties(field, index)\n }\n return value\n }\n watchListener.displayName = `Formly Watch Listener for field for ${field.key}`\n }\n return watchListener\n }\n\n function modifyArgs(watcher, index, ...originalArgs) {\n return [$scope.fields[index], ...originalArgs, watcher.stopWatching]\n }\n\n function evalCloseToFormlyExpression(expression, val, field, index, extraLocals = {}) {\n extraLocals = angular.extend(getFormlyFieldLikeLocals(field, index), extraLocals)\n return formlyUtil.formlyEval($scope, expression, val, val, extraLocals)\n }\n\n function getFormlyFieldLikeLocals(field, index) {\n // this makes it closer to what a regular formlyExpression would be\n return {\n model: field.model,\n options: field,\n index,\n formState: $scope.options.formState,\n originalModel: $scope.model,\n formOptions: $scope.options,\n formId: $scope.formId,\n }\n }\n }\n\n function formlyFormLink(scope, el, attrs) {\n setFormController()\n fixChromeAutocomplete()\n\n function setFormController() {\n const formId = attrs.name\n scope.formId = formId\n scope.theFormlyForm = scope[formId]\n if (attrs.form) {\n const getter = $parse(attrs.form)\n const setter = getter.assign\n const parentForm = getter(scope.$parent)\n if (parentForm) {\n scope.theFormlyForm = parentForm\n if (scope[formId]) {\n scope.theFormlyForm.$removeControl(scope[formId])\n }\n\n // this next line is probably one of the more dangerous things that angular-formly does to improve the\n // API for angular-formly forms. It ensures that the NgModelControllers inside of formly-form will be\n // attached to the form that is passed to formly-form rather than the one that formly-form creates\n // this is necessary because it's confusing to have a step between the form you pass in\n // and the fields in that form. It also is because angular doesn't propagate properties like $submitted down\n // to children forms :-( This line was added to solve this issue:\n // https://github.com/formly-js/angular-formly/issues/287\n // luckily, this is how the formController has been accessed by the NgModelController since angular 1.0.0\n // so I expect it will remain this way for the life of angular 1.x\n el.removeData('$formController')\n } else {\n setter(scope.$parent, scope[formId])\n }\n }\n if (!scope.theFormlyForm && !formlyConfig.disableWarnings) {\n /* eslint no-console:0 */\n formlyWarn(\n 'formly-form-has-no-formcontroller',\n 'Your formly-form does not have a `form` property. Many functions of the form (like validation) may not work',\n el,\n scope\n )\n }\n }\n\n /*\n * chrome autocomplete lameness\n * see https://code.google.com/p/chromium/issues/detail?id=468153#c14\n * ლ(ಠ益ಠლ) (╯°□°)╯︵ ┻━┻ (◞‸◟;)\n */\n function fixChromeAutocomplete() {\n const global = formlyConfig.extras.removeChromeAutoComplete === true\n const offInstance = scope.options && scope.options.removeChromeAutoComplete === false\n const onInstance = scope.options && scope.options.removeChromeAutoComplete === true\n if ((global && !offInstance) || onInstance) {\n const input = document.createElement('input')\n input.setAttribute('autocomplete', 'address-level4')\n input.setAttribute('hidden', 'true')\n el[0].appendChild(input)\n }\n\n }\n }\n\n\n // stateless util functions\n function toKebabCase(string) {\n if (string) {\n return string.replace(/([A-Z])/g, $1 => '-' + $1.toLowerCase())\n } else {\n return ''\n }\n }\n\n function isFieldGroup(field) {\n return field && !!field.fieldGroup\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./directives/formly-form.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nvar _providersFormlyApiCheck = require('./providers/formlyApiCheck');\n\nvar _providersFormlyApiCheck2 = _interopRequireDefault(_providersFormlyApiCheck);\n\nvar _otherDocsBaseUrl = require('./other/docsBaseUrl');\n\nvar _otherDocsBaseUrl2 = _interopRequireDefault(_otherDocsBaseUrl);\n\nvar _providersFormlyUsability = require('./providers/formlyUsability');\n\nvar _providersFormlyUsability2 = _interopRequireDefault(_providersFormlyUsability);\n\nvar _providersFormlyConfig = require('./providers/formlyConfig');\n\nvar _providersFormlyConfig2 = _interopRequireDefault(_providersFormlyConfig);\n\nvar _providersFormlyValidationMessages = require('./providers/formlyValidationMessages');\n\nvar _providersFormlyValidationMessages2 = _interopRequireDefault(_providersFormlyValidationMessages);\n\nvar _servicesFormlyUtil = require('./services/formlyUtil');\n\nvar _servicesFormlyUtil2 = _interopRequireDefault(_servicesFormlyUtil);\n\nvar _servicesFormlyWarn = require('./services/formlyWarn');\n\nvar _servicesFormlyWarn2 = _interopRequireDefault(_servicesFormlyWarn);\n\nvar _directivesFormlyCustomValidation = require('./directives/formly-custom-validation');\n\nvar _directivesFormlyCustomValidation2 = _interopRequireDefault(_directivesFormlyCustomValidation);\n\nvar _directivesFormlyField = require('./directives/formly-field');\n\nvar _directivesFormlyField2 = _interopRequireDefault(_directivesFormlyField);\n\nvar _directivesFormlyFocus = require('./directives/formly-focus');\n\nvar _directivesFormlyFocus2 = _interopRequireDefault(_directivesFormlyFocus);\n\nvar _directivesFormlyForm = require('./directives/formly-form');\n\nvar _directivesFormlyForm2 = _interopRequireDefault(_directivesFormlyForm);\n\nvar _runFormlyNgModelAttrsManipulator = require('./run/formlyNgModelAttrsManipulator');\n\nvar _runFormlyNgModelAttrsManipulator2 = _interopRequireDefault(_runFormlyNgModelAttrsManipulator);\n\nvar _runFormlyCustomTags = require('./run/formlyCustomTags');\n\nvar _runFormlyCustomTags2 = _interopRequireDefault(_runFormlyCustomTags);\n\nvar ngModuleName = 'formly';\n\nexports['default'] = ngModuleName;\n\nvar ngModule = _angularFix2['default'].module(ngModuleName, []);\n\nngModule.constant('formlyApiCheck', _providersFormlyApiCheck2['default']);\nngModule.constant('formlyErrorAndWarningsUrlPrefix', _otherDocsBaseUrl2['default']);\nngModule.constant('formlyVersion', VERSION); // <-- webpack variable\n\nngModule.provider('formlyUsability', _providersFormlyUsability2['default']);\nngModule.provider('formlyConfig', _providersFormlyConfig2['default']);\n\nngModule.factory('formlyValidationMessages', _providersFormlyValidationMessages2['default']);\nngModule.factory('formlyUtil', _servicesFormlyUtil2['default']);\nngModule.factory('formlyWarn', _servicesFormlyWarn2['default']);\n\nngModule.directive('formlyCustomValidation', _directivesFormlyCustomValidation2['default']);\nngModule.directive('formlyField', _directivesFormlyField2['default']);\nngModule.directive('formlyFocus', _directivesFormlyFocus2['default']);\nngModule.directive('formlyForm', _directivesFormlyForm2['default']);\n\nngModule.run(_runFormlyNgModelAttrsManipulator2['default']);\nngModule.run(_runFormlyCustomTags2['default']);\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./index.common.js\n **/","import angular from 'angular-fix'\n\nimport formlyApiCheck from './providers/formlyApiCheck'\nimport formlyErrorAndWarningsUrlPrefix from './other/docsBaseUrl'\nimport formlyUsability from './providers/formlyUsability'\nimport formlyConfig from './providers/formlyConfig'\nimport formlyValidationMessages from './providers/formlyValidationMessages'\nimport formlyUtil from './services/formlyUtil'\nimport formlyWarn from './services/formlyWarn'\n\nimport formlyCustomValidation from './directives/formly-custom-validation'\nimport formlyField from './directives/formly-field'\nimport formlyFocus from './directives/formly-focus'\nimport formlyForm from './directives/formly-form'\n\nimport formlyNgModelAttrsManipulator from './run/formlyNgModelAttrsManipulator'\nimport formlyCustomTags from './run/formlyCustomTags'\n\nconst ngModuleName = 'formly'\n\nexport default ngModuleName\n\nconst ngModule = angular.module(ngModuleName, [])\n\nngModule.constant('formlyApiCheck', formlyApiCheck)\nngModule.constant('formlyErrorAndWarningsUrlPrefix', formlyErrorAndWarningsUrlPrefix)\nngModule.constant('formlyVersion', VERSION) // <-- webpack variable\n\nngModule.provider('formlyUsability', formlyUsability)\nngModule.provider('formlyConfig', formlyConfig)\n\nngModule.factory('formlyValidationMessages', formlyValidationMessages)\nngModule.factory('formlyUtil', formlyUtil)\nngModule.factory('formlyWarn', formlyWarn)\n\nngModule.directive('formlyCustomValidation', formlyCustomValidation)\nngModule.directive('formlyField', formlyField)\nngModule.directive('formlyFocus', formlyFocus)\nngModule.directive('formlyForm', formlyForm)\n\nngModule.run(formlyNgModelAttrsManipulator)\nngModule.run(formlyCustomTags)\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./index.common.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nvar _apiCheck = require('api-check');\n\nvar _apiCheck2 = _interopRequireDefault(_apiCheck);\n\nvar apiCheck = (0, _apiCheck2['default'])({\n output: {\n prefix: 'angular-formly:',\n docsBaseUrl: require('../other/docsBaseUrl')\n }\n});\n\nfunction shapeRequiredIfNot(otherProps, propChecker) {\n if (!_angularFix2['default'].isArray(otherProps)) {\n otherProps = [otherProps];\n }\n var type = 'specified if these are not specified: `' + otherProps.join(', ') + '` (otherwise it\\'s optional)';\n\n function shapeRequiredIfNotDefinition(prop, propName, location, obj) {\n var propExists = obj && obj.hasOwnProperty(propName);\n var otherPropsExist = otherProps.some(function (otherProp) {\n return obj && obj.hasOwnProperty(otherProp);\n });\n if (!otherPropsExist && !propExists) {\n return apiCheck.utils.getError(propName, location, type);\n } else if (propExists) {\n return propChecker(prop, propName, location, obj);\n }\n }\n\n shapeRequiredIfNotDefinition.type = type;\n return apiCheck.utils.checkerHelpers.setupChecker(shapeRequiredIfNotDefinition);\n}\n\nvar formlyExpression = apiCheck.oneOfType([apiCheck.string, apiCheck.func]);\nvar specifyWrapperType = apiCheck.typeOrArrayOf(apiCheck.string).nullable;\n\nvar apiCheckProperty = apiCheck.func;\n\nvar apiCheckInstanceProperty = apiCheck.shape.onlyIf('apiCheck', apiCheck.func.withProperties({\n warn: apiCheck.func,\n 'throw': apiCheck.func,\n shape: apiCheck.func\n}));\n\nvar apiCheckFunctionProperty = apiCheck.shape.onlyIf('apiCheck', apiCheck.oneOf(['throw', 'warn']));\n\nvar formlyWrapperType = apiCheck.shape({\n name: shapeRequiredIfNot('types', apiCheck.string).optional,\n template: apiCheck.shape.ifNot('templateUrl', apiCheck.string).optional,\n templateUrl: apiCheck.shape.ifNot('template', apiCheck.string).optional,\n types: apiCheck.typeOrArrayOf(apiCheck.string).optional,\n overwriteOk: apiCheck.bool.optional,\n apiCheck: apiCheckProperty.optional,\n apiCheckInstance: apiCheckInstanceProperty.optional,\n apiCheckFunction: apiCheckFunctionProperty.optional,\n apiCheckOptions: apiCheck.object.optional\n}).strict;\n\nvar expressionProperties = apiCheck.objectOf(apiCheck.oneOfType([formlyExpression, apiCheck.shape({\n expression: formlyExpression,\n message: formlyExpression.optional\n}).strict]));\n\nvar modelChecker = apiCheck.oneOfType([apiCheck.string, apiCheck.object]);\n\nvar templateManipulators = apiCheck.shape({\n preWrapper: apiCheck.arrayOf(apiCheck.func).nullable.optional,\n postWrapper: apiCheck.arrayOf(apiCheck.func).nullable.optional\n}).strict.nullable;\n\nvar validatorChecker = apiCheck.objectOf(apiCheck.oneOfType([formlyExpression, apiCheck.shape({\n expression: formlyExpression,\n message: formlyExpression.optional\n}).strict]));\n\nvar watcherChecker = apiCheck.typeOrArrayOf(apiCheck.shape({\n expression: formlyExpression.optional,\n listener: formlyExpression.optional,\n runFieldExpressions: apiCheck.bool.optional\n}));\n\nvar fieldOptionsApiShape = {\n $$hashKey: apiCheck.any.optional,\n type: apiCheck.shape.ifNot(['template', 'templateUrl'], apiCheck.string).optional,\n template: apiCheck.shape.ifNot(['type', 'templateUrl'], apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n templateUrl: apiCheck.shape.ifNot(['type', 'template'], apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n key: apiCheck.oneOfType([apiCheck.string, apiCheck.number]).optional,\n model: modelChecker.optional,\n originalModel: modelChecker.optional,\n className: apiCheck.string.optional,\n id: apiCheck.string.optional,\n name: apiCheck.string.optional,\n expressionProperties: expressionProperties.optional,\n extras: apiCheck.shape({\n validateOnModelChange: apiCheck.bool.optional,\n skipNgModelAttrsManipulator: apiCheck.oneOfType([apiCheck.string, apiCheck.bool]).optional\n }).strict.optional,\n data: apiCheck.object.optional,\n templateOptions: apiCheck.object.optional,\n wrapper: specifyWrapperType.optional,\n modelOptions: apiCheck.shape({\n updateOn: apiCheck.string.optional,\n debounce: apiCheck.oneOfType([apiCheck.objectOf(apiCheck.number), apiCheck.number]).optional,\n allowInvalid: apiCheck.bool.optional,\n getterSetter: apiCheck.bool.optional,\n timezone: apiCheck.string.optional\n }).optional,\n watcher: watcherChecker.optional,\n validators: validatorChecker.optional,\n asyncValidators: validatorChecker.optional,\n parsers: apiCheck.arrayOf(formlyExpression).optional,\n formatters: apiCheck.arrayOf(formlyExpression).optional,\n noFormControl: apiCheck.bool.optional,\n hide: apiCheck.bool.optional,\n hideExpression: formlyExpression.optional,\n ngModelElAttrs: apiCheck.objectOf(apiCheck.string).optional,\n ngModelAttrs: apiCheck.objectOf(apiCheck.shape({\n statement: apiCheck.shape.ifNot(['value', 'attribute', 'bound', 'boolean'], apiCheck.any).optional,\n value: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n attribute: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n bound: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n boolean: apiCheck.shape.ifNot('statement', apiCheck.any).optional\n }).strict).optional,\n elementAttributes: apiCheck.objectOf(apiCheck.string).optional,\n optionsTypes: apiCheck.typeOrArrayOf(apiCheck.string).optional,\n link: apiCheck.func.optional,\n controller: apiCheck.oneOfType([apiCheck.string, apiCheck.func, apiCheck.array]).optional,\n validation: apiCheck.shape({\n show: apiCheck.bool.nullable.optional,\n messages: apiCheck.objectOf(formlyExpression).optional,\n errorExistsAndShouldBeVisible: apiCheck.bool.optional\n }).optional,\n formControl: apiCheck.typeOrArrayOf(apiCheck.object).optional,\n value: apiCheck.func.optional,\n runExpressions: apiCheck.func.optional,\n templateManipulators: templateManipulators.optional,\n resetModel: apiCheck.func.optional,\n updateInitialValue: apiCheck.func.optional,\n initialValue: apiCheck.any.optional,\n defaultValue: apiCheck.any.optional\n};\n\nvar formlyFieldOptions = apiCheck.shape(fieldOptionsApiShape).strict;\n\nvar formOptionsApi = apiCheck.shape({\n formState: apiCheck.object.optional,\n resetModel: apiCheck.func.optional,\n updateInitialValue: apiCheck.func.optional,\n removeChromeAutoComplete: apiCheck.bool.optional,\n templateManipulators: templateManipulators.optional,\n manualModelWatcher: apiCheck.oneOfType([apiCheck.bool, apiCheck.func]).optional,\n watchAllExpressions: apiCheck.bool.optional,\n wrapper: specifyWrapperType.optional,\n fieldTransform: apiCheck.oneOfType([apiCheck.func, apiCheck.array]).optional,\n data: apiCheck.object.optional\n}).strict;\n\nvar fieldGroup = apiCheck.shape({\n $$hashKey: apiCheck.any.optional,\n key: apiCheck.oneOfType([apiCheck.string, apiCheck.number]).optional,\n // danger. Nested field groups wont get api-checked...\n fieldGroup: apiCheck.arrayOf(apiCheck.oneOfType([formlyFieldOptions, apiCheck.object])),\n className: apiCheck.string.optional,\n options: formOptionsApi.optional,\n templateOptions: apiCheck.object.optional,\n wrapper: specifyWrapperType.optional,\n watcher: watcherChecker.optional,\n hide: apiCheck.bool.optional,\n hideExpression: formlyExpression.optional,\n data: apiCheck.object.optional,\n model: modelChecker.optional,\n form: apiCheck.object.optional,\n elementAttributes: apiCheck.objectOf(apiCheck.string).optional\n}).strict;\n\nvar typeOptionsDefaultOptions = _angularFix2['default'].copy(fieldOptionsApiShape);\ntypeOptionsDefaultOptions.key = apiCheck.string.optional;\n\nvar formlyTypeOptions = apiCheck.shape({\n name: apiCheck.string,\n template: apiCheck.shape.ifNot('templateUrl', apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n templateUrl: apiCheck.shape.ifNot('template', apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n controller: apiCheck.oneOfType([apiCheck.func, apiCheck.string, apiCheck.array]).optional,\n link: apiCheck.func.optional,\n defaultOptions: apiCheck.oneOfType([apiCheck.func, apiCheck.shape(typeOptionsDefaultOptions)]).optional,\n 'extends': apiCheck.string.optional,\n wrapper: specifyWrapperType.optional,\n data: apiCheck.object.optional,\n apiCheck: apiCheckProperty.optional,\n apiCheckInstance: apiCheckInstanceProperty.optional,\n apiCheckFunction: apiCheckFunctionProperty.optional,\n apiCheckOptions: apiCheck.object.optional,\n overwriteOk: apiCheck.bool.optional\n}).strict;\n\n_angularFix2['default'].extend(apiCheck, {\n formlyTypeOptions: formlyTypeOptions, formlyFieldOptions: formlyFieldOptions, formlyExpression: formlyExpression, formlyWrapperType: formlyWrapperType, fieldGroup: fieldGroup, formOptionsApi: formOptionsApi\n});\n\nexports['default'] = apiCheck;\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./providers/formlyApiCheck.js\n **/","import angular from 'angular-fix'\nimport apiCheckFactory from 'api-check'\n\nconst apiCheck = apiCheckFactory({\n output: {\n prefix: 'angular-formly:',\n docsBaseUrl: require('../other/docsBaseUrl'),\n },\n})\n\nfunction shapeRequiredIfNot(otherProps, propChecker) {\n if (!angular.isArray(otherProps)) {\n otherProps = [otherProps]\n }\n const type = `specified if these are not specified: \\`${otherProps.join(', ')}\\` (otherwise it's optional)`\n\n function shapeRequiredIfNotDefinition(prop, propName, location, obj) {\n const propExists = obj && obj.hasOwnProperty(propName)\n const otherPropsExist = otherProps.some(function(otherProp) {\n return obj && obj.hasOwnProperty(otherProp)\n })\n if (!otherPropsExist && !propExists) {\n return apiCheck.utils.getError(propName, location, type)\n } else if (propExists) {\n return propChecker(prop, propName, location, obj)\n }\n }\n\n shapeRequiredIfNotDefinition.type = type\n return apiCheck.utils.checkerHelpers.setupChecker(shapeRequiredIfNotDefinition)\n}\n\nconst formlyExpression = apiCheck.oneOfType([apiCheck.string, apiCheck.func])\nconst specifyWrapperType = apiCheck.typeOrArrayOf(apiCheck.string).nullable\n\nconst apiCheckProperty = apiCheck.func\n\nconst apiCheckInstanceProperty = apiCheck.shape.onlyIf('apiCheck', apiCheck.func.withProperties({\n warn: apiCheck.func,\n throw: apiCheck.func,\n shape: apiCheck.func,\n}))\n\nconst apiCheckFunctionProperty = apiCheck.shape.onlyIf('apiCheck', apiCheck.oneOf(['throw', 'warn']))\n\nconst formlyWrapperType = apiCheck.shape({\n name: shapeRequiredIfNot('types', apiCheck.string).optional,\n template: apiCheck.shape.ifNot('templateUrl', apiCheck.string).optional,\n templateUrl: apiCheck.shape.ifNot('template', apiCheck.string).optional,\n types: apiCheck.typeOrArrayOf(apiCheck.string).optional,\n overwriteOk: apiCheck.bool.optional,\n apiCheck: apiCheckProperty.optional,\n apiCheckInstance: apiCheckInstanceProperty.optional,\n apiCheckFunction: apiCheckFunctionProperty.optional,\n apiCheckOptions: apiCheck.object.optional,\n}).strict\n\nconst expressionProperties = apiCheck.objectOf(apiCheck.oneOfType([\n formlyExpression,\n apiCheck.shape({\n expression: formlyExpression,\n message: formlyExpression.optional,\n }).strict,\n]))\n\nconst modelChecker = apiCheck.oneOfType([apiCheck.string, apiCheck.object])\n\nconst templateManipulators = apiCheck.shape({\n preWrapper: apiCheck.arrayOf(apiCheck.func).nullable.optional,\n postWrapper: apiCheck.arrayOf(apiCheck.func).nullable.optional,\n}).strict.nullable\n\nconst validatorChecker = apiCheck.objectOf(apiCheck.oneOfType([\n formlyExpression, apiCheck.shape({\n expression: formlyExpression,\n message: formlyExpression.optional,\n }).strict,\n]))\n\nconst watcherChecker = apiCheck.typeOrArrayOf(\n apiCheck.shape({\n expression: formlyExpression.optional,\n listener: formlyExpression.optional,\n runFieldExpressions: apiCheck.bool.optional,\n })\n)\n\nconst fieldOptionsApiShape = {\n $$hashKey: apiCheck.any.optional,\n type: apiCheck.shape.ifNot(['template', 'templateUrl'], apiCheck.string).optional,\n template: apiCheck.shape.ifNot(\n ['type', 'templateUrl'],\n apiCheck.oneOfType([apiCheck.string, apiCheck.func])\n ).optional,\n templateUrl: apiCheck.shape.ifNot(\n ['type', 'template'],\n apiCheck.oneOfType([apiCheck.string, apiCheck.func])\n ).optional,\n key: apiCheck.oneOfType([apiCheck.string, apiCheck.number]).optional,\n model: modelChecker.optional,\n originalModel: modelChecker.optional,\n className: apiCheck.string.optional,\n id: apiCheck.string.optional,\n name: apiCheck.string.optional,\n expressionProperties: expressionProperties.optional,\n extras: apiCheck.shape({\n validateOnModelChange: apiCheck.bool.optional,\n skipNgModelAttrsManipulator: apiCheck.oneOfType([\n apiCheck.string, apiCheck.bool,\n ]).optional,\n }).strict.optional,\n data: apiCheck.object.optional,\n templateOptions: apiCheck.object.optional,\n wrapper: specifyWrapperType.optional,\n modelOptions: apiCheck.shape({\n updateOn: apiCheck.string.optional,\n debounce: apiCheck.oneOfType([\n apiCheck.objectOf(apiCheck.number), apiCheck.number,\n ]).optional,\n allowInvalid: apiCheck.bool.optional,\n getterSetter: apiCheck.bool.optional,\n timezone: apiCheck.string.optional,\n }).optional,\n watcher: watcherChecker.optional,\n validators: validatorChecker.optional,\n asyncValidators: validatorChecker.optional,\n parsers: apiCheck.arrayOf(formlyExpression).optional,\n formatters: apiCheck.arrayOf(formlyExpression).optional,\n noFormControl: apiCheck.bool.optional,\n hide: apiCheck.bool.optional,\n hideExpression: formlyExpression.optional,\n ngModelElAttrs: apiCheck.objectOf(apiCheck.string).optional,\n ngModelAttrs: apiCheck.objectOf(apiCheck.shape({\n statement: apiCheck.shape.ifNot(['value', 'attribute', 'bound', 'boolean'], apiCheck.any).optional,\n value: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n attribute: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n bound: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n boolean: apiCheck.shape.ifNot('statement', apiCheck.any).optional,\n }).strict).optional,\n elementAttributes: apiCheck.objectOf(apiCheck.string).optional,\n optionsTypes: apiCheck.typeOrArrayOf(apiCheck.string).optional,\n link: apiCheck.func.optional,\n controller: apiCheck.oneOfType([\n apiCheck.string, apiCheck.func, apiCheck.array,\n ]).optional,\n validation: apiCheck.shape({\n show: apiCheck.bool.nullable.optional,\n messages: apiCheck.objectOf(formlyExpression).optional,\n errorExistsAndShouldBeVisible: apiCheck.bool.optional,\n }).optional,\n formControl: apiCheck.typeOrArrayOf(apiCheck.object).optional,\n value: apiCheck.func.optional,\n runExpressions: apiCheck.func.optional,\n templateManipulators: templateManipulators.optional,\n resetModel: apiCheck.func.optional,\n updateInitialValue: apiCheck.func.optional,\n initialValue: apiCheck.any.optional,\n defaultValue: apiCheck.any.optional,\n}\n\n\nconst formlyFieldOptions = apiCheck.shape(fieldOptionsApiShape).strict\n\nconst formOptionsApi = apiCheck.shape({\n formState: apiCheck.object.optional,\n resetModel: apiCheck.func.optional,\n updateInitialValue: apiCheck.func.optional,\n removeChromeAutoComplete: apiCheck.bool.optional,\n templateManipulators: templateManipulators.optional,\n manualModelWatcher: apiCheck.oneOfType([apiCheck.bool, apiCheck.func]).optional,\n watchAllExpressions: apiCheck.bool.optional,\n wrapper: specifyWrapperType.optional,\n fieldTransform: apiCheck.oneOfType([\n apiCheck.func, apiCheck.array,\n ]).optional,\n data: apiCheck.object.optional,\n}).strict\n\n\nconst fieldGroup = apiCheck.shape({\n $$hashKey: apiCheck.any.optional,\n key: apiCheck.oneOfType([apiCheck.string, apiCheck.number]).optional,\n // danger. Nested field groups wont get api-checked...\n fieldGroup: apiCheck.arrayOf(apiCheck.oneOfType([formlyFieldOptions, apiCheck.object])),\n className: apiCheck.string.optional,\n options: formOptionsApi.optional,\n templateOptions: apiCheck.object.optional,\n wrapper: specifyWrapperType.optional,\n watcher: watcherChecker.optional,\n hide: apiCheck.bool.optional,\n hideExpression: formlyExpression.optional,\n data: apiCheck.object.optional,\n model: modelChecker.optional,\n form: apiCheck.object.optional,\n elementAttributes: apiCheck.objectOf(apiCheck.string).optional,\n}).strict\n\nconst typeOptionsDefaultOptions = angular.copy(fieldOptionsApiShape)\ntypeOptionsDefaultOptions.key = apiCheck.string.optional\n\nconst formlyTypeOptions = apiCheck.shape({\n name: apiCheck.string,\n template: apiCheck.shape.ifNot('templateUrl', apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n templateUrl: apiCheck.shape.ifNot('template', apiCheck.oneOfType([apiCheck.string, apiCheck.func])).optional,\n controller: apiCheck.oneOfType([\n apiCheck.func, apiCheck.string, apiCheck.array,\n ]).optional,\n link: apiCheck.func.optional,\n defaultOptions: apiCheck.oneOfType([\n apiCheck.func, apiCheck.shape(typeOptionsDefaultOptions),\n ]).optional,\n extends: apiCheck.string.optional,\n wrapper: specifyWrapperType.optional,\n data: apiCheck.object.optional,\n apiCheck: apiCheckProperty.optional,\n apiCheckInstance: apiCheckInstanceProperty.optional,\n apiCheckFunction: apiCheckFunctionProperty.optional,\n apiCheckOptions: apiCheck.object.optional,\n overwriteOk: apiCheck.bool.optional,\n}).strict\n\nangular.extend(apiCheck, {\n formlyTypeOptions, formlyFieldOptions, formlyExpression, formlyWrapperType, fieldGroup, formOptionsApi,\n})\n\nexport default apiCheck\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./providers/formlyApiCheck.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nvar _otherUtils = require('../other/utils');\n\nvar _otherUtils2 = _interopRequireDefault(_otherUtils);\n\nexports['default'] = formlyConfig;\n\n// @ngInject\nfunction formlyConfig(formlyUsabilityProvider, formlyErrorAndWarningsUrlPrefix, formlyApiCheck) {\n var _this2 = this;\n\n var typeMap = {};\n var templateWrappersMap = {};\n var defaultWrapperName = 'default';\n var _this = this;\n var getError = formlyUsabilityProvider.getFormlyError;\n\n _angularFix2['default'].extend(this, {\n setType: setType,\n getType: getType,\n getTypeHeritage: getTypeHeritage,\n setWrapper: setWrapper,\n getWrapper: getWrapper,\n getWrapperByType: getWrapperByType,\n removeWrapperByName: removeWrapperByName,\n removeWrappersForType: removeWrappersForType,\n disableWarnings: false,\n extras: {\n disableNgModelAttrsManipulator: false,\n fieldTransform: [],\n ngModelAttrsManipulatorPreferUnbound: false,\n removeChromeAutoComplete: false,\n defaultHideDirective: 'ng-if',\n getFieldId: null\n },\n templateManipulators: {\n preWrapper: [],\n postWrapper: []\n },\n $get: function $get() {\n return _this2;\n }\n });\n\n function setType(options) {\n if (_angularFix2['default'].isArray(options)) {\n var _ret = (function () {\n var allTypes = [];\n _angularFix2['default'].forEach(options, function (item) {\n allTypes.push(setType(item));\n });\n return {\n v: allTypes\n };\n })();\n\n if (typeof _ret === 'object') return _ret.v;\n } else if (_angularFix2['default'].isObject(options)) {\n checkType(options);\n if (options['extends']) {\n extendTypeOptions(options);\n }\n typeMap[options.name] = options;\n return typeMap[options.name];\n } else {\n throw getError('You must provide an object or array for setType. You provided: ' + JSON.stringify(arguments));\n }\n }\n\n function checkType(options) {\n formlyApiCheck['throw'](formlyApiCheck.formlyTypeOptions, options, {\n prefix: 'formlyConfig.setType',\n url: 'settype-validation-failed'\n });\n if (!options.overwriteOk) {\n checkOverwrite(options.name, typeMap, options, 'types');\n } else {\n options.overwriteOk = undefined;\n }\n }\n\n function extendTypeOptions(options) {\n var extendsType = getType(options['extends'], true, options);\n extendTypeControllerFunction(options, extendsType);\n extendTypeLinkFunction(options, extendsType);\n extendTypeDefaultOptions(options, extendsType);\n _otherUtils2['default'].reverseDeepMerge(options, extendsType);\n extendTemplate(options, extendsType);\n }\n\n function extendTemplate(options, extendsType) {\n if (options.template && extendsType.templateUrl) {\n delete options.templateUrl;\n } else if (options.templateUrl && extendsType.template) {\n delete options.template;\n }\n }\n\n function extendTypeControllerFunction(options, extendsType) {\n var extendsCtrl = extendsType.controller;\n if (!_angularFix2['default'].isDefined(extendsCtrl)) {\n return;\n }\n var optionsCtrl = options.controller;\n if (_angularFix2['default'].isDefined(optionsCtrl)) {\n options.controller = function ($scope, $controller) {\n $controller(extendsCtrl, { $scope: $scope });\n $controller(optionsCtrl, { $scope: $scope });\n };\n options.controller.$inject = ['$scope', '$controller'];\n } else {\n options.controller = extendsCtrl;\n }\n }\n\n function extendTypeLinkFunction(options, extendsType) {\n var extendsFn = extendsType.link;\n if (!_angularFix2['default'].isDefined(extendsFn)) {\n return;\n }\n var optionsFn = options.link;\n if (_angularFix2['default'].isDefined(optionsFn)) {\n options.link = function () {\n extendsFn.apply(undefined, arguments);\n optionsFn.apply(undefined, arguments);\n };\n } else {\n options.link = extendsFn;\n }\n }\n\n function extendTypeDefaultOptions(options, extendsType) {\n var extendsDO = extendsType.defaultOptions;\n if (!_angularFix2['default'].isDefined(extendsDO)) {\n return;\n }\n var optionsDO = options.defaultOptions;\n var optionsDOIsFn = _angularFix2['default'].isFunction(optionsDO);\n var extendsDOIsFn = _angularFix2['default'].isFunction(extendsDO);\n if (extendsDOIsFn) {\n options.defaultOptions = function defaultOptions(opts, scope) {\n var extendsDefaultOptions = extendsDO(opts, scope);\n var mergedDefaultOptions = {};\n _otherUtils2['default'].reverseDeepMerge(mergedDefaultOptions, opts, extendsDefaultOptions);\n var extenderOptionsDefaultOptions = optionsDO;\n if (optionsDOIsFn) {\n extenderOptionsDefaultOptions = extenderOptionsDefaultOptions(mergedDefaultOptions, scope);\n }\n _otherUtils2['default'].reverseDeepMerge(extendsDefaultOptions, extenderOptionsDefaultOptions);\n return extendsDefaultOptions;\n };\n } else if (optionsDOIsFn) {\n options.defaultOptions = function defaultOptions(opts, scope) {\n var newDefaultOptions = {};\n _otherUtils2['default'].reverseDeepMerge(newDefaultOptions, opts, extendsDO);\n return optionsDO(newDefaultOptions, scope);\n };\n }\n }\n\n function getType(name, throwError, errorContext) {\n if (!name) {\n return undefined;\n }\n var type = typeMap[name];\n if (!type && throwError === true) {\n throw getError('There is no type by the name of \"' + name + '\": ' + JSON.stringify(errorContext));\n } else {\n return type;\n }\n }\n\n function getTypeHeritage(parent) {\n var heritage = [];\n var type = parent;\n if (_angularFix2['default'].isString(type)) {\n type = getType(parent);\n }\n parent = type['extends'];\n while (parent) {\n type = getType(parent);\n heritage.push(type);\n parent = type['extends'];\n }\n return heritage;\n }\n\n function setWrapper(_x, _x2) {\n var _again = true;\n\n _function: while (_again) {\n var options = _x,\n name = _x2;\n _again = false;\n\n if (_angularFix2['default'].isArray(options)) {\n return options.map(function (wrapperOptions) {\n return setWrapper(wrapperOptions);\n });\n } else if (_angularFix2['default'].isObject(options)) {\n options.types = getOptionsTypes(options);\n options.name = getOptionsName(options, name);\n checkWrapperAPI(options);\n templateWrappersMap[options.name] = options;\n return options;\n } else if (_angularFix2['default'].isString(options)) {\n _x = {\n template: options,\n name: name\n };\n _x2 = undefined;\n _again = true;\n continue _function;\n }\n }\n }\n\n function getOptionsTypes(options) {\n if (_angularFix2['default'].isString(options.types)) {\n return [options.types];\n }\n if (!_angularFix2['default'].isDefined(options.types)) {\n return [];\n } else {\n return options.types;\n }\n }\n\n function getOptionsName(options, name) {\n return options.name || name || options.types.join(' ') || defaultWrapperName;\n }\n\n function checkWrapperAPI(options) {\n formlyUsabilityProvider.checkWrapper(options);\n if (options.template) {\n formlyUsabilityProvider.checkWrapperTemplate(options.template, options);\n }\n if (!options.overwriteOk) {\n checkOverwrite(options.name, templateWrappersMap, options, 'templateWrappers');\n } else {\n delete options.overwriteOk;\n }\n checkWrapperTypes(options);\n }\n\n function checkWrapperTypes(options) {\n var shouldThrow = !_angularFix2['default'].isArray(options.types) || !options.types.every(_angularFix2['default'].isString);\n if (shouldThrow) {\n throw getError('Attempted to create a template wrapper with types that is not a string or an array of strings');\n }\n }\n\n function checkOverwrite(property, object, newValue, objectName) {\n if (object.hasOwnProperty(property)) {\n warn('overwriting-types-or-wrappers', ['Attempting to overwrite ' + property + ' on ' + objectName + ' which is currently', JSON.stringify(object[property]) + ' with ' + JSON.stringify(newValue), 'To supress this warning, specify the property \"overwriteOk: true\"'].join(' '));\n }\n }\n\n function getWrapper(name) {\n return templateWrappersMap[name || defaultWrapperName];\n }\n\n function getWrapperByType(type) {\n /* eslint prefer-const:0 */\n var wrappers = [];\n for (var _name in templateWrappersMap) {\n if (templateWrappersMap.hasOwnProperty(_name)) {\n if (templateWrappersMap[_name].types && templateWrappersMap[_name].types.indexOf(type) !== -1) {\n wrappers.push(templateWrappersMap[_name]);\n }\n }\n }\n return wrappers;\n }\n\n function removeWrapperByName(name) {\n var wrapper = templateWrappersMap[name];\n delete templateWrappersMap[name];\n return wrapper;\n }\n\n function removeWrappersForType(type) {\n var wrappers = getWrapperByType(type);\n if (!wrappers) {\n return undefined;\n }\n if (!_angularFix2['default'].isArray(wrappers)) {\n return removeWrapperByName(wrappers.name);\n } else {\n wrappers.forEach(function (wrapper) {\n return removeWrapperByName(wrapper.name);\n });\n return wrappers;\n }\n }\n\n function warn() {\n if (!_this.disableWarnings && console.warn) {\n /* eslint no-console:0 */\n var args = Array.prototype.slice.call(arguments);\n var warnInfoSlug = args.shift();\n args.unshift('Formly Warning:');\n args.push('' + formlyErrorAndWarningsUrlPrefix + warnInfoSlug);\n console.warn.apply(console, _toConsumableArray(args));\n }\n }\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./providers/formlyConfig.js\n **/","import angular from 'angular-fix'\nimport utils from '../other/utils'\n\nexport default formlyConfig\n\n// @ngInject\nfunction formlyConfig(formlyUsabilityProvider, formlyErrorAndWarningsUrlPrefix, formlyApiCheck) {\n\n const typeMap = {}\n const templateWrappersMap = {}\n const defaultWrapperName = 'default'\n const _this = this\n const getError = formlyUsabilityProvider.getFormlyError\n\n angular.extend(this, {\n setType,\n getType,\n getTypeHeritage,\n setWrapper,\n getWrapper,\n getWrapperByType,\n removeWrapperByName,\n removeWrappersForType,\n disableWarnings: false,\n extras: {\n disableNgModelAttrsManipulator: false,\n fieldTransform: [],\n ngModelAttrsManipulatorPreferUnbound: false,\n removeChromeAutoComplete: false,\n defaultHideDirective: 'ng-if',\n getFieldId: null,\n },\n templateManipulators: {\n preWrapper: [],\n postWrapper: [],\n },\n $get: () => this,\n })\n\n function setType(options) {\n if (angular.isArray(options)) {\n const allTypes = []\n angular.forEach(options, item => {\n allTypes.push(setType(item))\n })\n return allTypes\n } else if (angular.isObject(options)) {\n checkType(options)\n if (options.extends) {\n extendTypeOptions(options)\n }\n typeMap[options.name] = options\n return typeMap[options.name]\n } else {\n throw getError(`You must provide an object or array for setType. You provided: ${JSON.stringify(arguments)}`)\n }\n }\n\n function checkType(options) {\n formlyApiCheck.throw(formlyApiCheck.formlyTypeOptions, options, {\n prefix: 'formlyConfig.setType',\n url: 'settype-validation-failed',\n })\n if (!options.overwriteOk) {\n checkOverwrite(options.name, typeMap, options, 'types')\n } else {\n options.overwriteOk = undefined\n }\n }\n\n function extendTypeOptions(options) {\n const extendsType = getType(options.extends, true, options)\n extendTypeControllerFunction(options, extendsType)\n extendTypeLinkFunction(options, extendsType)\n extendTypeDefaultOptions(options, extendsType)\n utils.reverseDeepMerge(options, extendsType)\n extendTemplate(options, extendsType)\n }\n\n function extendTemplate(options, extendsType) {\n if (options.template && extendsType.templateUrl) {\n delete options.templateUrl\n } else if (options.templateUrl && extendsType.template) {\n delete options.template\n }\n }\n\n function extendTypeControllerFunction(options, extendsType) {\n const extendsCtrl = extendsType.controller\n if (!angular.isDefined(extendsCtrl)) {\n return\n }\n const optionsCtrl = options.controller\n if (angular.isDefined(optionsCtrl)) {\n options.controller = function($scope, $controller) {\n $controller(extendsCtrl, {$scope})\n $controller(optionsCtrl, {$scope})\n }\n options.controller.$inject = ['$scope', '$controller']\n } else {\n options.controller = extendsCtrl\n }\n }\n\n function extendTypeLinkFunction(options, extendsType) {\n const extendsFn = extendsType.link\n if (!angular.isDefined(extendsFn)) {\n return\n }\n const optionsFn = options.link\n if (angular.isDefined(optionsFn)) {\n options.link = function() {\n extendsFn(...arguments)\n optionsFn(...arguments)\n }\n } else {\n options.link = extendsFn\n }\n }\n\n function extendTypeDefaultOptions(options, extendsType) {\n const extendsDO = extendsType.defaultOptions\n if (!angular.isDefined(extendsDO)) {\n return\n }\n const optionsDO = options.defaultOptions\n const optionsDOIsFn = angular.isFunction(optionsDO)\n const extendsDOIsFn = angular.isFunction(extendsDO)\n if (extendsDOIsFn) {\n options.defaultOptions = function defaultOptions(opts, scope) {\n const extendsDefaultOptions = extendsDO(opts, scope)\n const mergedDefaultOptions = {}\n utils.reverseDeepMerge(mergedDefaultOptions, opts, extendsDefaultOptions)\n let extenderOptionsDefaultOptions = optionsDO\n if (optionsDOIsFn) {\n extenderOptionsDefaultOptions = extenderOptionsDefaultOptions(mergedDefaultOptions, scope)\n }\n utils.reverseDeepMerge(extendsDefaultOptions, extenderOptionsDefaultOptions)\n return extendsDefaultOptions\n }\n } else if (optionsDOIsFn) {\n options.defaultOptions = function defaultOptions(opts, scope) {\n const newDefaultOptions = {}\n utils.reverseDeepMerge(newDefaultOptions, opts, extendsDO)\n return optionsDO(newDefaultOptions, scope)\n }\n }\n }\n\n function getType(name, throwError, errorContext) {\n if (!name) {\n return undefined\n }\n const type = typeMap[name]\n if (!type && throwError === true) {\n throw getError(\n `There is no type by the name of \"${name}\": ${JSON.stringify(errorContext)}`\n )\n } else {\n return type\n }\n }\n\n function getTypeHeritage(parent) {\n const heritage = []\n let type = parent\n if (angular.isString(type)) {\n type = getType(parent)\n }\n parent = type.extends\n while (parent) {\n type = getType(parent)\n heritage.push(type)\n parent = type.extends\n }\n return heritage\n }\n\n\n function setWrapper(options, name) {\n if (angular.isArray(options)) {\n return options.map(wrapperOptions => setWrapper(wrapperOptions))\n } else if (angular.isObject(options)) {\n options.types = getOptionsTypes(options)\n options.name = getOptionsName(options, name)\n checkWrapperAPI(options)\n templateWrappersMap[options.name] = options\n return options\n } else if (angular.isString(options)) {\n return setWrapper({\n template: options,\n name,\n })\n }\n }\n\n function getOptionsTypes(options) {\n if (angular.isString(options.types)) {\n return [options.types]\n }\n if (!angular.isDefined(options.types)) {\n return []\n } else {\n return options.types\n }\n }\n\n function getOptionsName(options, name) {\n return options.name || name || options.types.join(' ') || defaultWrapperName\n }\n\n function checkWrapperAPI(options) {\n formlyUsabilityProvider.checkWrapper(options)\n if (options.template) {\n formlyUsabilityProvider.checkWrapperTemplate(options.template, options)\n }\n if (!options.overwriteOk) {\n checkOverwrite(options.name, templateWrappersMap, options, 'templateWrappers')\n } else {\n delete options.overwriteOk\n }\n checkWrapperTypes(options)\n }\n\n function checkWrapperTypes(options) {\n const shouldThrow = !angular.isArray(options.types) || !options.types.every(angular.isString)\n if (shouldThrow) {\n throw getError(`Attempted to create a template wrapper with types that is not a string or an array of strings`)\n }\n }\n\n function checkOverwrite(property, object, newValue, objectName) {\n if (object.hasOwnProperty(property)) {\n warn('overwriting-types-or-wrappers', [\n `Attempting to overwrite ${property} on ${objectName} which is currently`,\n `${JSON.stringify(object[property])} with ${JSON.stringify(newValue)}`,\n `To supress this warning, specify the property \"overwriteOk: true\"`,\n ].join(' '))\n }\n }\n\n function getWrapper(name) {\n return templateWrappersMap[name || defaultWrapperName]\n }\n\n function getWrapperByType(type) {\n /* eslint prefer-const:0 */\n const wrappers = []\n for (let name in templateWrappersMap) {\n if (templateWrappersMap.hasOwnProperty(name)) {\n if (templateWrappersMap[name].types && templateWrappersMap[name].types.indexOf(type) !== -1) {\n wrappers.push(templateWrappersMap[name])\n }\n }\n }\n return wrappers\n }\n\n function removeWrapperByName(name) {\n const wrapper = templateWrappersMap[name]\n delete templateWrappersMap[name]\n return wrapper\n }\n\n function removeWrappersForType(type) {\n const wrappers = getWrapperByType(type)\n if (!wrappers) {\n return undefined\n }\n if (!angular.isArray(wrappers)) {\n return removeWrapperByName(wrappers.name)\n } else {\n wrappers.forEach((wrapper) => removeWrapperByName(wrapper.name))\n return wrappers\n }\n }\n\n\n function warn() {\n if (!_this.disableWarnings && console.warn) {\n /* eslint no-console:0 */\n const args = Array.prototype.slice.call(arguments)\n const warnInfoSlug = args.shift()\n args.unshift('Formly Warning:')\n args.push(`${formlyErrorAndWarningsUrlPrefix}${warnInfoSlug}`)\n console.warn(...args)\n }\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./providers/formlyConfig.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nexports['default'] = formlyUsability;\n\n// @ngInject\nfunction formlyUsability(formlyApiCheck, formlyErrorAndWarningsUrlPrefix) {\n var _this = this;\n\n _angularFix2['default'].extend(this, {\n getFormlyError: getFormlyError,\n getFieldError: getFieldError,\n checkWrapper: checkWrapper,\n checkWrapperTemplate: checkWrapperTemplate,\n getErrorMessage: getErrorMessage,\n $get: function $get() {\n return _this;\n }\n });\n\n function getFieldError(errorInfoSlug, message, field) {\n if (arguments.length < 3) {\n field = message;\n message = errorInfoSlug;\n errorInfoSlug = null;\n }\n return new Error(getErrorMessage(errorInfoSlug, message) + (' Field definition: ' + _angularFix2['default'].toJson(field)));\n }\n\n function getFormlyError(errorInfoSlug, message) {\n if (!message) {\n message = errorInfoSlug;\n errorInfoSlug = null;\n }\n return new Error(getErrorMessage(errorInfoSlug, message));\n }\n\n function getErrorMessage(errorInfoSlug, message) {\n var url = '';\n if (errorInfoSlug !== null) {\n url = '' + formlyErrorAndWarningsUrlPrefix + errorInfoSlug;\n }\n return 'Formly Error: ' + message + '. ' + url;\n }\n\n function checkWrapper(wrapper) {\n formlyApiCheck['throw'](formlyApiCheck.formlyWrapperType, wrapper, {\n prefix: 'formlyConfig.setWrapper',\n urlSuffix: 'setwrapper-validation-failed'\n });\n }\n\n function checkWrapperTemplate(template, additionalInfo) {\n var formlyTransclude = ' ';\n if (template.indexOf(formlyTransclude) === -1) {\n throw getFormlyError('Template wrapper templates must use \"' + formlyTransclude + '\" somewhere in them. ' + ('This one does not have \" \" in it: ' + template) + '\\n' + ('Additional information: ' + JSON.stringify(additionalInfo)));\n }\n }\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./providers/formlyUsability.js\n **/","import angular from 'angular-fix'\n\nexport default formlyUsability\n\n// @ngInject\nfunction formlyUsability(formlyApiCheck, formlyErrorAndWarningsUrlPrefix) {\n angular.extend(this, {\n getFormlyError,\n getFieldError,\n checkWrapper,\n checkWrapperTemplate,\n getErrorMessage,\n $get: () => this,\n })\n\n function getFieldError(errorInfoSlug, message, field) {\n if (arguments.length < 3) {\n field = message\n message = errorInfoSlug\n errorInfoSlug = null\n }\n return new Error(getErrorMessage(errorInfoSlug, message) + ` Field definition: ${angular.toJson(field)}`)\n }\n\n function getFormlyError(errorInfoSlug, message) {\n if (!message) {\n message = errorInfoSlug\n errorInfoSlug = null\n }\n return new Error(getErrorMessage(errorInfoSlug, message))\n }\n\n function getErrorMessage(errorInfoSlug, message) {\n let url = ''\n if (errorInfoSlug !== null) {\n url = `${formlyErrorAndWarningsUrlPrefix}${errorInfoSlug}`\n }\n return `Formly Error: ${message}. ${url}`\n }\n\n function checkWrapper(wrapper) {\n formlyApiCheck.throw(formlyApiCheck.formlyWrapperType, wrapper, {\n prefix: 'formlyConfig.setWrapper',\n urlSuffix: 'setwrapper-validation-failed',\n })\n }\n\n function checkWrapperTemplate(template, additionalInfo) {\n const formlyTransclude = ' '\n if (template.indexOf(formlyTransclude) === -1) {\n throw getFormlyError(\n `Template wrapper templates must use \"${formlyTransclude}\" somewhere in them. ` +\n `This one does not have \" \" in it: ${template}` + '\\n' +\n `Additional information: ${JSON.stringify(additionalInfo)}`\n )\n }\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./providers/formlyUsability.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\nexports['default'] = formlyValidationMessages;\n\n// @ngInject\nfunction formlyValidationMessages() {\n\n var validationMessages = {\n addTemplateOptionValueMessage: addTemplateOptionValueMessage,\n addStringMessage: addStringMessage,\n messages: {}\n };\n\n return validationMessages;\n\n function addTemplateOptionValueMessage(name, prop, prefix, suffix, alternate) {\n validationMessages.messages[name] = templateOptionValue(prop, prefix, suffix, alternate);\n }\n\n function addStringMessage(name, string) {\n validationMessages.messages[name] = function () {\n return string;\n };\n }\n\n function templateOptionValue(prop, prefix, suffix, alternate) {\n return function getValidationMessage(viewValue, modelValue, scope) {\n if (typeof scope.options.templateOptions[prop] !== 'undefined') {\n return prefix + ' ' + scope.options.templateOptions[prop] + ' ' + suffix;\n } else {\n return alternate;\n }\n };\n }\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./providers/formlyValidationMessages.js\n **/","export default formlyValidationMessages\n\n\n// @ngInject\nfunction formlyValidationMessages() {\n\n const validationMessages = {\n addTemplateOptionValueMessage,\n addStringMessage,\n messages: {},\n }\n\n return validationMessages\n\n function addTemplateOptionValueMessage(name, prop, prefix, suffix, alternate) {\n validationMessages.messages[name] = templateOptionValue(prop, prefix, suffix, alternate)\n }\n\n function addStringMessage(name, string) {\n validationMessages.messages[name] = () => string\n }\n\n\n function templateOptionValue(prop, prefix, suffix, alternate) {\n return function getValidationMessage(viewValue, modelValue, scope) {\n if (typeof scope.options.templateOptions[prop] !== 'undefined') {\n return `${prefix} ${scope.options.templateOptions[prop]} ${suffix}`\n } else {\n return alternate\n }\n }\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./providers/formlyValidationMessages.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nexports['default'] = addCustomTags;\n\n// @ngInject\nfunction addCustomTags($document) {\n // IE8 check ->\n // https://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx\n if ($document && $document.documentMode < 9) {\n (function () {\n var document = $document.get(0);\n // add the custom elements that we need for formly\n var customElements = ['formly-field', 'formly-form'];\n _angularFix2['default'].forEach(customElements, function (el) {\n document.createElement(el);\n });\n })();\n }\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./run/formlyCustomTags.js\n **/","import angular from 'angular-fix'\nexport default addCustomTags\n\n// @ngInject\nfunction addCustomTags($document) {\n // IE8 check ->\n // https://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx\n if ($document && $document.documentMode < 9) {\n const document = $document.get(0)\n // add the custom elements that we need for formly\n const customElements = [\n 'formly-field', 'formly-form',\n ]\n angular.forEach(customElements, el => {\n document.createElement(el)\n })\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./run/formlyCustomTags.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _angularFix = require('angular-fix');\n\nvar _angularFix2 = _interopRequireDefault(_angularFix);\n\nvar _otherUtils = require('../other/utils');\n\nexports['default'] = addFormlyNgModelAttrsManipulator;\n\n// @ngInject\nfunction addFormlyNgModelAttrsManipulator(formlyConfig, $interpolate) {\n if (formlyConfig.extras.disableNgModelAttrsManipulator) {\n return;\n }\n formlyConfig.templateManipulators.preWrapper.push(ngModelAttrsManipulator);\n\n function ngModelAttrsManipulator(template, options, scope) {\n var node = document.createElement('div');\n var skip = options.extras && options.extras.skipNgModelAttrsManipulator;\n if (skip === true) {\n return template;\n }\n node.innerHTML = template;\n\n var modelNodes = getNgModelNodes(node, skip);\n if (!modelNodes || !modelNodes.length) {\n return template;\n }\n\n addIfNotPresent(modelNodes, 'id', scope.id);\n addIfNotPresent(modelNodes, 'name', scope.name || scope.id);\n\n addValidation();\n alterNgModelAttr();\n addModelOptions();\n addTemplateOptionsAttrs();\n addNgModelElAttrs();\n\n return node.innerHTML;\n\n function addValidation() {\n if (_angularFix2['default'].isDefined(options.validators) || _angularFix2['default'].isDefined(options.validation.messages)) {\n addIfNotPresent(modelNodes, 'formly-custom-validation', '');\n }\n }\n\n function alterNgModelAttr() {\n if (isPropertyAccessor(options.key)) {\n addRegardlessOfPresence(modelNodes, 'ng-model', 'model.' + options.key);\n }\n }\n\n function addModelOptions() {\n if (_angularFix2['default'].isDefined(options.modelOptions)) {\n addIfNotPresent(modelNodes, 'ng-model-options', 'options.modelOptions');\n if (options.modelOptions.getterSetter) {\n addRegardlessOfPresence(modelNodes, 'ng-model', 'options.value');\n }\n }\n }\n\n function addTemplateOptionsAttrs() {\n if (!options.templateOptions && !options.expressionProperties) {\n // no need to run these if there are no templateOptions or expressionProperties\n return;\n }\n var to = options.templateOptions || {};\n var ep = options.expressionProperties || {};\n\n var ngModelAttributes = getBuiltInAttributes();\n\n // extend with the user's specifications winning\n _angularFix2['default'].extend(ngModelAttributes, options.ngModelAttrs);\n\n // Feel free to make this more simple :-)\n _angularFix2['default'].forEach(ngModelAttributes, function (val, name) {\n /* eslint complexity:[2, 14] */\n var attrVal = undefined,\n attrName = undefined;\n var ref = 'options.templateOptions[\\'' + name + '\\']';\n var toVal = to[name];\n var epVal = getEpValue(ep, name);\n\n var inTo = _angularFix2['default'].isDefined(toVal);\n var inEp = _angularFix2['default'].isDefined(epVal);\n if (val.value) {\n // I realize this looks backwards, but it's right, trust me...\n attrName = val.value;\n attrVal = name;\n } else if (val.statement && inTo) {\n attrName = val.statement;\n if (_angularFix2['default'].isString(to[name])) {\n attrVal = '$eval(' + ref + ')';\n } else if (_angularFix2['default'].isFunction(to[name])) {\n attrVal = ref + '(model[options.key], options, this, $event)';\n } else {\n throw new Error('options.templateOptions.' + name + ' must be a string or function: ' + JSON.stringify(options));\n }\n } else if (val.bound && inEp) {\n attrName = val.bound;\n attrVal = ref;\n } else if ((val.attribute || val.boolean) && inEp) {\n attrName = val.attribute || val.boolean;\n attrVal = '' + $interpolate.startSymbol() + ref + $interpolate.endSymbol();\n } else if (val.attribute && inTo) {\n attrName = val.attribute;\n attrVal = toVal;\n } else if (val.boolean) {\n if (inTo && !inEp && toVal) {\n attrName = val.boolean;\n attrVal = true;\n } else {\n /* eslint no-empty:0 */\n // empty to illustrate that a boolean will not be added via val.bound\n // if you want it added via val.bound, then put it in expressionProperties\n }\n } else if (val.bound && inTo) {\n attrName = val.bound;\n attrVal = ref;\n }\n\n if (_angularFix2['default'].isDefined(attrName) && _angularFix2['default'].isDefined(attrVal)) {\n addIfNotPresent(modelNodes, attrName, attrVal);\n }\n });\n }\n\n function addNgModelElAttrs() {\n _angularFix2['default'].forEach(options.ngModelElAttrs, function (val, name) {\n addRegardlessOfPresence(modelNodes, name, val);\n });\n }\n }\n\n // Utility functions\n function getNgModelNodes(node, skip) {\n var selectorNot = _angularFix2['default'].isString(skip) ? ':not(' + skip + ')' : '';\n var skipNot = ':not([formly-skip-ng-model-attrs-manipulator])';\n var query = '[ng-model]' + selectorNot + skipNot + ', [data-ng-model]' + selectorNot + skipNot;\n try {\n return node.querySelectorAll(query);\n } catch (e) {\n //this code is needed for IE8, as it does not support the CSS3 ':not' selector\n //it should be removed when IE8 support is dropped\n return getNgModelNodesFallback(node, skip);\n }\n }\n\n function getNgModelNodesFallback(node, skip) {\n var allNgModelNodes = node.querySelectorAll('[ng-model], [data-ng-model]');\n var matchingNgModelNodes = [];\n\n //make sure this array is compatible with NodeList type by adding an 'item' function\n matchingNgModelNodes.item = function (i) {\n return this[i];\n };\n\n for (var i = 0; i < allNgModelNodes.length; i++) {\n var ngModelNode = allNgModelNodes[i];\n if (!ngModelNode.hasAttribute('formly-skip-ng-model-attrs-manipulator') && !(_angularFix2['default'].isString(skip) && nodeMatches(ngModelNode, skip))) {\n matchingNgModelNodes.push(ngModelNode);\n }\n }\n\n return matchingNgModelNodes;\n }\n\n function nodeMatches(node, selector) {\n var div = document.createElement('div');\n div.innerHTML = node.outerHTML;\n return div.querySelector(selector);\n }\n\n function getBuiltInAttributes() {\n var ngModelAttributes = {\n focus: {\n attribute: 'formly-focus'\n }\n };\n var boundOnly = [];\n var bothBooleanAndBound = ['required', 'disabled'];\n var bothAttributeAndBound = ['pattern', 'minlength'];\n var statementOnly = ['change', 'keydown', 'keyup', 'keypress', 'click', 'focus', 'blur'];\n var attributeOnly = ['placeholder', 'min', 'max', 'step', 'tabindex', 'type'];\n if (formlyConfig.extras.ngModelAttrsManipulatorPreferUnbound) {\n bothAttributeAndBound.push('maxlength');\n } else {\n boundOnly.push('maxlength');\n }\n\n _angularFix2['default'].forEach(boundOnly, function (item) {\n ngModelAttributes[item] = { bound: 'ng-' + item };\n });\n\n _angularFix2['default'].forEach(bothBooleanAndBound, function (item) {\n ngModelAttributes[item] = { boolean: item, bound: 'ng-' + item };\n });\n\n _angularFix2['default'].forEach(bothAttributeAndBound, function (item) {\n ngModelAttributes[item] = { attribute: item, bound: 'ng-' + item };\n });\n\n _angularFix2['default'].forEach(statementOnly, function (item) {\n var propName = 'on' + item.substr(0, 1).toUpperCase() + item.substr(1);\n ngModelAttributes[propName] = { statement: 'ng-' + item };\n });\n\n _angularFix2['default'].forEach(attributeOnly, function (item) {\n ngModelAttributes[item] = { attribute: item };\n });\n return ngModelAttributes;\n }\n\n function getEpValue(ep, name) {\n return ep['templateOptions.' + name] || ep['templateOptions[\\'' + name + '\\']'] || ep['templateOptions[\"' + name + '\"]'];\n }\n\n function addIfNotPresent(nodes, attr, val) {\n _angularFix2['default'].forEach(nodes, function (node) {\n if (!node.getAttribute(attr)) {\n node.setAttribute(attr, val);\n }\n });\n }\n\n function addRegardlessOfPresence(nodes, attr, val) {\n _angularFix2['default'].forEach(nodes, function (node) {\n node.setAttribute(attr, val);\n });\n }\n\n function isPropertyAccessor(key) {\n return (0, _otherUtils.contains)(key, '.') || (0, _otherUtils.contains)(key, '[') && (0, _otherUtils.contains)(key, ']');\n }\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./run/formlyNgModelAttrsManipulator.js\n **/","import angular from 'angular-fix'\nimport {contains} from '../other/utils'\n\nexport default addFormlyNgModelAttrsManipulator\n\n// @ngInject\nfunction addFormlyNgModelAttrsManipulator(formlyConfig, $interpolate) {\n if (formlyConfig.extras.disableNgModelAttrsManipulator) {\n return\n }\n formlyConfig.templateManipulators.preWrapper.push(ngModelAttrsManipulator)\n\n\n function ngModelAttrsManipulator(template, options, scope) {\n const node = document.createElement('div')\n const skip = options.extras && options.extras.skipNgModelAttrsManipulator\n if (skip === true) {\n return template\n }\n node.innerHTML = template\n\n const modelNodes = getNgModelNodes(node, skip)\n if (!modelNodes || !modelNodes.length) {\n return template\n }\n\n addIfNotPresent(modelNodes, 'id', scope.id)\n addIfNotPresent(modelNodes, 'name', scope.name || scope.id)\n\n addValidation()\n alterNgModelAttr()\n addModelOptions()\n addTemplateOptionsAttrs()\n addNgModelElAttrs()\n\n\n return node.innerHTML\n\n\n function addValidation() {\n if (angular.isDefined(options.validators) || angular.isDefined(options.validation.messages)) {\n addIfNotPresent(modelNodes, 'formly-custom-validation', '')\n }\n }\n\n function alterNgModelAttr() {\n if (isPropertyAccessor(options.key)) {\n addRegardlessOfPresence(modelNodes, 'ng-model', 'model.' + options.key)\n }\n }\n\n function addModelOptions() {\n if (angular.isDefined(options.modelOptions)) {\n addIfNotPresent(modelNodes, 'ng-model-options', 'options.modelOptions')\n if (options.modelOptions.getterSetter) {\n addRegardlessOfPresence(modelNodes, 'ng-model', 'options.value')\n }\n }\n }\n\n function addTemplateOptionsAttrs() {\n if (!options.templateOptions && !options.expressionProperties) {\n // no need to run these if there are no templateOptions or expressionProperties\n return\n }\n const to = options.templateOptions || {}\n const ep = options.expressionProperties || {}\n\n const ngModelAttributes = getBuiltInAttributes()\n\n // extend with the user's specifications winning\n angular.extend(ngModelAttributes, options.ngModelAttrs)\n\n // Feel free to make this more simple :-)\n angular.forEach(ngModelAttributes, (val, name) => {\n /* eslint complexity:[2, 14] */\n let attrVal, attrName\n const ref = `options.templateOptions['${name}']`\n const toVal = to[name]\n const epVal = getEpValue(ep, name)\n\n const inTo = angular.isDefined(toVal)\n const inEp = angular.isDefined(epVal)\n if (val.value) {\n // I realize this looks backwards, but it's right, trust me...\n attrName = val.value\n attrVal = name\n } else if (val.statement && inTo) {\n attrName = val.statement\n if (angular.isString(to[name])) {\n attrVal = `$eval(${ref})`\n } else if (angular.isFunction(to[name])) {\n attrVal = `${ref}(model[options.key], options, this, $event)`\n } else {\n throw new Error(\n `options.templateOptions.${name} must be a string or function: ${JSON.stringify(options)}`\n )\n }\n } else if (val.bound && inEp) {\n attrName = val.bound\n attrVal = ref\n } else if ((val.attribute || val.boolean) && inEp) {\n attrName = val.attribute || val.boolean\n attrVal = `${$interpolate.startSymbol()}${ref}${$interpolate.endSymbol()}`\n } else if (val.attribute && inTo) {\n attrName = val.attribute\n attrVal = toVal\n } else if (val.boolean) {\n if (inTo && !inEp && toVal) {\n attrName = val.boolean\n attrVal = true\n } else {\n /* eslint no-empty:0 */\n // empty to illustrate that a boolean will not be added via val.bound\n // if you want it added via val.bound, then put it in expressionProperties\n }\n } else if (val.bound && inTo) {\n attrName = val.bound\n attrVal = ref\n }\n\n if (angular.isDefined(attrName) && angular.isDefined(attrVal)) {\n addIfNotPresent(modelNodes, attrName, attrVal)\n }\n })\n }\n\n function addNgModelElAttrs() {\n angular.forEach(options.ngModelElAttrs, (val, name) => {\n addRegardlessOfPresence(modelNodes, name, val)\n })\n }\n }\n\n // Utility functions\n function getNgModelNodes(node, skip) {\n const selectorNot = angular.isString(skip) ? `:not(${skip})` : ''\n const skipNot = ':not([formly-skip-ng-model-attrs-manipulator])'\n const query = `[ng-model]${selectorNot}${skipNot}, [data-ng-model]${selectorNot}${skipNot}`\n try {\n return node.querySelectorAll(query)\n } catch (e) {\n //this code is needed for IE8, as it does not support the CSS3 ':not' selector\n //it should be removed when IE8 support is dropped\n return getNgModelNodesFallback(node, skip)\n }\n }\n\n function getNgModelNodesFallback(node, skip) {\n const allNgModelNodes = node.querySelectorAll('[ng-model], [data-ng-model]')\n const matchingNgModelNodes = []\n\n //make sure this array is compatible with NodeList type by adding an 'item' function\n matchingNgModelNodes.item = function(i) {\n return this[i]\n }\n\n for (let i = 0; i < allNgModelNodes.length; i++) {\n const ngModelNode = allNgModelNodes[i]\n if (!ngModelNode.hasAttribute('formly-skip-ng-model-attrs-manipulator') &&\n !(angular.isString(skip) && nodeMatches(ngModelNode, skip))) {\n matchingNgModelNodes.push(ngModelNode)\n }\n }\n\n return matchingNgModelNodes\n }\n\n function nodeMatches(node, selector) {\n const div = document.createElement('div')\n div.innerHTML = node.outerHTML\n return div.querySelector(selector)\n }\n\n function getBuiltInAttributes() {\n const ngModelAttributes = {\n focus: {\n attribute: 'formly-focus',\n },\n }\n const boundOnly = []\n const bothBooleanAndBound = ['required', 'disabled']\n const bothAttributeAndBound = ['pattern', 'minlength']\n const statementOnly = ['change', 'keydown', 'keyup', 'keypress', 'click', 'focus', 'blur']\n const attributeOnly = ['placeholder', 'min', 'max', 'step', 'tabindex', 'type']\n if (formlyConfig.extras.ngModelAttrsManipulatorPreferUnbound) {\n bothAttributeAndBound.push('maxlength')\n } else {\n boundOnly.push('maxlength')\n }\n\n angular.forEach(boundOnly, item => {\n ngModelAttributes[item] = {bound: 'ng-' + item}\n })\n\n angular.forEach(bothBooleanAndBound, item => {\n ngModelAttributes[item] = {boolean: item, bound: 'ng-' + item}\n })\n\n angular.forEach(bothAttributeAndBound, item => {\n ngModelAttributes[item] = {attribute: item, bound: 'ng-' + item}\n })\n\n angular.forEach(statementOnly, item => {\n const propName = 'on' + item.substr(0, 1).toUpperCase() + item.substr(1)\n ngModelAttributes[propName] = {statement: 'ng-' + item}\n })\n\n angular.forEach(attributeOnly, item => {\n ngModelAttributes[item] = {attribute: item}\n })\n return ngModelAttributes\n }\n\n function getEpValue(ep, name) {\n return ep['templateOptions.' + name] ||\n ep[`templateOptions['${name}']`] ||\n ep[`templateOptions[\"${name}\"]`]\n }\n\n function addIfNotPresent(nodes, attr, val) {\n angular.forEach(nodes, node => {\n if (!node.getAttribute(attr)) {\n node.setAttribute(attr, val)\n }\n })\n }\n\n function addRegardlessOfPresence(nodes, attr, val) {\n angular.forEach(nodes, node => {\n node.setAttribute(attr, val)\n })\n }\n\n function isPropertyAccessor(key) {\n return contains(key, '.') || (contains(key, '[') && contains(key, ']'))\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./run/formlyNgModelAttrsManipulator.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar _otherUtils = require('../other/utils');\n\nvar _otherUtils2 = _interopRequireDefault(_otherUtils);\n\nexports['default'] = formlyUtil;\n\n// @ngInject\nfunction formlyUtil() {\n return _otherUtils2['default'];\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./services/formlyUtil.js\n **/","import utils from '../other/utils'\n\nexport default formlyUtil\n\n// @ngInject\nfunction formlyUtil() {\n return utils\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./services/formlyUtil.js\n **/","'use strict';\n\nObject.defineProperty(exports, '__esModule', {\n value: true\n});\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }\n\nexports['default'] = formlyWarn;\n\n// @ngInject\nfunction formlyWarn(formlyConfig, formlyErrorAndWarningsUrlPrefix, $log) {\n return function warn() {\n if (!formlyConfig.disableWarnings) {\n var args = Array.prototype.slice.call(arguments);\n var warnInfoSlug = args.shift();\n args.unshift('Formly Warning:');\n args.push('' + formlyErrorAndWarningsUrlPrefix + warnInfoSlug);\n $log.warn.apply($log, _toConsumableArray(args));\n }\n };\n}\nmodule.exports = exports['default'];\n\n\n/** WEBPACK FOOTER **\n ** ./services/formlyWarn.js\n **/","export default formlyWarn\n\n// @ngInject\nfunction formlyWarn(formlyConfig, formlyErrorAndWarningsUrlPrefix, $log) {\n return function warn() {\n if (!formlyConfig.disableWarnings) {\n const args = Array.prototype.slice.call(arguments)\n const warnInfoSlug = args.shift()\n args.unshift('Formly Warning:')\n args.push(`${formlyErrorAndWarningsUrlPrefix}${warnInfoSlug}`)\n $log.warn(...args)\n }\n }\n}\n\n\n\n/** WEBPACK FOOTER **\n ** ../~/eslint-loader?configFile=./other/src.eslintrc!./services/formlyWarn.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_18__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"angular\"\n ** module id = 18\n ** module chunks = 0\n **/"],"sourceRoot":""}
diff --git a/static/js/lodash.min.js b/static/js/lodash.min.js
new file mode 100644
index 0000000..4d6e9ff
--- /dev/null
+++ b/static/js/lodash.min.js
@@ -0,0 +1,98 @@
+/**
+ * @license
+ * lodash 3.9.3 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
+ * Build: `lodash modern -o ./lodash.js`
+ */
+;(function(){function n(n,t){if(n!==t){var r=null===n,e=n===m,u=n===n,i=null===t,o=t===m,f=t===t;if(n>t&&!i||!u||r&&!o&&f||e&&f)return 1;if(n=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n);
+}function _(n,t){for(var r=-1,e=n.length,u=-1,i=[];++ro(t,l,0)&&u.push(l);return u}function at(n,t){var r=true;return Mu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function ct(n,t,r,e){var u=e,i=u;return Mu(n,function(n,o,f){o=+t(n,o,f),(r(o,u)||o===e&&o===i)&&(u=o,i=n)}),i}function st(n,t){var r=[];return Mu(n,function(n,e,u){t(n,e,u)&&r.push(n);
+}),r}function pt(n,t,r,e){var u;return r(n,function(n,r,i){return t(n,r,i)?(u=e?r:n,false):void 0}),u}function ht(n,t,r){for(var e=-1,u=n.length,i=-1,o=[];++et&&(t=-t>u?0:u+t),r=r===m||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Me(u);++eu(l,s,0)&&((t||f)&&l.push(s),a.push(c))}return a}function Ft(n,t){for(var r=-1,e=t.length,u=Me(e);++r>>1,o=n[i];(r?o<=t:ou?m:i,u=1);++earguments.length;return typeof e=="function"&&i===m&&Ti(r)?n(r,e,u,o):Et(r,mr(e,i,4),u,o,t)}}function sr(n,t,r,e,u,i,o,f,l,a){function c(){for(var w=arguments.length,A=w,j=Me(w);A--;)j[A]=arguments[A];if(e&&(j=qt(j,e,u)),i&&(j=Dt(j,i,o)),v||y){var A=c.placeholder,k=_(j,A),w=w-k.length;
+if(wt?0:t)):[]}function qr(n,t,r){var e=n?n.length:0;return e?((r?Cr(n,t,r):null==t)&&(t=1),
+t=e-(+t||0),Ct(n,0,0>t?0:t)):[]}function Dr(n){return n?n[0]:m}function Kr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?ku(u+e,0):e;else if(e)return e=zt(n,t),n=n[e],(t===t?t===n:n!==n)?e:-1;return r(n,t,e||0)}function Vr(n){var t=n?n.length:0;return t?n[t-1]:m}function Yr(n){return Pr(n,1)}function Zr(n,t,e,u){if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=Cr(n,t,u)?null:t,t=false);var i=mr();if((null!=e||i!==it)&&(e=i(e,u,3)),t&&br()==r){t=e;var o;e=-1,u=n.length;
+for(var i=-1,f=[];++er?ku(u+r,0):r||0,typeof n=="string"||!Ti(n)&&me(n)?rt?0:+t||0,e);++r=n&&(t=null),r}}function fe(n,t,r){function e(){var r=t-(wi()-a);0>=r||r>t?(f&&cu(f),r=p,f=s=p=m,r&&(h=wi(),l=n.apply(c,o),s||f||(o=c=null))):s=gu(e,r)}function u(){s&&cu(s),f=s=p=m,(v||_!==t)&&(h=wi(),l=n.apply(c,o),s||f||(o=c=null))}function i(){if(o=arguments,a=wi(),c=this,p=v&&(s||!g),false===_)var r=g&&!s;else{f||g||(h=a);var i=_-(a-h),y=0>=i||i>_;y?(f&&(f=cu(f)),h=a,l=n.apply(c,o)):f||(f=gu(u,i))}return y&&s?s=cu(s):s||t===_||(s=gu(e,t)),r&&(y=true,l=n.apply(c,o)),
+!y||s||f||(o=c=null),l}var o,f,l,a,c,s,p,h=0,_=false,v=true;if(typeof n!="function")throw new Je(N);if(t=0>t?0:+t||0,true===r)var g=true,v=false;else ve(r)&&(g=r.leading,_="maxWait"in r&&ku(+r.maxWait||0,t),v="trailing"in r?r.trailing:v);return i.cancel=function(){s&&cu(s),f&&cu(f),f=s=p=m},i}function le(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new Je(N);return r.cache=new le.Cache,
+r}function ae(n,t){if(typeof n!="function")throw new Je(N);return t=ku(t===m?n.length-1:+t||0,0),function(){for(var r=arguments,e=-1,u=ku(r.length-t,0),i=Me(u);++et}function se(n){return p(n)&&Ir(n)&&uu.call(n)==z}function pe(n){return!!n&&1===n.nodeType&&p(n)&&-1t||!n||!Au(t))return r;do t%2&&(r+=n),t=su(t/2),n+=n;while(t);return r}function Se(n,t,r){var e=n;return(n=u(n))?(r?Cr(e,t,r):null==t)?n.slice(v(n),g(n)+1):(t+="",n.slice(i(n,t),o(n,t)+1)):n}function Te(n,t,r){
+return r&&Cr(n,t,r)&&(t=null),n=u(n),n.match(t||Wn)||[]}function Ue(n,t,r){return r&&Cr(n,t,r)&&(t=null),p(n)?Ne(n):it(n,t)}function $e(n){return function(){return n}}function Fe(n){return n}function Ne(n){return xt(ot(n,true))}function Le(n,t,r){if(null==r){var e=ve(t),u=e?Ki(t):null;((u=u&&u.length?yt(t,u):null)?u.length:e)||(u=false,r=t,t=n,n=this)}u||(u=yt(t,Ki(t)));var i=true,e=-1,o=$i(n),f=u.length;false===r?i=false:ve(r)&&"chain"in r&&(i=r.chain);for(;++e=S)return r}else n=0;return Ku(r,e)}}(),Ju=ae(function(n,t){return Ir(n)?lt(n,ht(t,false,true)):[]}),Xu=tr(),Hu=tr(true),Qu=ae(function(n){for(var t=n.length,e=t,u=Me(c),i=br(),o=i==r,f=[];e--;){var l=n[e]=Ir(l=n[e])?l:[];u[e]=o&&120<=l.length?Vu(e&&l):null}var o=n[0],a=-1,c=o?o.length:0,s=u[0];
+n:for(;++a(s?qn(s,l):i(f,l,0))){for(e=t;--e;){var p=u[e];if(0>(p?qn(p,l):i(n[e],l,0)))continue n}s&&s.push(l),f.push(l)}return f}),ni=ae(function(t,r){r=ht(r);var e=et(t,r);return Rt(t,r.sort(n)),e}),ti=_r(),ri=_r(true),ei=ae(function(n){return $t(ht(n,false,true))}),ui=ae(function(n,t){return Ir(n)?lt(n,t):[]}),ii=ae(Gr),oi=ae(function(n){var t=n.length,r=2--n?t.apply(this,arguments):void 0}},Nn.ary=function(n,t,r){return r&&Cr(n,t,r)&&(t=null),t=n&&null==t?n.length:ku(+t||0,0),vr(n,I,null,null,null,null,t)},Nn.assign=Ni,Nn.at=fi,Nn.before=oe,Nn.bind=bi,Nn.bindAll=xi,Nn.bindKey=Ai,Nn.callback=Ue,Nn.chain=Hr,Nn.chunk=function(n,t,r){t=(r?Cr(n,t,r):null==t)?1:ku(+t||1,1),r=0;for(var e=n?n.length:0,u=-1,i=Me(au(e/t));rr&&(r=-r>u?0:u+r),e=e===m||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;rt?0:t)):[]},Nn.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?Cr(n,t,r):null==t)&&(t=1),t=e-(+t||0),Ct(n,0>t?0:t)):[]},Nn.takeRightWhile=function(n,t,r){return n&&n.length?Nt(n,mr(t,r,3),false,true):[]},Nn.takeWhile=function(n,t,r){return n&&n.length?Nt(n,mr(t,r,3)):[];
+},Nn.tap=function(n,t,r){return t.call(r,n),n},Nn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Je(N);return false===r?e=false:ve(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),Fn.leading=e,Fn.maxWait=+t,Fn.trailing=u,fe(n,t,Fn)},Nn.thru=Qr,Nn.times=function(n,t,r){if(n=su(n),1>n||!Au(n))return[];var e=-1,u=Me(Ou(n,4294967295));for(t=Mt(t,r,1);++ee?u[e]=t(e):t(e);return u},Nn.toArray=xe,Nn.toPlainObject=Ae,Nn.transform=function(n,t,r,e){var u=Ti(n)||we(n);
+return t=mr(t,e,4),null==r&&(u||ve(n)?(e=n.constructor,r=u?Ti(n)?new e:[]:Bu($i(e)?e.prototype:null)):r={}),(u?Kn:vt)(n,function(n,e,u){return t(r,n,e,u)}),r},Nn.union=ei,Nn.uniq=Zr,Nn.unzip=Gr,Nn.unzipWith=Jr,Nn.values=Re,Nn.valuesIn=function(n){return Ft(n,ke(n))},Nn.where=function(n,t){return te(n,xt(t))},Nn.without=ui,Nn.wrap=function(n,t){return t=null==t?Fe:t,vr(t,O,null,[n],[])},Nn.xor=function(){for(var n=-1,t=arguments.length;++nr?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Nn.escape=function(n){return(n=u(n))&&pn.test(n)?n.replace(cn,a):n},Nn.escapeRegExp=Ee,Nn.every=ne,Nn.find=ai,Nn.findIndex=Xu,Nn.findKey=zi,Nn.findLast=ci,Nn.findLastIndex=Hu,Nn.findLastKey=Bi,Nn.findWhere=function(n,t){return ai(n,xt(t))},Nn.first=Dr,Nn.get=function(n,t,r){
+return n=null==n?m:dt(n,Br(t),t+""),n===m?r:n},Nn.gt=ce,Nn.gte=function(n,t){return n>=t},Nn.has=function(n,t){if(null==n)return false;var r=ru.call(n,t);if(!r&&!Wr(t)){if(t=Br(t),n=1==t.length?n:dt(n,Ct(t,0,-1)),null==n)return false;t=Vr(t),r=ru.call(n,t)}return r||Tr(n.length)&&Er(t,n.length)&&(Ti(n)||se(n))},Nn.identity=Fe,Nn.includes=re,Nn.indexOf=Kr,Nn.inRange=function(n,t,r){return t=+t||0,"undefined"===typeof r?(r=t,t=0):r=+r||0,n>=Ou(t,r)&&nr?ku(e+r,0):Ou(r||0,e-1))+1;else if(r)return u=zt(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;if(t!==t)return s(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},Nn.lt=be,Nn.lte=function(n,t){return n<=t},Nn.max=oo,Nn.min=fo,Nn.noConflict=function(){return h._=iu,this},Nn.noop=ze,Nn.now=wi,
+Nn.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return er?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Nn.sum=function(n,t,r){r&&Cr(n,t,r)&&(t=null);var e=mr(),u=null==t;if(u&&e===it||(u=false,
+t=e(t,r,3)),u){for(n=Ti(n)?n:Lr(n),t=n.length,r=0;t--;)r+=+n[t]||0;n=r}else n=Ut(n,t);return n},Nn.template=function(n,t,r){var e=Nn.templateSettings;r&&Cr(n,t,r)&&(t=r=null),n=u(n),t=tt(rt({},r||t),e,nt),r=tt(rt({},t.imports),e.imports,nt);var i,o,f=Ki(r),l=Ft(r,f),a=0;r=t.interpolate||En;var s="__p+='";r=Ze((t.escape||En).source+"|"+r.source+"|"+(r===vn?An:En).source+"|"+(t.evaluate||En).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,l){
+return e||(e=u),s+=n.slice(a,l).replace(Cn,c),r&&(i=true,s+="'+__e("+r+")+'"),f&&(o=true,s+="';"+f+";\n__p+='"),e&&(s+="'+((__t=("+e+"))==null?'':__t)+'"),a=l+t.length,t}),s+="';",(t=t.variable)||(s="with(obj){"+s+"}"),s=(o?s.replace(on,""):s).replace(fn,"$1").replace(ln,"$1;"),s="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(i?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+s+"return __p}",t=eo(function(){return De(f,p+"return "+s).apply(m,l);
+}),t.source=s,_e(t))throw t;return t},Nn.trim=Se,Nn.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?Cr(e,t,r):null==t)?v(n):i(n,t+"")):n},Nn.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?Cr(e,t,r):null==t)?n.slice(0,g(n)+1):n.slice(0,o(n,t+"")+1):n},Nn.trunc=function(n,t,r){r&&Cr(n,t,r)&&(t=null);var e=C;if(r=W,null!=t)if(ve(t)){var i="separator"in t?t.separator:i,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length,
+1>e)return r;if(t=n.slice(0,e),null==i)return t+r;if(de(i)){if(n.slice(e).search(i)){var o,f=n.slice(0,e);for(i.global||(i=Ze(i.source,(jn.exec(i)||"")+"g")),i.lastIndex=0;n=i.exec(f);)o=n.index;t=t.slice(0,null==o?e:o)}}else n.indexOf(i,e)!=e&&(i=t.lastIndexOf(i),-1u.__dir__?"Right":"")}),u},Bn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse();
+},Bn.prototype[n+"RightWhile"]=function(n,t){return this.reverse()[r](n,t).reverse()}}),Kn(["first","last"],function(n,t){var r="take"+(t?"Right":"");Bn.prototype[n]=function(){return this[r](1).value()[0]}}),Kn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");Bn.prototype[n]=function(){return this[r](1)}}),Kn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?xt:Be;Bn.prototype[n]=function(n){return this[r](e(n))}}),Bn.prototype.compact=function(){return this.filter(Fe)},Bn.prototype.reject=function(n,t){
+return n=mr(n,t,1),this.filter(function(t){return!n(t)})},Bn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return 0>n?r=this.takeRight(-n):n&&(r=this.drop(n)),t!==m&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r},Bn.prototype.toArray=function(){return this.drop(0)},vt(Bn.prototype,function(n,t){var r=Nn[t];if(r){var e=/^(?:filter|map|reject)|While$/.test(t),u=/^(?:first|last)$/.test(t);Nn.prototype[t]=function(){function t(n){return n=[n],_u.apply(n,i),r.apply(Nn,n)}var i=arguments,o=this.__chain__,f=this.__wrapped__,l=!!this.__actions__.length,a=f instanceof Bn,c=i[0],s=a||Ti(f);
+return s&&e&&typeof c=="function"&&1!=c.length&&(a=s=false),a=a&&!l,u&&!o?a?n.call(f):r.call(Nn,this.value()):s?(f=n.apply(a?f:new Bn(this),i),u||!l&&!f.__actions__||(f.__actions__||(f.__actions__=[])).push({func:Qr,args:[t],thisArg:Nn}),new zn(f,o)):this.thru(t)}}}),Kn("concat join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?Qe:Xe)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|replace|shift)$/.test(n);Nn.prototype[n]=function(){
+var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),vt(Bn.prototype,function(n,t){var r=Nn[t];if(r){var e=r.name;(Lu[e]||(Lu[e]=[])).push({name:t,func:r})}}),Lu[sr(null,x).name]=[{name:"wrapper",func:null}],Bn.prototype.clone=function(){var n=this.__actions__,t=this.__iteratees__,r=this.__views__,e=new Bn(this.__wrapped__);return e.__actions__=n?Dn(n):null,e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=t?Dn(t):null,
+e.__takeCount__=this.__takeCount__,e.__views__=r?Dn(r):null,e},Bn.prototype.reverse=function(){if(this.__filtered__){var n=new Bn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Bn.prototype.value=function(){var n=this.__wrapped__.value();if(!Ti(n))return Lt(n,this.__actions__);var t,r=this.__dir__,e=0>r;t=n.length;for(var u=this.__views__,i=0,o=-1,f=u?u.length:0;++op.index:u=_:!h(s))))continue n}else if(p=h(s),_==F)s=p;else if(!p){if(_==$)continue n;break n}}a[l++]=s}return a},Nn.prototype.chain=function(){
+return Hr(this)},Nn.prototype.commit=function(){return new zn(this.value(),this.__chain__)},Nn.prototype.plant=function(n){for(var t,r=this;r instanceof Ln;){var e=Mr(r);t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},Nn.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Bn?(this.__actions__.length&&(n=new Bn(this)),new zn(n.reverse(),this.__chain__)):this.thru(function(n){return n.reverse()})},Nn.prototype.toString=function(){return this.value()+""},Nn.prototype.run=Nn.prototype.toJSON=Nn.prototype.valueOf=Nn.prototype.value=function(){
+return Lt(this.__wrapped__,this.__actions__)},Nn.prototype.collect=Nn.prototype.map,Nn.prototype.head=Nn.prototype.first,Nn.prototype.select=Nn.prototype.filter,Nn.prototype.tail=Nn.prototype.rest,Nn}var m,w="3.9.3",b=1,x=2,A=4,j=8,k=16,O=32,R=64,I=128,E=256,C=30,W="...",S=150,T=16,U=0,$=1,F=2,N="Expected a function",L="__lodash_placeholder__",z="[object Arguments]",B="[object Array]",M="[object Boolean]",P="[object Date]",q="[object Error]",D="[object Function]",K="[object Number]",V="[object Object]",Y="[object RegExp]",Z="[object String]",G="[object ArrayBuffer]",J="[object Float32Array]",X="[object Float64Array]",H="[object Int8Array]",Q="[object Int16Array]",nn="[object Int32Array]",tn="[object Uint8Array]",rn="[object Uint8ClampedArray]",en="[object Uint16Array]",un="[object Uint32Array]",on=/\b__p\+='';/g,fn=/\b(__p\+=)''\+/g,ln=/(__e\(.*?\)|\b__t\))\+'';/g,an=/&(?:amp|lt|gt|quot|#39|#96);/g,cn=/[&<>"'`]/g,sn=RegExp(an.source),pn=RegExp(cn.source),hn=/<%-([\s\S]+?)%>/g,_n=/<%([\s\S]+?)%>/g,vn=/<%=([\s\S]+?)%>/g,gn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,yn=/^\w*$/,dn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,mn=/[.*+?^${}()|[\]\/\\]/g,wn=RegExp(mn.source),bn=/[\u0300-\u036f\ufe20-\ufe23]/g,xn=/\\(\\)?/g,An=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,jn=/\w*$/,kn=/^0[xX]/,On=/^\[object .+?Constructor\]$/,Rn=/^\d+$/,In=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,En=/($^)/,Cn=/['\n\r\u2028\u2029\\]/g,Wn=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),Sn=" \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",Tn="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseFloat parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window".split(" "),Un={};
+Un[J]=Un[X]=Un[H]=Un[Q]=Un[nn]=Un[tn]=Un[rn]=Un[en]=Un[un]=true,Un[z]=Un[B]=Un[G]=Un[M]=Un[P]=Un[q]=Un[D]=Un["[object Map]"]=Un[K]=Un[V]=Un[Y]=Un["[object Set]"]=Un[Z]=Un["[object WeakMap]"]=false;var $n={};$n[z]=$n[B]=$n[G]=$n[M]=$n[P]=$n[J]=$n[X]=$n[H]=$n[Q]=$n[nn]=$n[K]=$n[V]=$n[Y]=$n[Z]=$n[tn]=$n[rn]=$n[en]=$n[un]=true,$n[q]=$n[D]=$n["[object Map]"]=$n["[object Set]"]=$n["[object WeakMap]"]=false;var Fn={leading:false,maxWait:0,trailing:false},Nn={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A",
+"\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u",
+"\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Ln={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},zn={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Bn={"function":true,object:true},Mn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Pn=Bn[typeof exports]&&exports&&!exports.nodeType&&exports,qn=Bn[typeof module]&&module&&!module.nodeType&&module,Dn=Bn[typeof self]&&self&&self.Object&&self,Kn=Bn[typeof window]&&window&&window.Object&&window,Vn=qn&&qn.exports===Pn&&Pn,Yn=Pn&&qn&&typeof global=="object"&&global&&global.Object&&global||Kn!==(this&&this.window)&&Kn||Dn||this,Zn=d();
+typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Yn._=Zn, define(function(){return Zn})):Pn&&qn?Vn?(qn.exports=Zn)._=Zn:Pn._=Zn:Yn._=Zn}).call(this);
\ No newline at end of file
diff --git a/static/js/nya-bs-select.js b/static/js/nya-bs-select.js
new file mode 100644
index 0000000..b145031
--- /dev/null
+++ b/static/js/nya-bs-select.js
@@ -0,0 +1,1723 @@
+/**
+ * nya-bootstrap-select v2.1.6
+ * Copyright 2014 Nyasoft
+ * Licensed under MIT license
+ */
+(function(){
+ 'use strict';
+
+
+var uid = 0;
+
+function nextUid() {
+ return ++uid;
+}
+
+/**
+ * Checks if `obj` is a window object.
+ *
+ * @private
+ * @param {*} obj Object to check
+ * @returns {boolean} True if `obj` is a window obj.
+ */
+function isWindow(obj) {
+ return obj && obj.window === obj;
+}
+
+/**
+ * @ngdoc function
+ * @name angular.isString
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is a `String`.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `String`.
+ */
+function isString(value){return typeof value === 'string';}
+
+/**
+ * @param {*} obj
+ * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
+ * String ...)
+ */
+function isArrayLike(obj) {
+ if (obj == null || isWindow(obj)) {
+ return false;
+ }
+
+ var length = obj.length;
+
+ if (obj.nodeType === 1 && length) {
+ return true;
+ }
+
+ return isString(obj) || Array.isArray(obj) || length === 0 ||
+ typeof length === 'number' && length > 0 && (length - 1) in obj;
+}
+
+/**
+ * Creates a new object without a prototype. This object is useful for lookup without having to
+ * guard against prototypically inherited properties via hasOwnProperty.
+ *
+ * Related micro-benchmarks:
+ * - http://jsperf.com/object-create2
+ * - http://jsperf.com/proto-map-lookup/2
+ * - http://jsperf.com/for-in-vs-object-keys2
+ *
+ * @returns {Object}
+ */
+function createMap() {
+ return Object.create(null);
+}
+
+/**
+ * Computes a hash of an 'obj'.
+ * Hash of a:
+ * string is string
+ * number is number as string
+ * object is either result of calling $$hashKey function on the object or uniquely generated id,
+ * that is also assigned to the $$hashKey property of the object.
+ *
+ * @param obj
+ * @returns {string} hash string such that the same input will have the same hash string.
+ * The resulting string key is in 'type:hashKey' format.
+ */
+function hashKey(obj, nextUidFn) {
+ var objType = typeof obj,
+ key;
+
+ if (objType == 'function' || (objType == 'object' && obj !== null)) {
+ if (typeof (key = obj.$$hashKey) == 'function') {
+ // must invoke on object to keep the right this
+ key = obj.$$hashKey();
+ } else if (key === undefined) {
+ key = obj.$$hashKey = (nextUidFn || nextUid)();
+ }
+ } else {
+ key = obj;
+ }
+
+ return objType + ':' + key;
+}
+
+//TODO: use with caution. if an property of element in array doesn't exist in group, the resultArray may lose some element.
+function sortByGroup(array ,group, property) {
+ var unknownGroup = [],
+ i, j,
+ resultArray = [];
+ for(i = 0; i < group.length; i++) {
+ for(j = 0; j < array.length;j ++) {
+ if(!array[j][property]) {
+ unknownGroup.push(array[j]);
+ } else if(array[j][property] === group[i]) {
+ resultArray.push(array[j]);
+ }
+ }
+ }
+
+ resultArray = resultArray.concat(unknownGroup);
+
+ return resultArray;
+}
+
+/**
+ * Return the DOM siblings between the first and last node in the given array.
+ * @param {Array} array like object
+ * @returns {jqLite} jqLite collection containing the nodes
+ */
+function getBlockNodes(nodes) {
+ // TODO(perf): just check if all items in `nodes` are siblings and if they are return the original
+ // collection, otherwise update the original collection.
+ var node = nodes[0];
+ var endNode = nodes[nodes.length - 1];
+ var blockNodes = [node];
+
+ do {
+ node = node.nextSibling;
+ if (!node) break;
+ blockNodes.push(node);
+ } while (node !== endNode);
+
+ return angular.element(blockNodes);
+}
+
+var getBlockStart = function(block) {
+ return block.clone[0];
+};
+
+var getBlockEnd = function(block) {
+ return block.clone[block.clone.length - 1];
+};
+
+var updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength, group) {
+ // TODO(perf): generate setters to shave off ~40ms or 1-1.5%
+ scope[valueIdentifier] = value;
+ if (keyIdentifier) scope[keyIdentifier] = key;
+ scope.$index = index;
+ scope.$first = (index === 0);
+ scope.$last = (index === (arrayLength - 1));
+ scope.$middle = !(scope.$first || scope.$last);
+ // jshint bitwise: false
+ scope.$odd = !(scope.$even = (index&1) === 0);
+ // jshint bitwise: true
+
+ if(group) {
+ scope.$group = group;
+ }
+};
+
+var setElementIsolateScope = function(element, scope) {
+ element.data('isolateScope', scope);
+};
+
+var contains = function(array, element) {
+ var length = array.length,
+ i;
+ if(length === 0) {
+ return false;
+ }
+ for(i = 0;i < length; i++) {
+ if(deepEquals(element, array[i])) {
+ return true;
+ }
+ }
+ return false;
+};
+
+var indexOf = function(array, element) {
+ var length = array.length,
+ i;
+ if(length === 0) {
+ return -1;
+ }
+ for(i = 0; i < length; i++) {
+ if(deepEquals(element, array[i])) {
+ return i;
+ }
+ }
+ return -1;
+};
+
+/**
+ * filter the event target for the nya-bs-option element.
+ * Use this method with event delegate. (attach a event handler on an parent element and listen the special children elements)
+ * @param target event.target node
+ * @param parent {object} the parent, where the event handler attached.
+ * @param selector {string}|{object} a class or DOM element
+ * @return the filtered target or null if no element satisfied the selector.
+ */
+var filterTarget = function(target, parent, selector) {
+ var elem = target,
+ className, type = typeof selector;
+
+ if(target == parent) {
+ return null;
+ } else {
+ do {
+ if(type === 'string') {
+ className = ' ' + elem.className + ' ';
+ if(elem.nodeType === 1 && className.replace(/[\t\r\n\f]/g, ' ').indexOf(selector) >= 0) {
+ return elem;
+ }
+ } else {
+ if(elem == selector) {
+ return elem;
+ }
+ }
+
+ } while((elem = elem.parentNode) && elem != parent && elem.nodeType !== 9);
+
+ return null;
+ }
+
+};
+
+var getClassList = function(element) {
+ var classList,
+ className = element.className.replace(/[\t\r\n\f]/g, ' ').trim();
+ classList = className.split(' ');
+ for(var i = 0; i < classList.length; i++) {
+ if(/\s+/.test(classList[i])) {
+ classList.splice(i, 1);
+ i--;
+ }
+ }
+ return classList;
+
+};
+
+// work with node element
+var hasClass = function(element, className) {
+ var classList = getClassList(element);
+ return classList.indexOf(className) !== -1;
+};
+
+// query children by class(one or more)
+var queryChildren = function(element, classList) {
+ var children = element.children(),
+ length = children.length,
+ child,
+ valid,
+ classes;
+ if(length > 0) {
+ for(var i = 0; i < length; i++) {
+ child = children.eq(i);
+ valid = true;
+ classes = getClassList(child[0]);
+ if(classes.length > 0) {
+ for(var j = 0; j < classList.length; j++) {
+ if(classes.indexOf(classList[j]) === -1) {
+ valid = false;
+ break;
+ }
+ }
+ }
+ if(valid) {
+ return child;
+ }
+ }
+ }
+ return [];
+};
+
+/**
+ * Current support only drill down one level.
+ * case insensitive
+ * @param element
+ * @param keyword
+ */
+var hasKeyword = function(element, keyword) {
+ var childElements,
+ index, length;
+ if(element.text().toLowerCase().indexOf(keyword.toLowerCase()) !== -1) {
+ return true;
+ } else {
+ childElements = element.children();
+ length = childElements.length;
+ for(index = 0; index < length; index++) {
+ if(childElements.eq(index).text().toLowerCase().indexOf(keyword.toLowerCase()) !== -1) {
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+function sibling( cur, dir ) {
+ while ( (cur = cur[dir]) && cur.nodeType !== 1) {}
+ return cur;
+}
+
+
+// map global property to local variable.
+var jqLite = angular.element;
+
+var deepEquals = angular.equals;
+
+var deepCopy = angular.copy;
+
+var extend = angular.extend;
+
+var nyaBsSelect = angular.module('nya.bootstrap.select', []);
+
+/**
+ * A service for configuration. the configuration is shared globally.
+ * Testing ci build --jpmckearin
+ */
+nyaBsSelect.provider('nyaBsConfig', function() {
+
+ var locale = null;
+
+ // default localized text. cannot be modified.
+ var defaultText = {
+ 'en-us': {
+ defaultNoneSelection: 'Nothing selected',
+ noSearchResult: 'NO SEARCH RESULT',
+ numberItemSelected: '%d items selected',
+ selectAll: 'Select All',
+ deselectAll: 'Deselect All'
+ }
+ };
+
+ // localized text which actually being used.
+ var interfaceText = deepCopy(defaultText);
+
+ /**
+ * Merge with default localized text.
+ * @param localeId a string formatted as languageId-countryId
+ * @param obj localized text object.
+ */
+ this.setLocalizedText = function(localeId, obj) {
+ if(!localeId) {
+ throw new Error('localeId must be a string formatted as languageId-countryId');
+ }
+ if(!interfaceText[localeId]) {
+ interfaceText[localeId] = {};
+ }
+ interfaceText[localeId] = extend(interfaceText[localeId], obj);
+ };
+
+ /**
+ * Force to use a special locale id. if localeId is null. reset to user-agent locale.
+ * @param localeId a string formatted as languageId-countryId
+ */
+ this.useLocale = function(localeId) {
+ locale = localeId;
+ };
+
+ /**
+ * get the localized text according current locale or forced locale
+ * @returns localizedText
+ */
+ this.$get = ['$locale', function($locale){
+ var localizedText;
+ if(locale) {
+ localizedText = interfaceText[locale];
+ } else {
+ localizedText = interfaceText[$locale.id];
+ }
+ if(!localizedText) {
+ localizedText = defaultText['en-us'];
+ }
+ return localizedText;
+ }];
+
+});
+
+
+nyaBsSelect.controller('nyaBsSelectCtrl', function(){
+
+ var self = this;
+
+ // keyIdentifier and valueIdentifier are set by nyaBsOption directive
+ // used by nyaBsSelect directive to retrieve key and value from each nyaBsOption's child scope.
+ self.keyIdentifier = null;
+ self.valueIdentifier = null;
+
+ self.isMultiple = false;
+
+ // Should be override by nyaBsSelect directive and called by nyaBsOption directive when collection is changed.
+ self.onCollectionChange = function(){};
+
+ // for debug
+ self.setId = function(id) {
+ self.id = id || 'id#' + Math.floor(Math.random() * 10000);
+ };
+
+});
+nyaBsSelect.directive('nyaBsSelect', ['$parse', '$document', '$timeout', '$compile', 'nyaBsConfig', function ($parse, $document, $timeout, $compile, nyaBsConfig) {
+
+ var DEFAULT_NONE_SELECTION = 'Nothing selected';
+
+ var DROPDOWN_TOGGLE = '' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ';
+
+ var DROPDOWN_CONTAINER = '';
+
+ var SEARCH_BOX = '' +
+ ' ' +
+ '
';
+
+ var DROPDOWN_MENU = '';
+
+ var NO_SEARCH_RESULT = 'NO SEARCH RESULT ';
+
+ var ACTIONS_BOX = '' +
+ '
' +
+ 'SELECT ALL ' +
+ 'DESELECT ALL ' +
+ '
' +
+ '
';
+
+ return {
+ restrict: 'ECA',
+ require: ['ngModel', 'nyaBsSelect'],
+ controller: 'nyaBsSelectCtrl',
+ compile: function nyaBsSelectCompile (tElement, tAttrs){
+
+
+ tElement.addClass('btn-group');
+
+
+ /**
+ * get the default text when nothing is selected. can be template
+ * @param scope, if provided, will try to compile template with given scope, will not attempt to compile the pure text.
+ * @returns {*}
+ */
+ var getDefaultNoneSelectionContent = function(scope) {
+ // text node or jqLite element.
+ var content;
+
+ if(tAttrs.titleTpl) {
+ // use title-tpl attribute value.
+ content = jqLite(tAttrs.titleTpl);
+ } else if(tAttrs.title) {
+ // use title attribute value.
+ content = document.createTextNode(tAttrs.title);
+ } else if(localizedText.defaultNoneSelectionTpl){
+ // use localized text template.
+ content = jqLite(localizedText.defaultNoneSelectionTpl);
+ } else if(localizedText.defaultNoneSelection) {
+ // use localized text.
+ content = document.createTextNode(localizedText.defaultNoneSelection);
+ } else {
+ // use default.
+ content = document.createTextNode(DEFAULT_NONE_SELECTION);
+ }
+
+ if(scope && (tAttrs.titleTpl || localizedText.defaultNoneSelectionTpl)) {
+
+ return $compile(content)(scope);
+ }
+
+ return content;
+ };
+
+ var options = tElement.children(),
+ dropdownToggle = jqLite(DROPDOWN_TOGGLE),
+ dropdownContainer = jqLite(DROPDOWN_CONTAINER),
+ dropdownMenu = jqLite(DROPDOWN_MENU),
+ searchBox,
+ noSearchResult,
+ actionsBox,
+ classList,
+ length,
+ index,
+ liElement,
+ localizedText = nyaBsConfig,
+ isMultiple = typeof tAttrs.multiple !== 'undefined',
+ nyaBsOptionValue;
+
+ classList = getClassList(tElement[0]);
+ classList.forEach(function(className) {
+ if(/btn-(?:primary|info|success|warning|danger|inverse)/.test(className)) {
+ tElement.removeClass(className);
+ dropdownToggle.removeClass('btn-default');
+ dropdownToggle.addClass(className);
+ }
+
+ if(/btn-(?:lg|sm|xs)/.test(className)) {
+ tElement.removeClass(className);
+ dropdownToggle.addClass(className);
+ }
+
+ if(className === 'form-control') {
+ dropdownToggle.addClass(className);
+ }
+ });
+
+ dropdownMenu.append(options);
+
+ // add tabindex to children anchor elements if not present.
+ // tabindex attribute will give an anchor element ability to be get focused.
+ length = options.length;
+ for(index = 0; index < length; index++) {
+ liElement = options.eq(index);
+ if(liElement.hasClass('nya-bs-option') || liElement.attr('nya-bs-option')) {
+ liElement.find('a').attr('tabindex', '0');
+ // In order to be compatible with old version, we should copy value of value attribute into data-value attribute.
+ // For the reason we use data-value instead, see http://nya.io/AngularJS/Beware-Of-Using-value-Attribute-On-list-element/
+ nyaBsOptionValue = liElement.attr('value');
+ if(angular.isString(nyaBsOptionValue) && nyaBsOptionValue !== '') {
+ liElement.attr('data-value', nyaBsOptionValue);
+ liElement.removeAttr('value');
+ }
+ }
+ }
+
+ if(tAttrs.liveSearch === 'true') {
+ searchBox = jqLite(SEARCH_BOX);
+
+ if(tAttrs.noSearchTitle) {
+ NO_SEARCH_RESULT = NO_SEARCH_RESULT.replace('NO SEARCH RESULT', tAttrs.noSearchTitle);
+ } else if (tAttrs.noSearchTitleTpl) {
+ NO_SEARCH_RESULT = NO_SEARCH_RESULT.replace('NO SEARCH RESULT', tAttrs.noSearchTitleTpl);
+ }else {
+ // set localized text
+ if(localizedText.noSearchResultTpl) {
+ NO_SEARCH_RESULT = NO_SEARCH_RESULT.replace('NO SEARCH RESULT', localizedText.noSearchResultTpl);
+ } else if(localizedText.noSearchResult) {
+ NO_SEARCH_RESULT = NO_SEARCH_RESULT.replace('NO SEARCH RESULT', localizedText.noSearchResult);
+ }
+ }
+
+ noSearchResult = jqLite(NO_SEARCH_RESULT);
+ dropdownContainer.append(searchBox);
+ dropdownMenu.append(noSearchResult);
+ }
+
+ if (tAttrs.actionsBox === 'true' && isMultiple) {
+ // set localizedText
+ if (localizedText.selectAllTpl) {
+ ACTIONS_BOX = ACTIONS_BOX.replace('SELECT ALL', localizedText.selectAllTpl);
+ } else if (localizedText.selectAll) {
+ ACTIONS_BOX = ACTIONS_BOX.replace('SELECT ALL', localizedText.selectAll);
+ }
+
+ if (localizedText.deselectAllTpl) {
+ ACTIONS_BOX = ACTIONS_BOX.replace('DESELECT ALL', localizedText.deselectAllTpl);
+ } else if (localizedText.selectAll) {
+ ACTIONS_BOX = ACTIONS_BOX.replace('DESELECT ALL', localizedText.deselectAll);
+ }
+
+ actionsBox = jqLite(ACTIONS_BOX);
+ dropdownContainer.append(actionsBox);
+ }
+
+ // set default none selection text
+ jqLite(dropdownToggle[0].querySelector('.special-title')).append(getDefaultNoneSelectionContent());
+
+ dropdownContainer.append(dropdownMenu);
+
+ tElement.append(dropdownToggle);
+ tElement.append(dropdownContainer);
+
+ return function nyaBsSelectLink ($scope, $element, $attrs, ctrls) {
+
+ var ngCtrl = ctrls[0],
+ nyaBsSelectCtrl = ctrls[1],
+ liHeight,
+ isDisabled = false,
+ previousTabIndex,
+ valueExpFn,
+ valueExpGetter = $parse(nyaBsSelectCtrl.valueExp),
+ isMultiple = typeof $attrs.multiple !== 'undefined';
+
+ // find element from current $element root. because the compiled element may be detached from DOM tree by ng-if or ng-switch.
+ var dropdownToggle = jqLite($element[0].querySelector('.dropdown-toggle')),
+ dropdownContainer = dropdownToggle.next(),
+ dropdownMenu = jqLite(dropdownContainer[0].querySelector('.dropdown-menu.inner')),
+ searchBox = jqLite(dropdownContainer[0].querySelector('.bs-searchbox')),
+ noSearchResult = jqLite(dropdownMenu[0].querySelector('.no-search-result')),
+ actionsBox = jqLite(dropdownContainer[0].querySelector('.bs-actionsbox'));
+
+ if(nyaBsSelectCtrl.valueExp) {
+ valueExpFn = function(scope, locals) {
+ return valueExpGetter(scope, locals);
+ };
+ }
+
+ // for debug
+ nyaBsSelectCtrl.setId($element.attr('id'));
+
+ if (isMultiple) {
+ nyaBsSelectCtrl.isMultiple = true;
+
+ // required validator
+ ngCtrl.$isEmpty = function(value) {
+ return !value || value.length === 0;
+ };
+ }
+ if(typeof $attrs.disabled !== 'undefined') {
+ $scope.$watch($attrs.disabled, function(disabled){
+ if(disabled) {
+ dropdownToggle.addClass('disabled');
+ dropdownToggle.attr('disabled', 'disabled');
+ previousTabIndex = dropdownToggle.attr('tabindex');
+ dropdownToggle.attr('tabindex', '-1');
+ isDisabled = true;
+ } else {
+ dropdownToggle.removeClass('disabled');
+ dropdownToggle.removeAttr('disabled');
+ if(previousTabIndex) {
+ dropdownToggle.attr('tabindex', previousTabIndex);
+ } else {
+ dropdownToggle.removeAttr('tabindex');
+ }
+ isDisabled = false;
+ }
+ });
+ }
+
+ /**
+ * Do some check on modelValue. remove no existing value
+ * @param values
+ * @param deepWatched
+ */
+ nyaBsSelectCtrl.onCollectionChange = function (values, deepWatched) {
+ var valuesForSelect = [],
+ index,
+ modelValueChanged = false,
+ // Due to ngModelController compare reference with the old modelValue, we must set an new array instead of modifying the old one.
+ // See: https://github.com/angular/angular.js/issues/1751
+ modelValue = deepCopy(ngCtrl.$modelValue);
+
+ if(!modelValue) {
+ return;
+ }
+
+ /**
+ * Behavior change, since 2.1.0, we don't want to reset model to null or empty array when options' collection is not prepared.
+ */
+ if(Array.isArray(values) && values.length > 0) {
+ if(valueExpFn) {
+ for(index = 0; index < values.length; index++) {
+ valuesForSelect.push(valueExpFn($scope, values[index]));
+ }
+ } else {
+ for(index = 0; index < values.length; index++) {
+ if(nyaBsSelectCtrl.valueIdentifier) {
+ valuesForSelect.push(values[index][nyaBsSelectCtrl.valueIdentifier]);
+ } else if(nyaBsSelectCtrl.keyIdentifier) {
+ valuesForSelect.push(values[index][nyaBsSelectCtrl.keyIdentifier]);
+ }
+ }
+
+ }
+
+ if(isMultiple) {
+ for(index = 0; index < modelValue.length; index++) {
+ if(!contains(valuesForSelect, modelValue[index])) {
+ modelValueChanged = true;
+ modelValue.splice(index, 1);
+ index--;
+ }
+ }
+
+ if(modelValueChanged) {
+ // modelValue changed.
+
+ ngCtrl.$setViewValue(modelValue);
+
+ updateButtonContent();
+ }
+
+ } else {
+ if(!contains(valuesForSelect, modelValue)) {
+ modelValue = valuesForSelect[0];
+
+ ngCtrl.$setViewValue(modelValue);
+
+ updateButtonContent();
+ }
+ }
+
+ }
+
+ /**
+ * if we set deep-watch="true" on nyaBsOption directive,
+ * we need to refresh dropdown button content whenever a change happened in collection.
+ */
+ if(deepWatched) {
+
+ updateButtonContent();
+ }
+
+ };
+
+ // view --> model
+
+ dropdownMenu.on('click', function menuEventHandler (event) {
+ if(isDisabled) {
+ return;
+ }
+
+ if(jqLite(event.target).hasClass('dropdown-header')) {
+ return;
+ }
+ var nyaBsOptionNode = filterTarget(event.target, dropdownMenu[0], 'nya-bs-option'),
+ nyaBsOption;
+
+ if(nyaBsOptionNode !== null) {
+ nyaBsOption = jqLite(nyaBsOptionNode);
+ if(nyaBsOption.hasClass('disabled')) {
+ return;
+ }
+ selectOption(nyaBsOption);
+ }
+ });
+
+ // if click the outside of dropdown menu, close the dropdown menu
+ var outClick = function(event) {
+ if(filterTarget(event.target, $element.parent()[0], $element[0]) === null) {
+ if($element.hasClass('open')) {
+ $element.triggerHandler('blur');
+ }
+ $element.removeClass('open');
+ }
+ };
+ $document.on('click', outClick);
+
+
+
+ dropdownToggle.on('blur', function() {
+ if(!$element.hasClass('open')) {
+ $element.triggerHandler('blur');
+ }
+ });
+ dropdownToggle.on('click', function() {
+ var nyaBsOptionNode;
+ $element.toggleClass('open');
+ if($element.hasClass('open') && typeof liHeight === 'undefined') {
+ calcMenuSize();
+ }
+ if($attrs.liveSearch === 'true' && $element.hasClass('open')) {
+ searchBox.children().eq(0)[0].focus();
+ nyaBsOptionNode = findFocus(true);
+ if(nyaBsOptionNode) {
+ dropdownMenu.children().removeClass('active');
+ jqLite(nyaBsOptionNode).addClass('active');
+ }
+ } else if($element.hasClass('open')) {
+ nyaBsOptionNode = findFocus(true);
+ if(nyaBsOptionNode) {
+ setFocus(nyaBsOptionNode);
+ }
+ }
+ });
+
+ // actions box
+ if ($attrs.actionsBox === 'true' && isMultiple) {
+ actionsBox.find('button').eq(0).on('click', function () {
+ setAllOptions(true);
+ });
+ actionsBox.find('button').eq(1).on('click', function () {
+ setAllOptions(false);
+ });
+ }
+
+
+ // live search
+ if($attrs.liveSearch === 'true') {
+ searchBox.children().on('input', function(){
+
+ var searchKeyword = searchBox.children().val(),
+ found = 0,
+ options = dropdownMenu.children(),
+ length = options.length,
+ index,
+ option,
+ nyaBsOptionNode;
+
+ if(searchKeyword) {
+ for(index = 0; index < length; index++) {
+ option = options.eq(index);
+ if(option.hasClass('nya-bs-option')) {
+ if(!hasKeyword(option.find('a'), searchKeyword)) {
+ option.addClass('not-match');
+ } else {
+ option.removeClass('not-match');
+ found++;
+ }
+ }
+ }
+
+ if(found === 0) {
+ noSearchResult.addClass('show');
+ } else {
+ noSearchResult.removeClass('show');
+ }
+ } else {
+ for(index = 0; index < length; index++) {
+ option = options.eq(index);
+ if(option.hasClass('nya-bs-option')) {
+ option.removeClass('not-match');
+ }
+ }
+ noSearchResult.removeClass('show');
+ }
+
+ nyaBsOptionNode = findFocus(true);
+
+ if(nyaBsOptionNode) {
+ options.removeClass('active');
+ jqLite(nyaBsOptionNode).addClass('active');
+ }
+
+ });
+ }
+
+
+ // model --> view
+
+ ngCtrl.$render = function() {
+ var modelValue = ngCtrl.$modelValue,
+ index,
+ bsOptionElements = dropdownMenu.children(),
+ length = bsOptionElements.length,
+ value;
+ if(typeof modelValue === 'undefined') {
+ // if modelValue is undefined. uncheck all option
+ for(index = 0; index < length; index++) {
+ if(bsOptionElements.eq(index).hasClass('nya-bs-option')) {
+ bsOptionElements.eq(index).removeClass('selected');
+ }
+ }
+ } else {
+ for(index = 0; index < length; index++) {
+ if(bsOptionElements.eq(index).hasClass('nya-bs-option')) {
+
+ value = getOptionValue(bsOptionElements.eq(index));
+ if(isMultiple) {
+ if(contains(modelValue, value)) {
+ bsOptionElements.eq(index).addClass('selected');
+ } else {
+ bsOptionElements.eq(index).removeClass('selected');
+ }
+ } else {
+ if(deepEquals(modelValue, value)) {
+ bsOptionElements.eq(index).addClass('selected');
+ } else {
+ bsOptionElements.eq(index).removeClass('selected');
+ }
+ }
+
+ }
+ }
+ }
+ //console.log(nyaBsSelectCtrl.id + ' render end');
+ updateButtonContent();
+ };
+
+ // simple keyboard support
+ $element.on('keydown', function(event){
+ var keyCode = event.keyCode;
+
+ if(keyCode !== 27 && keyCode !== 13 && keyCode !== 38 && keyCode !== 40) {
+ // we only handle special keys. don't waste time to traverse the dom tree.
+ return;
+ }
+
+ // prevent a click event to be fired.
+ event.preventDefault();
+ if(isDisabled) {
+ event.stopPropagation();
+ return;
+ }
+ var toggleButton = filterTarget(event.target, $element[0], dropdownToggle[0]),
+ menuContainer,
+ searchBoxContainer,
+ liElement,
+ nyaBsOptionNode;
+
+ if($attrs.liveSearch === 'true') {
+ searchBoxContainer = filterTarget(event.target, $element[0], searchBox[0]);
+ } else {
+ menuContainer = filterTarget(event.target, $element[0], dropdownContainer[0])
+ }
+
+ if(toggleButton) {
+
+
+ // press enter to active dropdown
+ if((keyCode === 13 || keyCode === 38 || keyCode === 40) && !$element.hasClass('open')) {
+
+ event.stopPropagation();
+
+ $element.addClass('open');
+
+ // calculate menu size
+ if(typeof liHeight === 'undefined') {
+ calcMenuSize();
+ }
+
+ // if live search enabled. give focus to search box.
+ if($attrs.liveSearch === 'true') {
+ searchBox.children().eq(0)[0].focus();
+ // find the focusable node but we will use active
+ nyaBsOptionNode = findFocus(true);
+ if(nyaBsOptionNode) {
+ // remove previous active state
+ dropdownMenu.children().removeClass('active');
+ // set active to first focusable element
+ jqLite(nyaBsOptionNode).addClass('active');
+ }
+ } else {
+ // otherwise, give focus to first menu item.
+ nyaBsOptionNode = findFocus(true);
+ if(nyaBsOptionNode) {
+ setFocus(nyaBsOptionNode);
+ }
+ }
+ }
+
+ // press enter or escape to de-active dropdown
+ //if((keyCode === 13 || keyCode === 27) && $element.hasClass('open')) {
+ // $element.removeClass('open');
+ // event.stopPropagation();
+ //}
+ } else if(menuContainer) {
+
+ if(keyCode === 27) {
+ // escape pressed
+ dropdownToggle[0].focus();
+ if($element.hasClass('open')) {
+ $element.triggerHandler('blur');
+ }
+ $element.removeClass('open');
+ event.stopPropagation();
+
+ } else if(keyCode === 38) {
+ event.stopPropagation();
+ // up arrow key
+ nyaBsOptionNode = findNextFocus(event.target.parentNode, 'previousSibling');
+ if(nyaBsOptionNode) {
+ setFocus(nyaBsOptionNode);
+ } else {
+ nyaBsOptionNode = findFocus(false);
+ if(nyaBsOptionNode) {
+ setFocus(nyaBsOptionNode);
+ }
+ }
+ } else if(keyCode === 40) {
+ event.stopPropagation();
+ // down arrow key
+ nyaBsOptionNode = findNextFocus(event.target.parentNode, 'nextSibling');
+ if(nyaBsOptionNode) {
+ setFocus(nyaBsOptionNode);
+ } else {
+ nyaBsOptionNode = findFocus(true);
+ if(nyaBsOptionNode) {
+ setFocus(nyaBsOptionNode);
+ }
+ }
+ } else if(keyCode === 13) {
+ event.stopPropagation();
+ // enter pressed
+ liElement = jqLite(event.target.parentNode);
+ if(liElement.hasClass('nya-bs-option')) {
+ selectOption(liElement);
+ if(!isMultiple) {
+ dropdownToggle[0].focus();
+ }
+ }
+ }
+ } else if(searchBoxContainer) {
+ if(keyCode === 27) {
+ dropdownToggle[0].focus();
+ $element.removeClass('open');
+ event.stopPropagation();
+ } else if(keyCode === 38) {
+ // up
+ event.stopPropagation();
+
+ liElement = findActive();
+ if(liElement) {
+ nyaBsOptionNode = findNextFocus(liElement[0], 'previousSibling');
+ if(nyaBsOptionNode) {
+ liElement.removeClass('active');
+ jqLite(nyaBsOptionNode).addClass('active');
+ } else {
+ nyaBsOptionNode = findFocus(false);
+ if(nyaBsOptionNode) {
+ liElement.removeClass('active');
+ jqLite(nyaBsOptionNode).addClass('active');
+ }
+ }
+ }
+
+ } else if(keyCode === 40) {
+ // down
+ event.stopPropagation();
+
+ liElement = findActive();
+ if(liElement) {
+ nyaBsOptionNode = findNextFocus(liElement[0], 'nextSibling');
+ if(nyaBsOptionNode) {
+ liElement.removeClass('active');
+ jqLite(nyaBsOptionNode).addClass('active');
+ } else {
+ nyaBsOptionNode = findFocus(true);
+ if(nyaBsOptionNode) {
+ liElement.removeClass('active');
+ jqLite(nyaBsOptionNode).addClass('active');
+ }
+ }
+ }
+ } else if(keyCode === 13) {
+ // select an option.
+ liElement = findActive();
+ if(liElement) {
+ selectOption(liElement);
+ if(!isMultiple) {
+ dropdownToggle[0].focus();
+ }
+ }
+ }
+ }
+ });
+
+ function findActive() {
+ var list = dropdownMenu.children(),
+ i, liElement,
+ length = list.length;
+ for(i = 0; i < length; i++) {
+ liElement = list.eq(i);
+ if(liElement.hasClass('active') && liElement.hasClass('nya-bs-option') && !liElement.hasClass('not-match')) {
+ return liElement;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * setFocus on a nya-bs-option element. it actually set focus on its child anchor element.
+ * @param elem a nya-bs-option element.
+ */
+ function setFocus(elem) {
+ var childList = elem.childNodes,
+ length = childList.length,
+ child;
+ for(var i = 0; i < length; i++) {
+ child = childList[i];
+ if(child.nodeType === 1 && child.tagName.toLowerCase() === 'a') {
+ child.focus();
+ break;
+ }
+ }
+ }
+
+ function findFocus(fromFirst) {
+ var firstLiElement;
+ if(fromFirst) {
+ firstLiElement = dropdownMenu.children().eq(0);
+ } else {
+ firstLiElement = dropdownMenu.children().eq(dropdownMenu.children().length - 1);
+ }
+
+ // focus on selected element
+ for(var i = 0; i < dropdownMenu.children().length; i++) {
+ var childElement = dropdownMenu.children().eq(i);
+ if (!childElement.hasClass('not-match') && childElement.hasClass('selected')) {
+ return dropdownMenu.children().eq(i)[0];
+ }
+ }
+
+ if(firstLiElement.hasClass('nya-bs-option') && !firstLiElement.hasClass('disabled') && !firstLiElement.hasClass('not-match')) {
+ return firstLiElement[0];
+ } else {
+ if(fromFirst) {
+ return findNextFocus(firstLiElement[0], 'nextSibling');
+ } else {
+ return findNextFocus(firstLiElement[0], 'previousSibling');
+ }
+ }
+ }
+
+ /**
+ * find next focusable element on direction
+ * @param from the element traversed from
+ * @param direction can be 'nextSibling' or 'previousSibling'
+ * @returns the element if found, otherwise return null.
+ */
+ function findNextFocus(from, direction) {
+ if(from && !hasClass(from, 'nya-bs-option')) {
+ return;
+ }
+ var next = from;
+ while ((next = sibling(next, direction)) && next.nodeType) {
+ if(hasClass(next,'nya-bs-option') && !hasClass(next, 'disabled') && !hasClass(next, 'not-match')) {
+ return next
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ */
+ function setAllOptions(selectAll) {
+ if (!isMultiple || isDisabled)
+ return;
+
+ var liElements,
+ wv,
+ viewValue;
+
+ liElements = dropdownMenu[0].querySelectorAll('.nya-bs-option');
+ if (liElements.length > 0) {
+ wv = ngCtrl.$viewValue;
+
+ // make a deep copy enforce ngModelController to call its $render method.
+ // See: https://github.com/angular/angular.js/issues/1751
+ viewValue = Array.isArray(wv) ? deepCopy(wv) : [];
+
+ for (var i = 0; i < liElements.length; i++) {
+ var nyaBsOption = jqLite(liElements[i]);
+ if (nyaBsOption.hasClass('disabled'))
+ continue;
+
+ var value, index;
+
+ // if user specify the value attribute. we should use the value attribute
+ // otherwise, use the valueIdentifier specified field in target scope
+ value = getOptionValue(nyaBsOption);
+
+ if (typeof value !== 'undefined') {
+ index = indexOf(viewValue, value);
+ if (selectAll && index == -1) {
+ // check element
+ viewValue.push(value);
+ nyaBsOption.addClass('selected');
+ } else if (!selectAll && index != -1) {
+ // uncheck element
+ viewValue.splice(index, 1);
+ nyaBsOption.removeClass('selected');
+ }
+ }
+ }
+
+ // update view value regardless
+ ngCtrl.$setViewValue(viewValue);
+ $scope.$digest();
+
+ updateButtonContent();
+ }
+ }
+
+ /**
+ * select an option represented by nyaBsOption argument. Get the option's value and update model.
+ * if isMultiple = true, doesn't close dropdown menu. otherwise close the menu.
+ * @param nyaBsOption the jqLite wrapped `nya-bs-option` element.
+ */
+ function selectOption(nyaBsOption) {
+ var value,
+ viewValue,
+ wv = ngCtrl.$viewValue,
+ index;
+ // if user specify the value attribute. we should use the value attribute
+ // otherwise, use the valueIdentifier specified field in target scope
+
+ value = getOptionValue(nyaBsOption);
+
+ if(typeof value !== 'undefined') {
+ if(isMultiple) {
+ // make a deep copy enforce ngModelController to call its $render method.
+ // See: https://github.com/angular/angular.js/issues/1751
+ viewValue = Array.isArray(wv) ? deepCopy(wv) : [];
+ index = indexOf(viewValue, value);
+ if(index === -1) {
+ // check element
+ viewValue.push(value);
+ nyaBsOption.addClass('selected');
+
+ } else {
+ // uncheck element
+ viewValue.splice(index, 1);
+ nyaBsOption.removeClass('selected');
+
+ }
+
+ } else {
+ dropdownMenu.children().removeClass('selected');
+ viewValue = value;
+ nyaBsOption.addClass('selected');
+
+ }
+ }
+ // update view value regardless
+ ngCtrl.$setViewValue(viewValue);
+ $scope.$digest();
+
+ if(!isMultiple) {
+ // in single selection mode. close the dropdown menu
+ if($element.hasClass('open')) {
+ $element.triggerHandler('blur');
+ }
+ $element.removeClass('open');
+ dropdownToggle[0].focus();
+ }
+ updateButtonContent();
+ }
+
+ /**
+ * get a value of current nyaBsOption. according to different setting.
+ * - if `nya-bs-option` directive is used to populate options and a `value` attribute is specified. use expression of the attribute value.
+ * - if `nya-bs-option` directive is used to populate options and no other settings, use the valueIdentifier or keyIdentifier to retrieve value from scope of current nyaBsOption.
+ * - if `nya-bs-option` class is used on static options. use literal value of the `value` attribute.
+ * @param nyaBsOption a jqLite wrapped `nya-bs-option` element
+ */
+ function getOptionValue(nyaBsOption) {
+ var scopeOfOption;
+ if(valueExpFn) {
+ // here we use the scope bound by ourselves in the nya-bs-option.
+ scopeOfOption = nyaBsOption.data('isolateScope');
+ return valueExpFn(scopeOfOption);
+ } else {
+ if(nyaBsSelectCtrl.valueIdentifier || nyaBsSelectCtrl.keyIdentifier) {
+ scopeOfOption = nyaBsOption.data('isolateScope');
+ return scopeOfOption[nyaBsSelectCtrl.valueIdentifier] || scopeOfOption[nyaBsSelectCtrl.keyIdentifier];
+ } else {
+ return nyaBsOption.attr('data-value');
+ }
+ }
+
+ }
+
+ function getOptionText(nyaBsOption) {
+ var item = nyaBsOption.find('a');
+ if(item.children().length === 0 || item.children().eq(0).hasClass('check-mark')) {
+ // if the first child is check-mark or has no children, means the option text is text node
+ return item[0].firstChild.cloneNode(false);
+ } else {
+ // otherwise we clone the first element of the item
+ return item.children().eq(0)[0].cloneNode(true);
+ }
+ }
+
+ function updateButtonContent() {
+ var viewValue = ngCtrl.$viewValue;
+ $element.triggerHandler('change');
+
+ var filterOption = jqLite(dropdownToggle[0].querySelector('.filter-option'));
+ var specialTitle = jqLite(dropdownToggle[0].querySelector('.special-title'));
+ if(typeof viewValue === 'undefined') {
+ /**
+ * Select empty option when model is undefined.
+ */
+ dropdownToggle.addClass('show-special-title');
+ filterOption.empty();
+ return;
+ }
+ if(isMultiple && viewValue.length === 0) {
+ dropdownToggle.addClass('show-special-title');
+ filterOption.empty();
+ } else {
+ dropdownToggle.removeClass('show-special-title');
+ $timeout(function() {
+
+ var bsOptionElements = dropdownMenu.children(),
+ value,
+ nyaBsOption,
+ index,
+ length = bsOptionElements.length,
+ optionTitle,
+ selection = [],
+ match,
+ count;
+
+ if(isMultiple && $attrs.selectedTextFormat === 'count') {
+ count = 1;
+ } else if(isMultiple && $attrs.selectedTextFormat && (match = $attrs.selectedTextFormat.match(/\s*count\s*>\s*(\d+)\s*/))) {
+ count = parseInt(match[1], 10);
+ }
+
+ // data-selected-text-format="count" or data-selected-text-format="count>x"
+ if((typeof count !== 'undefined') && viewValue.length > count) {
+ filterOption.empty();
+ if(localizedText.numberItemSelectedTpl) {
+ filterOption.append(jqLite(localizedText.numberItemSelectedTpl.replace('%d', viewValue.length)));
+ } else if(localizedText.numberItemSelected) {
+ filterOption.append(document.createTextNode(localizedText.numberItemSelected.replace('%d', viewValue.length)));
+ } else {
+ filterOption.append(document.createTextNode(viewValue.length + ' items selected'));
+ }
+ return;
+ }
+
+ // data-selected-text-format="values" or the number of selected items is less than count
+ for(index = 0; index < length; index++) {
+ nyaBsOption = bsOptionElements.eq(index);
+ if(nyaBsOption.hasClass('nya-bs-option')) {
+
+ value = getOptionValue(nyaBsOption);
+
+ if(isMultiple) {
+ if(Array.isArray(viewValue) && contains(viewValue, value)) {
+ // if option has an title attribute. use the title value as content show in button.
+ // otherwise get very first child element.
+ optionTitle = nyaBsOption.attr('title');
+ if(optionTitle) {
+ selection.push(document.createTextNode(optionTitle));
+ } else {
+ selection.push(getOptionText(nyaBsOption));
+ }
+
+ }
+ } else {
+ if(deepEquals(viewValue, value)) {
+ optionTitle = nyaBsOption.attr('title');
+ if(optionTitle) {
+ selection.push(document.createTextNode(optionTitle));
+ } else {
+ selection.push(getOptionText(nyaBsOption));
+ }
+ }
+ }
+
+ }
+ }
+
+ if(selection.length === 0) {
+ filterOption.empty();
+ dropdownToggle.addClass('show-special-title');
+ } else if(selection.length === 1) {
+ dropdownToggle.removeClass('show-special-title');
+ // either single or multiple selection will show the only selected content.
+ filterOption.empty();
+ filterOption.append(selection[0]);
+ } else {
+ dropdownToggle.removeClass('show-special-title');
+ filterOption.empty();
+ for(index = 0; index < selection.length; index++) {
+ filterOption.append(selection[index]);
+ if(index < selection.length -1) {
+ filterOption.append(document.createTextNode(', '));
+ }
+ }
+ }
+
+ });
+ }
+
+ }
+
+ // will called only once.
+ function calcMenuSize(){
+
+ var liElements = dropdownMenu.find('li'),
+ length = liElements.length,
+ liElement,
+ i;
+ for(i = 0; i < length; i++) {
+ liElement = liElements.eq(i);
+ if(liElement.hasClass('nya-bs-option') || liElement.attr('nya-bs-option')) {
+ liHeight = liElement[0].clientHeight;
+ break;
+ }
+ }
+
+ if(/\d+/.test($attrs.size)) {
+ var dropdownSize = parseInt($attrs.size, 10);
+ dropdownMenu.css('max-height', (dropdownSize * liHeight) + 'px');
+ dropdownMenu.css('overflow-y', 'auto');
+ }
+
+ }
+
+ $scope.$on('$destroy', function() {
+ dropdownMenu.off();
+ dropdownToggle.off();
+ if (searchBox.off) searchBox.off();
+ $document.off('click', outClick);
+
+ });
+
+ };
+ }
+ };
+}]);
+
+nyaBsSelect.directive('nyaBsOption', ['$parse', function($parse){
+
+ //00000011111111111111100000000022222222222222200000003333333333333330000000000000004444444444000000000000000000055555555550000000000000000000006666666666000000
+ var BS_OPTION_REGEX = /^\s*(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/;
+
+ return {
+ restrict: 'A',
+ transclude: 'element',
+ priority: 1000,
+ terminal: true,
+ require: ['^nyaBsSelect', '^ngModel'],
+ compile: function nyaBsOptionCompile (tElement, tAttrs) {
+
+ var expression = tAttrs.nyaBsOption;
+ var nyaBsOptionEndComment = document.createComment(' end nyaBsOption: ' + expression + ' ');
+ var match = expression.match(BS_OPTION_REGEX);
+
+ if(!match) {
+ throw new Error('invalid expression');
+ }
+
+ // we want to keep our expression comprehensible so we don't use 'select as label for value in collection' expression.
+ var valueExp = tAttrs.value,
+ valueExpGetter = valueExp ? $parse(valueExp) : null;
+
+ var valueIdentifier = match[3] || match[1],
+ keyIdentifier = match[2],
+ collectionExp = match[4],
+ groupByExpGetter = match[5] ? $parse(match[5]) : null,
+ trackByExp = match[6];
+
+ var trackByIdArrayFn,
+ trackByIdObjFn,
+ trackByIdExpFn,
+ trackByExpGetter;
+ var hashFnLocals = {$id: hashKey};
+ var groupByFn, locals = {};
+
+ if(trackByExp) {
+ trackByExpGetter = $parse(trackByExp);
+ } else {
+ trackByIdArrayFn = function(key, value) {
+ return hashKey(value);
+ };
+ trackByIdObjFn = function(key) {
+ return key;
+ };
+ }
+ return function nyaBsOptionLink($scope, $element, $attr, ctrls, $transclude) {
+
+ var nyaBsSelectCtrl = ctrls[0],
+ ngCtrl = ctrls[1],
+ valueExpFn,
+ deepWatched,
+ valueExpLocals = {};
+
+ if(trackByExpGetter) {
+ trackByIdExpFn = function(key, value, index) {
+ // assign key, value, and $index to the locals so that they can be used in hash functions
+ if (keyIdentifier) {
+ hashFnLocals[keyIdentifier] = key;
+ }
+ hashFnLocals[valueIdentifier] = value;
+ hashFnLocals.$index = index;
+ return trackByExpGetter($scope, hashFnLocals);
+ };
+ }
+
+ if(groupByExpGetter) {
+ groupByFn = function(key, value) {
+ if(keyIdentifier) {
+ locals[keyIdentifier] = key;
+ }
+ locals[valueIdentifier] = value;
+ return groupByExpGetter($scope, locals);
+ }
+ }
+
+ // set keyIdentifier and valueIdentifier property of nyaBsSelectCtrl
+ if(keyIdentifier) {
+ nyaBsSelectCtrl.keyIdentifier = keyIdentifier;
+ }
+ if(valueIdentifier) {
+ nyaBsSelectCtrl.valueIdentifier = valueIdentifier;
+ }
+
+ if(valueExpGetter) {
+ nyaBsSelectCtrl.valueExp = valueExp;
+ valueExpFn = function(key, value) {
+ if(keyIdentifier) {
+ valueExpLocals[keyIdentifier] = key;
+ }
+ valueExpLocals[valueIdentifier] = value;
+ return valueExpGetter($scope, valueExpLocals);
+ }
+
+ }
+
+
+ // Store a list of elements from previous run. This is a hash where key is the item from the
+ // iterator, and the value is objects with following properties.
+ // - scope: bound scope
+ // - element: previous element.
+ // - index: position
+ //
+ // We are using no-proto object so that we don't need to guard against inherited props via
+ // hasOwnProperty.
+ var lastBlockMap = createMap();
+
+ // deepWatch will impact performance. use with caution.
+ if($attr.deepWatch === 'true') {
+ deepWatched = true;
+ $scope.$watch(collectionExp, nyaBsOptionAction, true);
+ } else {
+ deepWatched = false;
+ $scope.$watchCollection(collectionExp, nyaBsOptionAction);
+ }
+
+ function nyaBsOptionAction(collection) {
+ var index,
+
+ previousNode = $element[0], // node that cloned nodes should be inserted after
+ // initialized to the comment node anchor
+
+ key, value,
+ trackById,
+ trackByIdFn,
+ collectionKeys,
+ collectionLength,
+ // Same as lastBlockMap but it has the current state. It will become the
+ // lastBlockMap on the next iteration.
+ nextBlockMap = createMap(),
+ nextBlockOrder,
+ block,
+ groupName,
+ nextNode,
+ group,
+ lastGroup,
+
+ removedClone, // removed clone node, should also remove isolateScope data as well
+
+ values = [],
+ valueObj; // the collection value
+
+ if(groupByFn) {
+ group = [];
+ }
+
+ if(isArrayLike(collection)) {
+ collectionKeys = collection;
+ trackByIdFn = trackByIdExpFn || trackByIdArrayFn;
+ } else {
+ trackByIdFn = trackByIdExpFn || trackByIdObjFn;
+ // if object, extract keys, sort them and use to determine order of iteration over obj props
+ collectionKeys = [];
+ for (var itemKey in collection) {
+ if (collection.hasOwnProperty(itemKey) && itemKey.charAt(0) != '$') {
+ collectionKeys.push(itemKey);
+ }
+ }
+ collectionKeys.sort();
+ }
+ collectionLength = collectionKeys.length;
+ nextBlockOrder = new Array(collectionLength);
+
+ for(index = 0; index < collectionLength; index++) {
+ key = (collection === collectionKeys) ? index : collectionKeys[index];
+ value = collection[key];
+ trackById = trackByIdFn(key, value, index);
+
+ // copy the value with scope like structure to notify the select directive.
+ valueObj = {};
+ if(keyIdentifier) {
+ valueObj[keyIdentifier] = key;
+ }
+
+ valueObj[valueIdentifier] = value;
+ values.push(valueObj);
+
+ if(groupByFn) {
+ groupName = groupByFn(key, value);
+ if(group.indexOf(groupName) === -1 && groupName) {
+ group.push(groupName);
+ }
+ }
+
+ if(lastBlockMap[trackById]) {
+ // found previously seen block
+ block = lastBlockMap[trackById];
+ delete lastBlockMap[trackById];
+
+ // must update block here because some data we stored may change.
+ if(groupByFn) {
+ block.group = groupName;
+ }
+ block.key = key;
+ block.value = value;
+
+ nextBlockMap[trackById] = block;
+ nextBlockOrder[index] = block;
+ } else if(nextBlockMap[trackById]) {
+ //if collision detected. restore lastBlockMap and throw an error
+ nextBlockOrder.forEach(function(block) {
+ if(block && block.scope) {
+ lastBlockMap[block.id] = block;
+ }
+ });
+ throw new Error("Duplicates in a select are not allowed. Use 'track by' expression to specify unique keys.");
+ } else {
+ // new never before seen block
+ nextBlockOrder[index] = {id: trackById, scope: undefined, clone: undefined, key: key, value: value};
+ nextBlockMap[trackById] = true;
+ if(groupName) {
+ nextBlockOrder[index].group = groupName;
+ }
+ }
+ }
+
+ // only resort nextBlockOrder when group found
+ if(group && group.length > 0) {
+
+ nextBlockOrder = sortByGroup(nextBlockOrder, group, 'group');
+ }
+
+ // remove DOM nodes
+ for( var blockKey in lastBlockMap) {
+ block = lastBlockMap[blockKey];
+ removedClone = getBlockNodes(block.clone);
+ // remove the isolateScope data to detach scope from this clone
+ removedClone.removeData('isolateScope');
+ removedClone.remove();
+ block.scope.$destroy();
+ }
+
+ for(index = 0; index < collectionLength; index++) {
+ block = nextBlockOrder[index];
+ if(block.scope) {
+ // if we have already seen this object, then we need to reuse the
+ // associated scope/element
+
+ nextNode = previousNode;
+ if(getBlockStart(block) != nextNode) {
+ jqLite(previousNode).after(block.clone);
+ }
+ previousNode = getBlockEnd(block);
+
+ updateScope(block.scope, index, valueIdentifier, block.value, keyIdentifier, block.key, collectionLength, block.group);
+ } else {
+ $transclude(function nyaBsOptionTransclude(clone, scope) {
+ // in case of the debugInfoEnable is set to false, we have to bind the scope to the clone node.
+ setElementIsolateScope(clone, scope);
+
+ block.scope = scope;
+
+ var endNode = nyaBsOptionEndComment.cloneNode(false);
+ clone[clone.length++] = endNode;
+
+ jqLite(previousNode).after(clone);
+
+ // add nya-bs-option class
+ clone.addClass('nya-bs-option');
+
+ // for newly created item we need to ensure its selected status from the model value.
+ if(valueExpFn) {
+ value = valueExpFn(block.key, block.value);
+ } else {
+ value = block.value || block.key;
+ }
+
+ if(nyaBsSelectCtrl.isMultiple) {
+ if(Array.isArray(ngCtrl.$modelValue) && contains(ngCtrl.$modelValue, value)) {
+ clone.addClass('selected');
+ }
+ } else {
+ if(deepEquals(value, ngCtrl.$modelValue)) {
+ clone.addClass('selected');
+ }
+ }
+
+ previousNode = endNode;
+ // Note: We only need the first/last node of the cloned nodes.
+ // However, we need to keep the reference to the jqlite wrapper as it might be changed later
+ // by a directive with templateUrl when its template arrives.
+ block.clone = clone;
+ nextBlockMap[block.id] = block;
+ updateScope(block.scope, index, valueIdentifier, block.value, keyIdentifier, block.key, collectionLength, block.group);
+ });
+
+ }
+
+ // we need to mark the first item of a group
+ if(group) {
+ if(!lastGroup || lastGroup !== block.group) {
+ block.clone.addClass('first-in-group');
+ } else {
+ block.clone.removeClass('first-in-group');
+ }
+
+ lastGroup = block.group;
+
+ // add special class for indent
+ block.clone.addClass('group-item');
+ }
+ }
+
+ lastBlockMap = nextBlockMap;
+
+ nyaBsSelectCtrl.onCollectionChange(values, deepWatched);
+ }
+ };
+ }
+ }
+}]);
+
+
+})();
\ No newline at end of file
diff --git a/static/js/nya-bs-select.min.js b/static/js/nya-bs-select.min.js
new file mode 100644
index 0000000..ec38c8b
--- /dev/null
+++ b/static/js/nya-bs-select.min.js
@@ -0,0 +1,6 @@
+/**
+ * nya-bootstrap-select v2.0.10
+ * Copyright 2014 Nyasoft
+ * Licensed under MIT license
+ */
+!function(){"use strict";function a(){return++j}function b(a){return a&&a.window===a}function c(a){return"string"==typeof a}function d(a){if(null==a||b(a))return!1;var d=a.length;return 1===a.nodeType&&d?!0:c(a)||Array.isArray(a)||0===d||"number"==typeof d&&d>0&&d-1 in a}function e(){return Object.create(null)}function f(b,c){var d,e=typeof b;return"function"==e||"object"==e&&null!==b?"function"==typeof(d=b.$$hashKey)?d=b.$$hashKey():void 0===d&&(d=b.$$hashKey=(c||a)()):d=b,e+":"+d}function g(a,b,c){var d,e,f=[],g=[];for(d=0;dc;c++)if(v(b,a[c]))return!0;return!1},o=function(a,b){var c,d=a.length;if(0===d)return-1;for(c=0;d>c;c++)if(v(b,a[c]))return c;return-1},p=function(a,b,c){var d,e=a,f=typeof c;if(a==b)return null;do if("string"===f){if(d=" "+e.className+" ",1===e.nodeType&&d.replace(/[\t\r\n\f]/g," ").indexOf(c)>=0)return e}else if(e==c)return e;while((e=e.parentNode)&&e!=b&&9!==e.nodeType);return null},q=function(a){var b,c=a.className.replace(/[\t\r\n\f]/g," ").trim();b=c.split(" ");for(var d=0;d0)for(var h=0;g>h;h++){if(c=f.eq(h),d=!0,e=q(c[0]),e.length>0)for(var i=0;id;d++)if(-1!==c.eq(d).text().toLowerCase().indexOf(b.toLowerCase()))return!0;return!1},u=angular.element,v=angular.equals,w=angular.copy,x=angular.extend,y=angular.module("nya.bootstrap.select",[]);y.provider("nyaBsConfig",function(){var a=null,b={"en-us":{defaultNoneSelection:"Nothing selected",noSearchResult:"NO SEARCH RESULT",numberItemSelected:"%d item selected"}},c=w(b);this.setLocalizedText=function(a,b){if(!a)throw new Error("localeId must be a string formatted as languageId-countryId");c[a]||(c[a]={}),c[a]=x(c[a],b)},this.useLocale=function(b){a=b},this.$get=["$locale",function(d){var e;return e=a?c[a]:c[d.id],e||(e=b["en-us"]),e}]}),y.controller("nyaBsSelectCtrl",function(){var a=this;a.keyIdentifier=null,a.valueIdentifier=null,a.isMultiple=!1,a.onCollectionChange=function(){},a.setId=function(b){a.id=b||"id#"+Math.floor(1e4*Math.random())}}),y.directive("nyaBsSelect",["$parse","$document","$timeout","nyaBsConfig",function(a,b,c,d){var e="Nothing selected",f=' ',g='',h='
',j='',k='NO SEARCH RESULT ';return{restrict:"ECA",require:["ngModel","nyaBsSelect"],controller:"nyaBsSelectCtrl",compile:function(l,m){l.addClass("btn-group");var x,y,z,A,B,C,D=function(){var a;return a=m.titleTpl?u(m.titleTpl):m.title?document.createTextNode(m.title):I.defaultNoneSelectionTpl?u(I.defaultNoneSelectionTpl):document.createTextNode(I.defaultNoneSelection?I.defaultNoneSelection:e)},E=l.children(),F=u(f),G=u(g),H=u(j),I=d;for(z=q(l[0]),z.forEach(function(a){/btn-(?:primary|info|success|warning|danger|inverse)/.test(a)&&(l.removeClass(a),F.removeClass("btn-default"),F.addClass(a)),"form-control"===a&&F.addClass(a)}),H.append(E),A=E.length,B=0;A>B;B++)C=E.eq(B),(C.hasClass("nya-bs-option")||C.attr("nya-bs-option"))&&C.find("a").attr("tabindex","0");return"true"===m.liveSearch&&(x=u(h),I.noSearchResultTpl?k=k.replace("NO SEARCH RESULT",I.noSearchResultTpl):I.noSearchResult&&(k=k.replace("NO SEARCH RESULT",I.noSearchResult)),y=u(k),G.append(x),H.append(y)),F.children().eq(0).append(D()),G.append(H),l.append(F),l.append(G),function(d,e,f,g){function h(){var a,b,c=M.children(),d=c.length;for(a=0;d>a;a++)if(b=c.eq(a),b.hasClass("active")&&b.hasClass("nya-bs-option"))return b;return null}function j(a){for(var b,c=a.childNodes,d=c.length,e=0;d>e;e++)if(b=c[e],1===b.nodeType&&"a"===b.tagName.toLowerCase()){b.focus();break}}function k(a){var b;b=M.children().eq(a?0:M.children().length-1);for(var c=0;c\s*(\d+)\s*/))&&(i=parseInt(h[1],10)),"undefined"!=typeof i&&a.length>i)return b.empty(),void b.append(I.numberItemSelectedTpl?u(I.numberItemSelectedTpl.replace("%d",a.length)):I.numberItemSelected?document.createTextNode(I.numberItemSelected.replace("%d",a.length)):document.createTextNode(a.length+" items selected"));for(e=0;k>e;e++)d=j.eq(e),d.hasClass("nya-bs-option")&&(c=q(d),J?Array.isArray(a)&&n(a,c)&&(g=d.attr("title"),l.push(g?document.createTextNode(g):x(d))):v(a,c)&&(g=d.attr("title"),l.push(g?document.createTextNode(g):x(d))));if(0===l.length)b.empty(),b.append(D());else if(1===l.length)b.empty(),b.append(l[0]);else for(b.empty(),e=0;eb;b++)if(a=c.eq(b),a.hasClass("nya-bs-option")||a.attr("nya-bs-option")){A=a[0].clientHeight;break}if(/\d+/.test(f.size)){var e=parseInt(f.size,10);M.css("max-height",e*A+"px"),M.css("overflow-y","auto")}}var A,B,C,E=g[0],F=g[1],G=!1,H=a(F.valueExp),J="undefined"!=typeof f.multiple,K=s(e,["dropdown-toggle"]),L=K.next(),M=s(L,["dropdown-menu","inner"]),N=s(L,["bs-searchbox"]),O=s(M,["no-search-result"]);F.valueExp&&(C=function(a,b){return H(a,b)}),F.setId(e.attr("id")),J&&(F.isMultiple=!0,E.$isEmpty=function(a){return!a||0===a.length}),"undefined"!=typeof f.disabled&&d.$watch(f.disabled,function(a){a?(K.addClass("disabled"),B=K.attr("tabindex"),K.attr("tabindex","-1"),G=!0):(K.removeClass("disabled"),B?K.attr("tabindex",B):K.removeAttr("tabindex"),G=!1)}),F.onCollectionChange=function(a){var b,c,e=[],f=E.$modelValue;if(f){if(a&&0!==a.length){if(C)for(b=0;ba;a++)b=f.eq(a),b.hasClass("nya-bs-option")&&(t(b.find("a"),d)?(b.removeClass("not-match"),e++):b.addClass("not-match"));0===e?O.addClass("show"):O.removeClass("show")}else{for(a=0;g>a;a++)b=f.eq(a),b.hasClass("nya-bs-option")&&b.removeClass("not-match");O.removeClass("show")}c=k(!0),c&&(f.removeClass("active"),u(c).addClass("active"))}),E.$render=function(){var a,b,c=E.$modelValue,d=M.children(),e=d.length;if("undefined"==typeof c)for(a=0;e>a;a++)d.eq(a).hasClass("nya-bs-option")&&d.eq(a).removeClass("selected");else for(a=0;e>a;a++)d.eq(a).hasClass("nya-bs-option")&&(b=q(d.eq(a)),J?n(c,b)?d.eq(a).addClass("selected"):d.eq(a).removeClass("selected"):v(c,b)?d.eq(a).addClass("selected"):d.eq(a).removeClass("selected"));y()},e.on("keydown",function(a){var b=a.keyCode;if(27===b||13===b||38===b||40===b){if(a.preventDefault(),G)return void a.stopPropagation();var c,d,g,i,n=p(a.target,e[0],K[0]);"true"===f.liveSearch?d=p(a.target,e[0],N[0]):c=p(a.target,e[0],L[0]),n?13!==b&&38!==b&&40!==b||e.hasClass("open")||(a.stopPropagation(),e.addClass("open"),"undefined"==typeof A&&z(),"true"===f.liveSearch?(N.children().eq(0)[0].focus(),i=k(!0),i&&(M.children().removeClass("active"),u(i).addClass("active"))):(i=k(!0),i&&j(i))):c?27===b?(K[0].focus(),e.hasClass("open")&&e.triggerHandler("blur"),e.removeClass("open"),a.stopPropagation()):38===b?(a.stopPropagation(),i=l(a.target.parentNode,"previousSibling"),i?j(i):(i=k(!1),i&&j(i))):40===b?(a.stopPropagation(),i=l(a.target.parentNode,"nextSibling"),i?j(i):(i=k(!0),i&&j(i))):13===b&&(a.stopPropagation(),g=u(a.target.parentNode),g.hasClass("nya-bs-option")&&(m(g),J||K[0].focus())):d&&(27===b?(K[0].focus(),e.removeClass("open"),a.stopPropagation()):38===b?(a.stopPropagation(),g=h(),g&&(i=l(g[0],"previousSibling"),i?(g.removeClass("active"),u(i).addClass("active")):(i=k(!1),i&&(g.removeClass("active"),u(i).addClass("active"))))):40===b?(a.stopPropagation(),g=h(),g&&(i=l(g[0],"nextSibling"),i?(g.removeClass("active"),u(i).addClass("active")):(i=k(!0),i&&(g.removeClass("active"),u(i).addClass("active"))))):13===b&&(g=h(),g&&(m(g),J||K[0].focus())))}})}}}}]),y.directive("nyaBsOption",["$parse",function(a){var b=/^\s*(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/;return{restrict:"A",transclude:"element",priority:1e3,terminal:!0,require:["^nyaBsSelect","^ngModel"],compile:function(c,i){var j=i.nyaBsOption,o=document.createComment(" end nyaBsOption: "+j+" "),p=j.match(b);if(!p)throw new Error("invalid expression");var q,r,s,t,w,x=i.value,y=x?a(x):null,z=p[3]||p[1],A=p[2],B=p[4],C=p[5]?a(p[5]):null,D=p[6],E={$id:f},F={};return D?t=a(D):(q=function(a,b){return f(b)},r=function(a){return a}),function(a,b,c,f,i){function j(a){var c,f,j,t,x,y,B,C,E,F,H,J,K,L,M=b[0],N=e(),O=[];if(w&&(J=[]),d(a))y=a,x=s||q;else{x=s||r,y=[];for(var P in a)a.hasOwnProperty(P)&&"$"!=P.charAt(0)&&y.push(P);y.sort()}for(B=y.length,C=new Array(B),c=0;B>c;c++)if(f=a===y?c:y[c],j=a[f],t=x(f,j,c),L={},A&&(L[A]=f),L[z]=j,O.push(L),w&&(F=w(f,j),-1===J.indexOf(F)&&F&&J.push(F)),I[t])E=I[t],delete I[t],w&&(E.group=F),E.key=f,E.value=j,N[t]=E,C[c]=E;else{if(N[t])throw C.forEach(function(a){a&&a.scope&&(I[a.id]=a)}),new Error("Duplicates in a select are not allowed. Use 'track by' expression to specify unique keys.");C[c]={id:t,scope:void 0,clone:void 0,key:f,value:j},N[t]=!0,F&&(C[c].group=F)}J&&J.length>0&&(C=g(C,J,"group"));for(var Q in I)E=I[Q],h(E.clone).remove(),E.scope.$destroy();for(c=0;B>c;c++)E=C[c],E.scope?(H=M,k(E)!=H&&u(M).after(E.clone),M=l(E),m(E.scope,c,z,E.value,A,E.key,B,E.group)):i(function(a,b){E.scope=b;var d=o.cloneNode(!1);a[a.length++]=d,u(M).after(a),a.addClass("nya-bs-option"),j=p?p(E.key,E.value):E.value||E.key,D.isMultiple?Array.isArray(G.$modelValue)&&n(G.$modelValue,j)&&a.addClass("selected"):v(j,G.$modelValue)&&a.addClass("selected"),M=d,E.clone=a,N[E.id]=E,m(E.scope,c,z,E.value,A,E.key,B,E.group)}),J&&(K&&K===E.group?E.clone.removeClass("first-in-group"):E.clone.addClass("first-in-group"),K=E.group,E.clone.addClass("group-item"));I=N,D.onCollectionChange(O)}var p,D=f[0],G=f[1],H={};t&&(s=function(b,c,d){return A&&(E[A]=b),E[z]=c,E.$index=d,t(a,E)}),C&&(w=function(b,c){return A&&(F[A]=b),F[z]=c,C(a,F)}),A&&(D.keyIdentifier=A),z&&(D.valueIdentifier=z),y&&(D.valueExp=x,p=function(b,c){return A&&(H[A]=b),H[z]=c,y(a,H)});var I=e();"true"===c.deepWatch?a.$watch(B,j,!0):a.$watchCollection(B,j)}}}}])}();
\ No newline at end of file
diff --git a/static/js/textAngular-rangy.min.js b/static/js/textAngular-rangy.min.js
new file mode 100644
index 0000000..c1112b0
--- /dev/null
+++ b/static/js/textAngular-rangy.min.js
@@ -0,0 +1,2 @@
+!function(a,b){"function"==typeof define&&define.amd?define(a):"undefined"!=typeof module&&"object"==typeof exports?module.exports=a():b.rangy=a()}(function(){function a(a,b){var c=typeof a[b];return c==u||!(c!=t||!a[b])||"unknown"==c}function b(a,b){return!(typeof a[b]!=t||!a[b])}function c(a,b){return typeof a[b]!=v}function d(a){return function(b,c){for(var d=c.length;d--;)if(!a(b,c[d]))return!1;return!0}}function e(a){return a&&A(a,z)&&C(a,y)}function f(a){return b(a,"body")?a.body:a.getElementsByTagName("body")[0]}function g(b){typeof console!=v&&a(console,"log")&&console.log(b)}function h(a,b){F&&b?alert(a):g(a)}function i(a){H.initialized=!0,H.supported=!1,h("Rangy is not supported in this environment. Reason: "+a,H.config.alertOnFail)}function j(a){h("Rangy warning: "+a,H.config.alertOnWarn)}function k(a){return a.message||a.description||String(a)}function l(){if(F&&!H.initialized){var b,c=!1,d=!1;a(document,"createRange")&&(b=document.createRange(),A(b,x)&&C(b,w)&&(c=!0));var h=f(document);if(!h||"body"!=h.nodeName.toLowerCase())return void i("No body element found");if(h&&a(h,"createTextRange")&&(b=h.createTextRange(),e(b)&&(d=!0)),!c&&!d)return void i("Neither Range nor TextRange are available");H.initialized=!0,H.features={implementsDomRange:c,implementsTextRange:d};var j,l;for(var m in E)(j=E[m])instanceof p&&j.init(j,H);for(var n=0,o=K.length;o>n;++n)try{K[n](H)}catch(q){l="Rangy init listener threw an exception. Continuing. Detail: "+k(q),g(l)}}}function m(a,b,c){c&&(a+=" in module "+c.name),H.warn("DEPRECATED: "+a+" is deprecated. Please use "+b+" instead.")}function n(a,b,c,d){a[b]=function(){return m(b,c,d),a[c].apply(a,G.toArray(arguments))}}function o(a){a=a||window,l();for(var b=0,c=L.length;c>b;++b)L[b](a)}function p(a,b,c){this.name=a,this.dependencies=b,this.initialized=!1,this.supported=!1,this.initializer=c}function q(a,b,c){var d=new p(a,b,function(b){if(!b.initialized){b.initialized=!0;try{c(H,b),b.supported=!0}catch(d){var e="Module '"+a+"' failed to load: "+k(d);g(e),d.stack&&g(d.stack)}}});return E[a]=d,d}function r(){}function s(){}var t="object",u="function",v="undefined",w=["startContainer","startOffset","endContainer","endOffset","collapsed","commonAncestorContainer"],x=["setStart","setStartBefore","setStartAfter","setEnd","setEndBefore","setEndAfter","collapse","selectNode","selectNodeContents","compareBoundaryPoints","deleteContents","extractContents","cloneContents","insertNode","surroundContents","cloneRange","toString","detach"],y=["boundingHeight","boundingLeft","boundingTop","boundingWidth","htmlText","text"],z=["collapse","compareEndPoints","duplicate","moveToElementText","parentElement","select","setEndPoint","getBoundingClientRect"],A=d(a),B=d(b),C=d(c),D=[].forEach?function(a,b){a.forEach(b)}:function(a,b){for(var c=0,d=a.length;d>c;++c)b(a[c],c)},E={},F=typeof window!=v&&typeof document!=v,G={isHostMethod:a,isHostObject:b,isHostProperty:c,areHostMethods:A,areHostObjects:B,areHostProperties:C,isTextRange:e,getBody:f,forEach:D},H={version:"1.3.0",initialized:!1,isBrowser:F,supported:!0,util:G,features:{},modules:E,config:{alertOnFail:!1,alertOnWarn:!1,preferTextRange:!1,autoInitialize:typeof rangyAutoInitialize==v?!0:rangyAutoInitialize}};H.fail=i,H.warn=j;var I;({}).hasOwnProperty?(G.extend=I=function(a,b,c){var d,e;for(var f in b)b.hasOwnProperty(f)&&(d=a[f],e=b[f],c&&null!==d&&"object"==typeof d&&null!==e&&"object"==typeof e&&I(d,e,!0),a[f]=e);return b.hasOwnProperty("toString")&&(a.toString=b.toString),a},G.createOptions=function(a,b){var c={};return I(c,b),a&&I(c,a),c}):i("hasOwnProperty not supported"),F||i("Rangy can only run in a browser"),function(){var a;if(F){var b=document.createElement("div");b.appendChild(document.createElement("span"));var c=[].slice;try{1==c.call(b.childNodes,0)[0].nodeType&&(a=function(a){return c.call(a,0)})}catch(d){}}a||(a=function(a){for(var b=[],c=0,d=a.length;d>c;++c)b[c]=a[c];return b}),G.toArray=a}();var J;F&&(a(document,"addEventListener")?J=function(a,b,c){a.addEventListener(b,c,!1)}:a(document,"attachEvent")?J=function(a,b,c){a.attachEvent("on"+b,c)}:i("Document does not have required addEventListener or attachEvent method"),G.addListener=J);var K=[];G.deprecationNotice=m,G.createAliasForDeprecatedMethod=n,H.init=l,H.addInitListener=function(a){H.initialized?a(H):K.push(a)};var L=[];H.addShimListener=function(a){L.push(a)},F&&(H.shim=H.createMissingNativeApi=o,n(H,"createMissingNativeApi","shim")),p.prototype={init:function(){for(var a,b,c=this.dependencies||[],d=0,e=c.length;e>d;++d){if(b=c[d],a=E[b],!(a&&a instanceof p))throw new Error("required module '"+b+"' not found");if(a.init(),!a.supported)throw new Error("required module '"+b+"' not supported")}this.initializer(this)},fail:function(a){throw this.initialized=!0,this.supported=!1,new Error(a)},warn:function(a){H.warn("Module "+this.name+": "+a)},deprecationNotice:function(a,b){H.warn("DEPRECATED: "+a+" in module "+this.name+" is deprecated. Please use "+b+" instead")},createError:function(a){return new Error("Error in Rangy "+this.name+" module: "+a)}},H.createModule=function(a){var b,c;2==arguments.length?(b=arguments[1],c=[]):(b=arguments[2],c=arguments[1]);var d=q(a,c,b);H.initialized&&H.supported&&d.init()},H.createCoreModule=function(a,b,c){q(a,b,c)},H.RangePrototype=r,H.rangePrototype=new r,H.selectionPrototype=new s,H.createCoreModule("DomUtil",[],function(a,b){function c(a){var b;return typeof a.namespaceURI==F||null===(b=a.namespaceURI)||"http://www.w3.org/1999/xhtml"==b}function d(a){var b=a.parentNode;return 1==b.nodeType?b:null}function e(a){for(var b=0;a=a.previousSibling;)++b;return b}function f(a){switch(a.nodeType){case 7:case 10:return 0;case 3:case 8:return a.length;default:return a.childNodes.length}}function g(a,b){var c,d=[];for(c=a;c;c=c.parentNode)d.push(c);for(c=b;c;c=c.parentNode)if(K(d,c))return c;return null}function h(a,b,c){for(var d=c?b:b.parentNode;d;){if(d===a)return!0;d=d.parentNode}return!1}function i(a,b){return h(a,b,!0)}function j(a,b,c){for(var d,e=c?a:a.parentNode;e;){if(d=e.parentNode,d===b)return e;e=d}return null}function k(a){var b=a.nodeType;return 3==b||4==b||8==b}function l(a){if(!a)return!1;var b=a.nodeType;return 3==b||8==b}function m(a,b){var c=b.nextSibling,d=b.parentNode;return c?d.insertBefore(a,c):d.appendChild(a),a}function n(a,b,c){var d=a.cloneNode(!1);if(d.deleteData(0,b),a.deleteData(b,a.length-b),m(d,a),c)for(var f,g=0;f=c[g++];)f.node==a&&f.offset>b?(f.node=d,f.offset-=b):f.node==a.parentNode&&f.offset>e(a)&&++f.offset;return d}function o(a){if(9==a.nodeType)return a;if(typeof a.ownerDocument!=F)return a.ownerDocument;if(typeof a.document!=F)return a.document;if(a.parentNode)return o(a.parentNode);throw b.createError("getDocument: no document found for node")}function p(a){var c=o(a);if(typeof c.defaultView!=F)return c.defaultView;if(typeof c.parentWindow!=F)return c.parentWindow;throw b.createError("Cannot get a window object for node")}function q(a){if(typeof a.contentDocument!=F)return a.contentDocument;if(typeof a.contentWindow!=F)return a.contentWindow.document;throw b.createError("getIframeDocument: No Document object found for iframe element")}function r(a){if(typeof a.contentWindow!=F)return a.contentWindow;if(typeof a.contentDocument!=F)return a.contentDocument.defaultView;throw b.createError("getIframeWindow: No Window object found for iframe element")}function s(a){return a&&G.isHostMethod(a,"setTimeout")&&G.isHostObject(a,"document")}function t(a,b,c){var d;if(a?G.isHostProperty(a,"nodeType")?d=1==a.nodeType&&"iframe"==a.tagName.toLowerCase()?q(a):o(a):s(a)&&(d=a.document):d=document,!d)throw b.createError(c+"(): Parameter must be a Window object or DOM node");return d}function u(a){for(var b;b=a.parentNode;)a=b;return a}function v(a,c,d,f){var h,i,k,l,m;if(a==d)return c===f?0:f>c?-1:1;if(h=j(d,a,!0))return c<=e(h)?-1:1;if(h=j(a,d,!0))return e(h)[index:"+e(a)+",length:"+a.childNodes.length+"]["+(a.innerHTML||"[innerHTML not supported]").slice(0,25)+"]"}return a.nodeName}function y(a){for(var b,c=o(a).createDocumentFragment();b=a.firstChild;)c.appendChild(b);return c}function z(a,b,c){var d=H(a),e=a.createElement("div");e.contentEditable=""+!!c,b&&(e.innerHTML=b);var f=d.firstChild;return f?d.insertBefore(e,f):d.appendChild(e),e}function A(a){return a.parentNode.removeChild(a)}function B(a){this.root=a,this._next=a}function C(a){return new B(a)}function D(a,b){this.node=a,this.offset=b}function E(a){this.code=this[a],this.codeName=a,this.message="DOMException: "+this.codeName}var F="undefined",G=a.util,H=G.getBody;G.areHostMethods(document,["createDocumentFragment","createElement","createTextNode"])||b.fail("document missing a Node creation method"),G.isHostMethod(document,"getElementsByTagName")||b.fail("document missing getElementsByTagName method");var I=document.createElement("div");G.areHostMethods(I,["insertBefore","appendChild","cloneNode"]||!G.areHostObjects(I,["previousSibling","nextSibling","childNodes","parentNode"]))||b.fail("Incomplete Element implementation"),G.isHostProperty(I,"innerHTML")||b.fail("Element is missing innerHTML property");var J=document.createTextNode("test");G.areHostMethods(J,["splitText","deleteData","insertData","appendData","cloneNode"]||!G.areHostObjects(I,["previousSibling","nextSibling","childNodes","parentNode"])||!G.areHostProperties(J,["data"]))||b.fail("Incomplete Text Node implementation");var K=function(a,b){for(var c=a.length;c--;)if(a[c]===b)return!0;return!1},L=!1;!function(){var b=document.createElement("b");b.innerHTML="1";var c=b.firstChild;b.innerHTML=" ",L=w(c),a.features.crashyTextNodes=L}();var M;typeof window.getComputedStyle!=F?M=function(a,b){return p(a).getComputedStyle(a,null)[b]}:typeof document.documentElement.currentStyle!=F?M=function(a,b){return a.currentStyle?a.currentStyle[b]:""}:b.fail("No means of obtaining computed style properties found"),B.prototype={_current:null,hasNext:function(){return!!this._next},next:function(){var a,b,c=this._current=this._next;if(this._current)if(a=c.firstChild)this._next=a;else{for(b=null;c!==this.root&&!(b=c.nextSibling);)c=c.parentNode;this._next=b}return this._current},detach:function(){this._current=this._next=this.root=null}},D.prototype={equals:function(a){return!!a&&this.node===a.node&&this.offset==a.offset},inspect:function(){return"[DomPosition("+x(this.node)+":"+this.offset+")]"},toString:function(){return this.inspect()}},E.prototype={INDEX_SIZE_ERR:1,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INVALID_STATE_ERR:11,INVALID_NODE_TYPE_ERR:24},E.prototype.toString=function(){return this.message},a.dom={arrayContains:K,isHtmlNamespace:c,parentElement:d,getNodeIndex:e,getNodeLength:f,getCommonAncestor:g,isAncestorOf:h,isOrIsAncestorOf:i,getClosestAncestorIn:j,isCharacterDataNode:k,isTextOrCommentNode:l,insertAfter:m,splitDataNode:n,getDocument:o,getWindow:p,getIframeWindow:r,getIframeDocument:q,getBody:H,isWindow:s,getContentDocument:t,getRootContainer:u,comparePoints:v,isBrokenNode:w,inspectNode:x,getComputedStyleProperty:M,createTestElement:z,removeNode:A,fragmentFromNodeChildren:y,createIterator:C,DomPosition:D},a.DOMException=E}),H.createCoreModule("DomRange",["DomUtil"],function(a,b){function c(a,b){return 3!=a.nodeType&&(P(a,b.startContainer)||P(a,b.endContainer))}function d(a){return a.document||Q(a.startContainer)}function e(a){return W(a.startContainer)}function f(a){return new L(a.parentNode,O(a))}function g(a){return new L(a.parentNode,O(a)+1)}function h(a,b,c){var d=11==a.nodeType?a.firstChild:a;return N(b)?c==b.length?J.insertAfter(a,b):b.parentNode.insertBefore(a,0==c?b:S(b,c)):c>=b.childNodes.length?b.appendChild(a):b.insertBefore(a,b.childNodes[c]),d}function i(a,b,c){if(z(a),z(b),d(b)!=d(a))throw new M("WRONG_DOCUMENT_ERR");var e=R(a.startContainer,a.startOffset,b.endContainer,b.endOffset),f=R(a.endContainer,a.endOffset,b.startContainer,b.startOffset);return c?0>=e&&f>=0:0>e&&f>0}function j(a){for(var b,c,e,f=d(a.range).createDocumentFragment();c=a.next();){if(b=a.isPartiallySelectedSubtree(),c=c.cloneNode(!b),b&&(e=a.getSubtreeIterator(),c.appendChild(j(e)),e.detach()),10==c.nodeType)throw new M("HIERARCHY_REQUEST_ERR");f.appendChild(c)}return f}function k(a,b,c){var d,e;c=c||{stop:!1};for(var f,g;f=a.next();)if(a.isPartiallySelectedSubtree()){if(b(f)===!1)return void(c.stop=!0);if(g=a.getSubtreeIterator(),k(g,b,c),g.detach(),c.stop)return}else for(d=J.createIterator(f);e=d.next();)if(b(e)===!1)return void(c.stop=!0)}function l(a){for(var b;a.next();)a.isPartiallySelectedSubtree()?(b=a.getSubtreeIterator(),l(b),b.detach()):a.remove()}function m(a){for(var b,c,e=d(a.range).createDocumentFragment();b=a.next();){if(a.isPartiallySelectedSubtree()?(b=b.cloneNode(!1),c=a.getSubtreeIterator(),b.appendChild(m(c)),c.detach()):a.remove(),10==b.nodeType)throw new M("HIERARCHY_REQUEST_ERR");e.appendChild(b)}return e}function n(a,b,c){var d,e=!(!b||!b.length),f=!!c;e&&(d=new RegExp("^("+b.join("|")+")$"));var g=[];return k(new p(a,!1),function(b){if((!e||d.test(b.nodeType))&&(!f||c(b))){var h=a.startContainer;if(b!=h||!N(h)||a.startOffset!=h.length){var i=a.endContainer;b==i&&N(i)&&0==a.endOffset||g.push(b)}}}),g}function o(a){var b="undefined"==typeof a.getName?"Range":a.getName();return"["+b+"("+J.inspectNode(a.startContainer)+":"+a.startOffset+", "+J.inspectNode(a.endContainer)+":"+a.endOffset+")]"}function p(a,b){if(this.range=a,this.clonePartiallySelectedTextNodes=b,!a.collapsed){this.sc=a.startContainer,this.so=a.startOffset,this.ec=a.endContainer,this.eo=a.endOffset;var c=a.commonAncestorContainer;this.sc===this.ec&&N(this.sc)?(this.isSingleCharacterDataNode=!0,this._first=this._last=this._next=this.sc):(this._first=this._next=this.sc!==c||N(this.sc)?T(this.sc,c,!0):this.sc.childNodes[this.so],this._last=this.ec!==c||N(this.ec)?T(this.ec,c,!0):this.ec.childNodes[this.eo-1])}}function q(a){return function(b,c){for(var d,e=c?b:b.parentNode;e;){if(d=e.nodeType,V(a,d))return e;e=e.parentNode}return null}}function r(a,b){if(ea(a,b))throw new M("INVALID_NODE_TYPE_ERR")}function s(a,b){if(!V(b,a.nodeType))throw new M("INVALID_NODE_TYPE_ERR")}function t(a,b){if(0>b||b>(N(a)?a.length:a.childNodes.length))throw new M("INDEX_SIZE_ERR")}function u(a,b){if(ca(a,!0)!==ca(b,!0))throw new M("WRONG_DOCUMENT_ERR")}function v(a){if(da(a,!0))throw new M("NO_MODIFICATION_ALLOWED_ERR")}function w(a,b){if(!a)throw new M(b)}function x(a,b){return b<=(N(a)?a.length:a.childNodes.length)}function y(a){return!!a.startContainer&&!!a.endContainer&&!(X&&(J.isBrokenNode(a.startContainer)||J.isBrokenNode(a.endContainer)))&&W(a.startContainer)==W(a.endContainer)&&x(a.startContainer,a.startOffset)&&x(a.endContainer,a.endOffset)}function z(a){if(!y(a))throw new Error("Range error: Range is not valid. This usually happens after DOM mutation. Range: ("+a.inspect()+")")}function A(a,b){z(a);var c=a.startContainer,d=a.startOffset,e=a.endContainer,f=a.endOffset,g=c===e;N(e)&&f>0&&f0&&d=O(c)&&f++,d=0),a.setStartAndEnd(c,d,e,f)}function B(a){z(a);var b=a.commonAncestorContainer.parentNode.cloneNode(!1);return b.appendChild(a.cloneContents()),b.innerHTML}function C(a){a.START_TO_START=ka,a.START_TO_END=la,a.END_TO_END=ma,a.END_TO_START=na,a.NODE_BEFORE=oa,a.NODE_AFTER=pa,a.NODE_BEFORE_AND_AFTER=qa,a.NODE_INSIDE=ra}function D(a){C(a),C(a.prototype)}function E(a,b){return function(){z(this);var c,d,e=this.startContainer,f=this.startOffset,h=this.commonAncestorContainer,i=new p(this,!0);e!==h&&(c=T(e,h,!0),d=g(c),e=d.node,f=d.offset),k(i,v),i.reset();var j=a(i);return i.detach(),b(this,e,f,e,f),j}}function F(b,d){function e(a,b){return function(c){s(c,Z),s(W(c),$);var d=(a?f:g)(c);(b?h:i)(this,d.node,d.offset)}}function h(a,b,c){var e=a.endContainer,f=a.endOffset;(b!==a.startContainer||c!==a.startOffset)&&((W(b)!=W(e)||1==R(b,c,e,f))&&(e=b,f=c),d(a,b,c,e,f))}function i(a,b,c){var e=a.startContainer,f=a.startOffset;(b!==a.endContainer||c!==a.endOffset)&&((W(b)!=W(e)||-1==R(b,c,e,f))&&(e=b,f=c),d(a,e,f,b,c))}var j=function(){};j.prototype=a.rangePrototype,b.prototype=new j,K.extend(b.prototype,{setStart:function(a,b){r(a,!0),t(a,b),h(this,a,b)},setEnd:function(a,b){r(a,!0),t(a,b),i(this,a,b)},setStartAndEnd:function(){var a=arguments,b=a[0],c=a[1],e=b,f=c;switch(a.length){case 3:f=a[2];break;case 4:e=a[2],f=a[3]}d(this,b,c,e,f)},setBoundary:function(a,b,c){this["set"+(c?"Start":"End")](a,b)},setStartBefore:e(!0,!0),setStartAfter:e(!1,!0),setEndBefore:e(!0,!1),setEndAfter:e(!1,!1),collapse:function(a){z(this),a?d(this,this.startContainer,this.startOffset,this.startContainer,this.startOffset):d(this,this.endContainer,this.endOffset,this.endContainer,this.endOffset)},selectNodeContents:function(a){r(a,!0),d(this,a,0,a,U(a))},selectNode:function(a){r(a,!1),s(a,Z);var b=f(a),c=g(a);d(this,b.node,b.offset,c.node,c.offset)},extractContents:E(m,d),deleteContents:E(l,d),canSurroundContents:function(){z(this),v(this.startContainer),v(this.endContainer);var a=new p(this,!0),b=a._first&&c(a._first,this)||a._last&&c(a._last,this);return a.detach(),!b},splitBoundaries:function(){A(this)},splitBoundariesPreservingPositions:function(a){A(this,a)},normalizeBoundaries:function(){z(this);var a,b=this.startContainer,c=this.startOffset,e=this.endContainer,f=this.endOffset,g=function(a){var b=a.nextSibling;b&&b.nodeType==a.nodeType&&(e=a,f=a.length,a.appendData(b.data),Y(b))},h=function(a){var d=a.previousSibling;if(d&&d.nodeType==a.nodeType){b=a;var g=a.length;if(c=d.length,a.insertData(0,d.data),Y(d),b==e)f+=c,e=b;else if(e==a.parentNode){var h=O(a);f==h?(e=a,f=g):f>h&&f--}}},i=!0;if(N(e))f==e.length?g(e):0==f&&(a=e.previousSibling,a&&a.nodeType==e.nodeType&&(f=a.length,b==e&&(i=!1),a.appendData(e.data),Y(e),e=a));else{if(f>0){var j=e.childNodes[f-1];j&&N(j)&&g(j)}i=!this.collapsed}if(i){if(N(b))0==c?h(b):c==b.length&&(a=b.nextSibling,a&&a.nodeType==b.nodeType&&(e==a&&(e=b,f+=b.length),b.appendData(a.data),Y(a)));else if(cx",ga=3==fa.firstChild.nodeType}catch(ha){}a.features.htmlParsingConforms=ga;var ia=ga?function(a){var b=this.startContainer,c=Q(b);if(!b)throw new M("INVALID_STATE_ERR");var d=null;return 1==b.nodeType?d=b:N(b)&&(d=J.parentElement(b)),d=null===d||"HTML"==d.nodeName&&J.isHtmlNamespace(Q(d).documentElement)&&J.isHtmlNamespace(d)?c.createElement("body"):d.cloneNode(!1),d.innerHTML=a,J.fragmentFromNodeChildren(d)}:function(a){var b=d(this),c=b.createElement("body");return c.innerHTML=a,J.fragmentFromNodeChildren(c)},ja=["startContainer","startOffset","endContainer","endOffset","collapsed","commonAncestorContainer"],ka=0,la=1,ma=2,na=3,oa=0,pa=1,qa=2,ra=3;K.extend(a.rangePrototype,{compareBoundaryPoints:function(a,b){z(this),u(this.startContainer,b.startContainer);var c,d,e,f,g=a==na||a==ka?"start":"end",h=a==la||a==ka?"start":"end";return c=this[g+"Container"],d=this[g+"Offset"],e=b[h+"Container"],f=b[h+"Offset"],R(c,d,e,f)},insertNode:function(a){if(z(this),s(a,aa),v(this.startContainer),P(a,this.startContainer))throw new M("HIERARCHY_REQUEST_ERR");var b=h(a,this.startContainer,this.startOffset);this.setStartBefore(b)},cloneContents:function(){z(this);var a,b;if(this.collapsed)return d(this).createDocumentFragment();if(this.startContainer===this.endContainer&&N(this.startContainer))return a=this.startContainer.cloneNode(!0),a.data=a.data.slice(this.startOffset,this.endOffset),b=d(this).createDocumentFragment(),b.appendChild(a),b;var c=new p(this,!0);return a=j(c),c.detach(),a},canSurroundContents:function(){z(this),v(this.startContainer),v(this.endContainer);var a=new p(this,!0),b=a._first&&c(a._first,this)||a._last&&c(a._last,this);return a.detach(),!b},surroundContents:function(a){if(s(a,ba),!this.canSurroundContents())throw new M("INVALID_STATE_ERR");var b=this.extractContents();if(a.hasChildNodes())for(;a.lastChild;)a.removeChild(a.lastChild);h(a,this.startContainer,this.startOffset),a.appendChild(b),this.selectNode(a)},cloneRange:function(){z(this);for(var a,b=new I(d(this)),c=ja.length;c--;)a=ja[c],b[a]=this[a];return b},toString:function(){z(this);var a=this.startContainer;if(a===this.endContainer&&N(a))return 3==a.nodeType||4==a.nodeType?a.data.slice(this.startOffset,this.endOffset):"";var b=[],c=new p(this,!0);return k(c,function(a){(3==a.nodeType||4==a.nodeType)&&b.push(a.data)}),c.detach(),b.join("")},compareNode:function(a){z(this);var b=a.parentNode,c=O(a);if(!b)throw new M("NOT_FOUND_ERR");var d=this.comparePoint(b,c),e=this.comparePoint(b,c+1);return 0>d?e>0?qa:oa:e>0?pa:ra},comparePoint:function(a,b){return z(this),w(a,"HIERARCHY_REQUEST_ERR"),u(a,this.startContainer),R(a,b,this.startContainer,this.startOffset)<0?-1:R(a,b,this.endContainer,this.endOffset)>0?1:0},createContextualFragment:ia,toHtml:function(){return B(this)},intersectsNode:function(a,b){if(z(this),W(a)!=e(this))return!1;var c=a.parentNode,d=O(a);if(!c)return!0;var f=R(c,d,this.endContainer,this.endOffset),g=R(c,d+1,this.startContainer,this.startOffset);return b?0>=f&&g>=0:0>f&&g>0},isPointInRange:function(a,b){return z(this),w(a,"HIERARCHY_REQUEST_ERR"),u(a,this.startContainer),R(a,b,this.startContainer,this.startOffset)>=0&&R(a,b,this.endContainer,this.endOffset)<=0},intersectsRange:function(a){return i(this,a,!1)},intersectsOrTouchesRange:function(a){return i(this,a,!0)},intersection:function(a){if(this.intersectsRange(a)){var b=R(this.startContainer,this.startOffset,a.startContainer,a.startOffset),c=R(this.endContainer,this.endOffset,a.endContainer,a.endOffset),d=this.cloneRange();return-1==b&&d.setStart(a.startContainer,a.startOffset),1==c&&d.setEnd(a.endContainer,a.endOffset),d}return null},union:function(a){if(this.intersectsOrTouchesRange(a)){var b=this.cloneRange();return-1==R(a.startContainer,a.startOffset,this.startContainer,this.startOffset)&&b.setStart(a.startContainer,a.startOffset),1==R(a.endContainer,a.endOffset,this.endContainer,this.endOffset)&&b.setEnd(a.endContainer,a.endOffset),b}throw new M("Ranges do not intersect")},containsNode:function(a,b){return b?this.intersectsNode(a,!1):this.compareNode(a)==ra},containsNodeContents:function(a){return this.comparePoint(a,0)>=0&&this.comparePoint(a,U(a))<=0},containsRange:function(a){var b=this.intersection(a);return null!==b&&a.equals(b)},containsNodeText:function(a){var b=this.cloneRange();b.selectNode(a);var c=b.getNodes([3]);if(c.length>0){b.setStart(c[0],0);var d=c.pop();return b.setEnd(d,d.length),this.containsRange(b)}return this.containsNodeContents(a)},getNodes:function(a,b){return z(this),n(this,a,b)},getDocument:function(){return d(this)},collapseBefore:function(a){this.setEndBefore(a),this.collapse(!1)},collapseAfter:function(a){this.setStartAfter(a),this.collapse(!0)},getBookmark:function(b){var c=d(this),e=a.createRange(c);b=b||J.getBody(c),e.selectNodeContents(b);var f=this.intersection(e),g=0,h=0;return f&&(e.setEnd(f.startContainer,f.startOffset),g=e.toString().length,h=g+f.toString().length),{start:g,end:h,containerNode:b}},moveToBookmark:function(a){var b=a.containerNode,c=0;this.setStart(b,0),this.collapse(!0);for(var d,e,f,g,h=[b],i=!1,j=!1;!j&&(d=h.pop());)if(3==d.nodeType)e=c+d.length,!i&&a.start>=c&&a.start<=e&&(this.setStart(d,a.start-c),i=!0),i&&a.end>=c&&a.end<=e&&(this.setEnd(d,a.end-c),j=!0),c=e;else for(g=d.childNodes,f=g.length;f--;)h.push(g[f])},getName:function(){return"DomRange"},equals:function(a){return I.rangesEqual(this,a)},isValid:function(){return y(this)},inspect:function(){return o(this)},detach:function(){}}),F(I,H),K.extend(I,{rangeProperties:ja,RangeIterator:p,copyComparisonConstants:D,createPrototypeRange:F,inspect:o,toHtml:B,getRangeDocument:d,rangesEqual:function(a,b){return a.startContainer===b.startContainer&&a.startOffset===b.startOffset&&a.endContainer===b.endContainer&&a.endOffset===b.endOffset}}),a.DomRange=I}),H.createCoreModule("WrappedRange",["DomRange"],function(a,b){var c,d,e=a.dom,f=a.util,g=e.DomPosition,h=a.DomRange,i=e.getBody,j=e.getContentDocument,k=e.isCharacterDataNode;if(a.features.implementsDomRange&&!function(){function d(a){for(var b,c=m.length;c--;)b=m[c],a[b]=a.nativeRange[b];a.collapsed=a.startContainer===a.endContainer&&a.startOffset===a.endOffset}function g(a,b,c,d,e){var f=a.startContainer!==b||a.startOffset!=c,g=a.endContainer!==d||a.endOffset!=e,h=!a.equals(a.nativeRange);(f||g||h)&&(a.setEnd(d,e),a.setStart(b,c))}var k,l,m=h.rangeProperties;c=function(a){if(!a)throw b.createError("WrappedRange: Range must be specified");this.nativeRange=a,d(this)},h.createPrototypeRange(c,g),k=c.prototype,k.selectNode=function(a){this.nativeRange.selectNode(a),d(this)},k.cloneContents=function(){return this.nativeRange.cloneContents()},k.surroundContents=function(a){this.nativeRange.surroundContents(a),d(this)},k.collapse=function(a){this.nativeRange.collapse(a),d(this)},k.cloneRange=function(){return new c(this.nativeRange.cloneRange())},k.refresh=function(){d(this)},k.toString=function(){return this.nativeRange.toString()};var n=document.createTextNode("test");i(document).appendChild(n);var o=document.createRange();o.setStart(n,0),o.setEnd(n,0);try{o.setStart(n,1),k.setStart=function(a,b){this.nativeRange.setStart(a,b),d(this)},k.setEnd=function(a,b){this.nativeRange.setEnd(a,b),d(this)},l=function(a){return function(b){this.nativeRange[a](b),d(this)}}}catch(p){k.setStart=function(a,b){try{this.nativeRange.setStart(a,b)}catch(c){this.nativeRange.setEnd(a,b),this.nativeRange.setStart(a,b)}d(this)},k.setEnd=function(a,b){try{this.nativeRange.setEnd(a,b)}catch(c){this.nativeRange.setStart(a,b),this.nativeRange.setEnd(a,b)}d(this)},l=function(a,b){return function(c){try{this.nativeRange[a](c)}catch(e){this.nativeRange[b](c),this.nativeRange[a](c)}d(this)}}}k.setStartBefore=l("setStartBefore","setEndBefore"),k.setStartAfter=l("setStartAfter","setEndAfter"),k.setEndBefore=l("setEndBefore","setStartBefore"),k.setEndAfter=l("setEndAfter","setStartAfter"),k.selectNodeContents=function(a){this.setStartAndEnd(a,0,e.getNodeLength(a))},o.selectNodeContents(n),o.setEnd(n,3);var q=document.createRange();q.selectNodeContents(n),q.setEnd(n,4),q.setStart(n,2),-1==o.compareBoundaryPoints(o.START_TO_END,q)&&1==o.compareBoundaryPoints(o.END_TO_START,q)?k.compareBoundaryPoints=function(a,b){return b=b.nativeRange||b,a==b.START_TO_END?a=b.END_TO_START:a==b.END_TO_START&&(a=b.START_TO_END),this.nativeRange.compareBoundaryPoints(a,b)}:k.compareBoundaryPoints=function(a,b){return this.nativeRange.compareBoundaryPoints(a,b.nativeRange||b)};var r=document.createElement("div");r.innerHTML="123";var s=r.firstChild,t=i(document);t.appendChild(r),o.setStart(s,1),o.setEnd(s,2),o.deleteContents(),"13"==s.data&&(k.deleteContents=function(){this.nativeRange.deleteContents(),d(this)},k.extractContents=function(){var a=this.nativeRange.extractContents();return d(this),a}),t.removeChild(r),t=null,f.isHostMethod(o,"createContextualFragment")&&(k.createContextualFragment=function(a){return this.nativeRange.createContextualFragment(a)}),i(document).removeChild(n),k.getName=function(){return"WrappedRange"},a.WrappedRange=c,a.createNativeRange=function(a){return a=j(a,b,"createNativeRange"),a.createRange()}}(),a.features.implementsTextRange){var l=function(a){var b=a.parentElement(),c=a.duplicate();c.collapse(!0);var d=c.parentElement();c=a.duplicate(),c.collapse(!1);var f=c.parentElement(),g=d==f?d:e.getCommonAncestor(d,f);return g==b?g:e.getCommonAncestor(b,g)},m=function(a){return 0==a.compareEndPoints("StartToEnd",a)},n=function(a,b,c,d,f){var h=a.duplicate();h.collapse(c);var i=h.parentElement();if(e.isOrIsAncestorOf(b,i)||(i=b),!i.canHaveHTML){var j=new g(i.parentNode,e.getNodeIndex(i));return{boundaryPosition:j,nodeInfo:{nodeIndex:j.offset,containerElement:j.node}}}var l=e.getDocument(i).createElement("span");l.parentNode&&e.removeNode(l);for(var m,n,o,p,q,r=c?"StartToStart":"StartToEnd",s=f&&f.containerElement==i?f.nodeIndex:0,t=i.childNodes.length,u=t,v=u;;){if(v==t?i.appendChild(l):i.insertBefore(l,i.childNodes[v]),h.moveToElementText(l),m=h.compareEndPoints(r,a),0==m||s==u)break;if(-1==m){if(u==s+1)break;s=v}else u=u==s+1?s:v;v=Math.floor((s+u)/2),i.removeChild(l)}if(q=l.nextSibling,-1==m&&q&&k(q)){h.setEndPoint(c?"EndToStart":"EndToEnd",a);var w;if(/[\r\n]/.test(q.data)){var x=h.duplicate(),y=x.text.replace(/\r\n/g,"\r").length;for(w=x.moveStart("character",y);-1==(m=x.compareEndPoints("StartToEnd",x));)w++,x.moveStart("character",1)}else w=h.text.length;p=new g(q,w)}else n=(d||!c)&&l.previousSibling,o=(d||c)&&l.nextSibling,p=o&&k(o)?new g(o,0):n&&k(n)?new g(n,n.data.length):new g(i,e.getNodeIndex(l));return e.removeNode(l),{boundaryPosition:p,nodeInfo:{nodeIndex:v,containerElement:i}}},o=function(a,b){var c,d,f,g,h=a.offset,j=e.getDocument(a.node),l=i(j).createTextRange(),m=k(a.node);return m?(c=a.node,d=c.parentNode):(g=a.node.childNodes,c=hb;++b)if(!C.isAncestorOf(a[0],a[b]))return!1;return!0}function m(a){var c=a.getNodes();if(!l(c))throw b.createError("getSingleElementFromRange: range "+a.inspect()+" did not consist of a single element");return c[0]}function n(a){return!!a&&"undefined"!=typeof a.text}function o(a,b){var c=new G(b);a._ranges=[c],h(a,c,!1),a.rangeCount=1,a.isCollapsed=c.collapsed}function p(b){if(b._ranges.length=0,"None"==b.docSelection.type)j(b);else{var c=b.docSelection.createRange();if(n(c))o(b,c);else{b.rangeCount=c.length;for(var d,e=L(c.item(0)),f=0;fh;++h)g.add(d.item(h));try{g.add(e)}catch(j){throw b.createError("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)")}g.select(),p(a)}function r(a,b,c){this.nativeSelection=a,this.docSelection=b,this._ranges=[],this.win=c,this.refresh()}function s(a){a.win=a.anchorNode=a.focusNode=a._ranges=null,a.rangeCount=a.anchorOffset=a.focusOffset=0,a.detached=!0}function t(a,b){for(var c,d,e=ba.length;e--;)if(c=ba[e],d=c.selection,"deleteAll"==b)s(d);else if(c.win==a)return"delete"==b?(ba.splice(e,1),!0):d;return"deleteAll"==b&&(ba.length=0),null}function u(a,c){for(var d,e=L(c[0].startContainer),f=M(e).createControlRange(),g=0,h=c.length;h>g;++g){d=m(c[g]);try{f.add(d)}catch(i){throw b.createError("setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)")}}f.select(),p(a)}function v(a,b){if(a.win.document!=L(b))throw new H("WRONG_DOCUMENT_ERR")}function w(b){return function(c,d){var e;this.rangeCount?(e=this.getRangeAt(0),e["set"+(b?"Start":"End")](c,d)):(e=a.createRange(this.win.document),e.setStartAndEnd(c,d)),this.setSingleRange(e,this.isBackward())}}function x(a){var b=[],c=new I(a.anchorNode,a.anchorOffset),d=new I(a.focusNode,a.focusOffset),e="function"==typeof a.getName?a.getName():"Selection";if("undefined"!=typeof a.rangeCount)for(var f=0,g=a.rangeCount;g>f;++f)b[f]=F.inspect(a.getRangeAt(f));return"["+e+"(Ranges: "+b.join(", ")+")(anchor: "+c.inspect()+", focus: "+d.inspect()+"]"}a.config.checkSelectionRanges=!0;var y,z,A="boolean",B="number",C=a.dom,D=a.util,E=D.isHostMethod,F=a.DomRange,G=a.WrappedRange,H=a.DOMException,I=C.DomPosition,J=a.features,K="Control",L=C.getDocument,M=C.getBody,N=F.rangesEqual,O=E(window,"getSelection"),P=D.isHostObject(document,"selection");J.implementsWinGetSelection=O,J.implementsDocSelection=P;var Q=P&&(!O||a.config.preferTextRange);if(Q)y=f,a.isSelectionValid=function(a){var b=d(a,"isSelectionValid").document,c=b.selection;return"None"!=c.type||L(c.createRange().parentElement())==b};else{if(!O)return b.fail("Neither document.selection or window.getSelection() detected."),!1;y=e,a.isSelectionValid=function(){return!0}}a.getNativeSelection=y;var R=y();if(!R)return b.fail("Native selection was null (possibly issue 138?)"),!1;var S=a.createNativeRange(document),T=M(document),U=D.areHostProperties(R,["anchorNode","focusNode","anchorOffset","focusOffset"]);J.selectionHasAnchorAndFocus=U;var V=E(R,"extend");J.selectionHasExtend=V;var W=typeof R.rangeCount==B;J.selectionHasRangeCount=W;var X=!1,Y=!0,Z=V?function(b,c){var d=F.getRangeDocument(c),e=a.createRange(d);e.collapseToPoint(c.endContainer,c.endOffset),b.addRange(k(e)),b.extend(c.startContainer,c.startOffset)}:null;D.areHostMethods(R,["addRange","getRangeAt","removeAllRanges"])&&typeof R.rangeCount==B&&J.implementsDomRange&&!function(){var b=window.getSelection();if(b){for(var c=b.rangeCount,d=c>1,e=[],f=g(b),h=0;c>h;++h)e[h]=b.getRangeAt(h);var i=C.createTestElement(document,"",!1),j=i.appendChild(document.createTextNode(" ")),k=document.createRange();if(k.setStart(j,1),k.collapse(!0),b.removeAllRanges(),b.addRange(k),Y=1==b.rangeCount,b.removeAllRanges(),!d){var l=window.navigator.appVersion.match(/Chrome\/(.*?) /);if(l&&parseInt(l[1])>=36)X=!1;else{var m=k.cloneRange();k.setStart(j,0),m.setEnd(j,3),m.setStart(j,2),b.addRange(k),b.addRange(m),X=2==b.rangeCount}}for(C.removeNode(i),b.removeAllRanges(),h=0;c>h;++h)0==h&&f?Z?Z(b,e[h]):(a.warn("Rangy initialization: original selection was backwards but selection has been restored forwards because the browser does not support Selection.extend"),b.addRange(e[h])):b.addRange(e[h])}}(),J.selectionSupportsMultipleRanges=X,J.collapsedNonEditableSelectionsSupported=Y;var $,_=!1;T&&E(T,"createControlRange")&&($=T.createControlRange(),D.areHostProperties($,["item","add"])&&(_=!0)),J.implementsControlRange=_,z=U?function(a){return a.anchorNode===a.focusNode&&a.anchorOffset===a.focusOffset}:function(a){return a.rangeCount?a.getRangeAt(a.rangeCount-1).collapsed:!1};var aa;E(R,"getRangeAt")?aa=function(a,b){try{return a.getRangeAt(b)}catch(c){return null}}:U&&(aa=function(b){var c=L(b.anchorNode),d=a.createRange(c);return d.setStartAndEnd(b.anchorNode,b.anchorOffset,b.focusNode,b.focusOffset),d.collapsed!==this.isCollapsed&&d.setStartAndEnd(b.focusNode,b.focusOffset,b.anchorNode,b.anchorOffset),d}),r.prototype=a.selectionPrototype;var ba=[],ca=function(a){if(a&&a instanceof r)return a.refresh(),a;a=d(a,"getNativeSelection");var b=t(a),c=y(a),e=P?f(a):null;return b?(b.nativeSelection=c,b.docSelection=e,b.refresh()):(b=new r(c,e,a),ba.push({win:a,selection:b})),b};a.getSelection=ca,D.createAliasForDeprecatedMethod(a,"getIframeSelection","getSelection");var da=r.prototype;if(!Q&&U&&D.areHostMethods(R,["removeAllRanges","addRange"])){da.removeAllRanges=function(){this.nativeSelection.removeAllRanges(),j(this)};var ea=function(a,b){Z(a.nativeSelection,b),a.refresh()};W?da.addRange=function(b,d){if(_&&P&&this.docSelection.type==K)q(this,b);else if(c(d)&&V)ea(this,b);else{var e;X?e=this.rangeCount:(this.removeAllRanges(),e=0);var f=k(b).cloneRange();try{this.nativeSelection.addRange(f)}catch(g){}if(this.rangeCount=this.nativeSelection.rangeCount,this.rangeCount==e+1){if(a.config.checkSelectionRanges){var i=aa(this.nativeSelection,this.rangeCount-1);i&&!N(i,b)&&(b=new G(i))}this._ranges[this.rangeCount-1]=b,h(this,b,ha(this.nativeSelection)),this.isCollapsed=z(this)}else this.refresh()}}:da.addRange=function(a,b){c(b)&&V?ea(this,a):(this.nativeSelection.addRange(k(a)),this.refresh())},da.setRanges=function(a){if(_&&P&&a.length>1)u(this,a);else{this.removeAllRanges();for(var b=0,c=a.length;c>b;++b)this.addRange(a[b])}}}else{if(!(E(R,"empty")&&E(S,"select")&&_&&Q))return b.fail("No means of selecting a Range or TextRange was found"),!1;da.removeAllRanges=function(){try{if(this.docSelection.empty(),"None"!=this.docSelection.type){var a;if(this.anchorNode)a=L(this.anchorNode);else if(this.docSelection.type==K){var b=this.docSelection.createRange();b.length&&(a=L(b.item(0)))}if(a){var c=M(a).createTextRange();c.select(),this.docSelection.empty()}}}catch(d){}j(this)},da.addRange=function(b){this.docSelection.type==K?q(this,b):(a.WrappedTextRange.rangeToTextRange(b).select(),this._ranges[0]=b,this.rangeCount=1,this.isCollapsed=this._ranges[0].collapsed,h(this,b,!1))},da.setRanges=function(a){this.removeAllRanges();var b=a.length;b>1?u(this,a):b&&this.addRange(a[0])}}da.getRangeAt=function(a){if(0>a||a>=this.rangeCount)throw new H("INDEX_SIZE_ERR");return this._ranges[a].cloneRange()};var fa;if(Q)fa=function(b){var c;a.isSelectionValid(b.win)?c=b.docSelection.createRange():(c=M(b.win.document).createTextRange(),c.collapse(!0)),b.docSelection.type==K?p(b):n(c)?o(b,c):j(b)};else if(E(R,"getRangeAt")&&typeof R.rangeCount==B)fa=function(b){if(_&&P&&b.docSelection.type==K)p(b);else if(b._ranges.length=b.rangeCount=b.nativeSelection.rangeCount,b.rangeCount){for(var c=0,d=b.rangeCount;d>c;++c)b._ranges[c]=new a.WrappedRange(b.nativeSelection.getRangeAt(c));h(b,b._ranges[b.rangeCount-1],ha(b.nativeSelection)),b.isCollapsed=z(b)}else j(b)};else{if(!U||typeof R.isCollapsed!=A||typeof S.collapsed!=A||!J.implementsDomRange)return b.fail("No means of obtaining a Range or TextRange from the user's selection was found"),!1;fa=function(a){var b,c=a.nativeSelection;c.anchorNode?(b=aa(c,0),a._ranges=[b],a.rangeCount=1,i(a),a.isCollapsed=z(a)):j(a)}}da.refresh=function(a){var b=a?this._ranges.slice(0):null,c=this.anchorNode,d=this.anchorOffset;if(fa(this),a){var e=b.length;if(e!=this._ranges.length)return!0;if(this.anchorNode!=c||this.anchorOffset!=d)return!0;for(;e--;)if(!N(b[e],this._ranges[e]))return!0;return!1}};var ga=function(a,b){var c=a.getAllRanges();a.removeAllRanges();for(var d=0,e=c.length;e>d;++d)N(b,c[d])||a.addRange(c[d]);a.rangeCount||j(a)};_&&P?da.removeRange=function(a){if(this.docSelection.type==K){for(var b,c=this.docSelection.createRange(),d=m(a),e=L(c.item(0)),f=M(e).createControlRange(),g=!1,h=0,i=c.length;i>h;++h)b=c.item(h),b!==d||g?f.add(c.item(h)):g=!0;f.select(),p(this)}else ga(this,a)}:da.removeRange=function(a){ga(this,a)};var ha;!Q&&U&&J.implementsDomRange?(ha=g,da.isBackward=function(){return ha(this)}):ha=da.isBackward=function(){return!1},da.isBackwards=da.isBackward,da.toString=function(){for(var a=[],b=0,c=this.rangeCount;c>b;++b)a[b]=""+this._ranges[b];return a.join("")},da.collapse=function(b,c){v(this,b);var d=a.createRange(b);d.collapseToPoint(b,c),this.setSingleRange(d),this.isCollapsed=!0},da.collapseToStart=function(){if(!this.rangeCount)throw new H("INVALID_STATE_ERR");var a=this._ranges[0];this.collapse(a.startContainer,a.startOffset)},da.collapseToEnd=function(){if(!this.rangeCount)throw new H("INVALID_STATE_ERR");var a=this._ranges[this.rangeCount-1];this.collapse(a.endContainer,a.endOffset)},da.selectAllChildren=function(b){v(this,b);var c=a.createRange(b);c.selectNodeContents(b),this.setSingleRange(c)},da.deleteFromDocument=function(){if(_&&P&&this.docSelection.type==K){for(var a,b=this.docSelection.createRange();b.length;)a=b.item(0),b.remove(a),C.removeNode(a);this.refresh()}else if(this.rangeCount){var c=this.getAllRanges();if(c.length){this.removeAllRanges();for(var d=0,e=c.length;e>d;++d)c[d].deleteContents();this.addRange(c[e-1])}}},da.eachRange=function(a,b){for(var c=0,d=this._ranges.length;d>c;++c)if(a(this.getRangeAt(c)))return b},da.getAllRanges=function(){var a=[];return this.eachRange(function(b){a.push(b)}),a},da.setSingleRange=function(a,b){this.removeAllRanges(),this.addRange(a,b)},da.callMethodOnEachRange=function(a,b){var c=[];return this.eachRange(function(d){c.push(d[a].apply(d,b||[]))}),c},da.setStart=w(!0),da.setEnd=w(!1),a.rangePrototype.select=function(a){ca(this.getDocument()).setSingleRange(this,a)},da.changeEachRange=function(a){var b=[],c=this.isBackward();this.eachRange(function(c){a(c),b.push(c)}),this.removeAllRanges(),c&&1==b.length?this.addRange(b[0],"backward"):this.setRanges(b)},da.containsNode=function(a,b){return this.eachRange(function(c){return c.containsNode(a,b)},!0)||!1},da.getBookmark=function(a){return{backward:this.isBackward(),rangeBookmarks:this.callMethodOnEachRange("getBookmark",[a])}},da.moveToBookmark=function(b){for(var c,d,e=[],f=0;c=b.rangeBookmarks[f++];)d=a.createRange(this.win),d.moveToBookmark(c),e.push(d);b.backward?this.setSingleRange(e[0],"backward"):this.setRanges(e)},da.saveRanges=function(){return{backward:this.isBackward(),ranges:this.callMethodOnEachRange("cloneRange")}},da.restoreRanges=function(a){this.removeAllRanges();for(var b,c=0;b=a.ranges[c];++c)this.addRange(b,a.backward&&0==c)},da.toHtml=function(){var a=[];return this.eachRange(function(b){a.push(F.toHtml(b))}),a.join("")},J.implementsTextRange&&(da.getNativeTextRange=function(){var c;if(c=this.docSelection){var d=c.createRange();if(n(d))return d;throw b.createError("getNativeTextRange: selection is a control selection")}if(this.rangeCount>0)return a.WrappedTextRange.rangeToTextRange(this.getRangeAt(0));throw b.createError("getNativeTextRange: selection contains no range")}),da.getName=function(){return"WrappedSelection"},da.inspect=function(){return x(this)},da.detach=function(){t(this.win,"delete"),s(this)},r.detachAll=function(){t(null,"deleteAll")},r.inspect=x,r.isDirectionBackward=c,a.Selection=r,a.selectionPrototype=da,a.addShimListener(function(a){"undefined"==typeof a.getSelection&&(a.getSelection=function(){return ca(a)}),a=null})});var M=!1,N=function(a){M||(M=!0,!H.initialized&&H.config.autoInitialize&&l())};return F&&("complete"==document.readyState?N():(a(document,"addEventListener")&&document.addEventListener("DOMContentLoaded",N,!1),J(window,"load",N))),H},this),function(a,b){"function"==typeof define&&define.amd?define(["./rangy-core"],a):"undefined"!=typeof module&&"object"==typeof exports?module.exports=a(require("rangy")):a(b.rangy)}(function(a){return a.createModule("SaveRestore",["WrappedRange"],function(a,b){function c(a,b){return(b||document).getElementById(a)}function d(a,b){var c,d="selectionBoundary_"+ +new Date+"_"+(""+Math.random()).slice(2),e=o.getDocument(a.startContainer),f=a.cloneRange();return f.collapse(b),c=e.createElement("span"),c.id=d,c.style.lineHeight="0",c.style.display="none",c.className="rangySelectionBoundary",c.appendChild(e.createTextNode(r)),f.insertNode(c),c}function e(a,d,e,f){var g=c(e,a);g?(d[f?"setStartBefore":"setEndBefore"](g),p(g)):b.warn("Marker element has been removed. Cannot restore selection.")}function f(a,b){return b.compareBoundaryPoints(a.START_TO_START,a)}function g(b,c){var e,f,g=a.DomRange.getRangeDocument(b),h=b.toString(),i=q(c);return b.collapsed?(f=d(b,!1),{document:g,markerId:f.id,collapsed:!0}):(f=d(b,!1),e=d(b,!0),{document:g,startMarkerId:e.id,endMarkerId:f.id,collapsed:!1,backward:i,toString:function(){return"original text: '"+h+"', new text: '"+b.toString()+"'"}})}function h(d,f){var g=d.document;"undefined"==typeof f&&(f=!0);var h=a.createRange(g);if(d.collapsed){var i=c(d.markerId,g);if(i){i.style.display="inline";var j=i.previousSibling;j&&3==j.nodeType?(p(i),h.collapseToPoint(j,j.length)):(h.collapseBefore(i),p(i))}else b.warn("Marker element has been removed. Cannot restore selection.")}else e(g,h,d.startMarkerId,!0),e(g,h,d.endMarkerId,!1);return f&&h.normalizeBoundaries(),h}function i(b,d){var e,h,i=[],j=q(d);b=b.slice(0),b.sort(f);for(var k=0,l=b.length;l>k;++k)i[k]=g(b[k],j);for(k=l-1;k>=0;--k)e=b[k],h=a.DomRange.getRangeDocument(e),e.collapsed?e.collapseAfter(c(i[k].markerId,h)):(e.setEndBefore(c(i[k].endMarkerId,h)),e.setStartAfter(c(i[k].startMarkerId,h)));return i}function j(c){if(!a.isSelectionValid(c))return b.warn("Cannot save selection. This usually happens when the selection is collapsed and the selection document has lost focus."),null;var d=a.getSelection(c),e=d.getAllRanges(),f=1==e.length&&d.isBackward(),g=i(e,f);return f?d.setSingleRange(e[0],f):d.setRanges(e),{win:c,rangeInfos:g,restored:!1}}function k(a){for(var b=[],c=a.length,d=c-1;d>=0;d--)b[d]=h(a[d],!0);return b}function l(b,c){if(!b.restored){var d=b.rangeInfos,e=a.getSelection(b.win),f=k(d),g=d.length;1==g&&c&&a.features.selectionHasExtend&&d[0].backward?(e.removeAllRanges(),e.addRange(f[0],!0)):e.setRanges(f),b.restored=!0}}function m(a,b){var d=c(b,a);d&&p(d)}function n(a){for(var b,c=a.rangeInfos,d=0,e=c.length;e>d;++d)b=c[d],b.collapsed?m(a.doc,b.markerId):(m(a.doc,b.startMarkerId),m(a.doc,b.endMarkerId))}var o=a.dom,p=o.removeNode,q=a.Selection.isDirectionBackward,r="\ufeff";a.util.extend(a,{saveRange:g,restoreRange:h,saveRanges:i,restoreRanges:k,saveSelection:j,restoreSelection:l,removeMarkerElement:m,removeMarkers:n})}),a},this);
\ No newline at end of file
diff --git a/static/js/textAngular-sanitize.js b/static/js/textAngular-sanitize.js
new file mode 100644
index 0000000..6091eca
--- /dev/null
+++ b/static/js/textAngular-sanitize.js
@@ -0,0 +1,791 @@
+/**
+ * @license AngularJS v1.3.10
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+var $sanitizeMinErr = angular.$$minErr('$sanitize');
+
+/**
+ * @ngdoc module
+ * @name ngSanitize
+ * @description
+ *
+ * # ngSanitize
+ *
+ * The `ngSanitize` module provides functionality to sanitize HTML.
+ *
+ *
+ *
+ *
+ * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
+ */
+
+/*
+ * HTML Parser By Misko Hevery (misko@hevery.com)
+ * based on: HTML Parser By John Resig (ejohn.org)
+ * Original code by Erik Arvidsson, Mozilla Public License
+ * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
+ *
+ * // Use like so:
+ * htmlParser(htmlString, {
+ * start: function(tag, attrs, unary) {},
+ * end: function(tag) {},
+ * chars: function(text) {},
+ * comment: function(text) {}
+ * });
+ *
+ */
+
+
+/**
+ * @ngdoc service
+ * @name $sanitize
+ * @kind function
+ *
+ * @description
+ * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are
+ * then serialized back to properly escaped html string. This means that no unsafe input can make
+ * it into the returned string, however, since our parser is more strict than a typical browser
+ * parser, it's possible that some obscure input, which would be recognized as valid HTML by a
+ * browser, won't make it through the sanitizer. The input may also contain SVG markup.
+ * The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
+ * `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
+ *
+ * @param {string} html HTML input.
+ * @returns {string} Sanitized HTML.
+ *
+ * @example
+
+
+
+
+ Snippet:
+
+
+ Directive
+ How
+ Source
+ Rendered
+
+
+ ng-bind-html
+ Automatically uses $sanitize
+ <div ng-bind-html="snippet"> </div>
+
+
+
+ ng-bind-html
+ Bypass $sanitize by explicitly trusting the dangerous value
+
+ <div ng-bind-html="deliberatelyTrustDangerousSnippet()">
+</div>
+
+
+
+
+ ng-bind
+ Automatically escapes
+ <div ng-bind="snippet"> </div>
+
+
+
+
+
+
+ it('should sanitize the html snippet by default', function() {
+ expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
+ toBe('an html\nclick here \nsnippet
');
+ });
+
+ it('should inline raw snippet if bound to a trusted value', function() {
+ expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
+ toBe("an html\n" +
+ "click here \n" +
+ "snippet
");
+ });
+
+ it('should escape snippet without any filter', function() {
+ expect(element(by.css('#bind-default div')).getInnerHtml()).
+ toBe("<p style=\"color:blue\">an html\n" +
+ "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
+ "snippet</p>");
+ });
+
+ it('should update', function() {
+ element(by.model('snippet')).clear();
+ element(by.model('snippet')).sendKeys('new text ');
+ expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
+ toBe('new text ');
+ expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
+ 'new text ');
+ expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
+ "new <b onclick=\"alert(1)\">text</b>");
+ });
+
+
+ */
+function $SanitizeProvider() {
+ this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
+ return function(html) {
+ if (typeof arguments[1] != 'undefined') {
+ arguments[1].version = 'taSanitize';
+ }
+ var buf = [];
+ htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
+ return !/^unsafe/.test($$sanitizeUri(uri, isImage));
+ }));
+ return buf.join('');
+ };
+ }];
+}
+
+function sanitizeText(chars) {
+ var buf = [];
+ var writer = htmlSanitizeWriter(buf, angular.noop);
+ writer.chars(chars);
+ return buf.join('');
+}
+
+
+// Regular Expressions for parsing tags and attributes
+var START_TAG_REGEXP =
+ /^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,
+ END_TAG_REGEXP = /^<\/\s*([\w:-]+)[^>]*>/,
+ ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
+ BEGIN_TAG_REGEXP = /^,
+ BEGING_END_TAGE_REGEXP = /^<\//,
+ COMMENT_REGEXP = //g,
+ SINGLE_COMMENT_REGEXP = /(^)/,
+ DOCTYPE_REGEXP = /]*?)>/i,
+ CDATA_REGEXP = //g,
+ SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
+ // Match everything outside of normal chars and " (quote character)
+ NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g,
+ WHITE_SPACE_REGEXP = /^(\s+)/;
+
+
+// Good source of info about elements and attributes
+// http://dev.w3.org/html5/spec/Overview.html#semantics
+// http://simon.html5.org/html-elements
+
+// Safe Void Elements - HTML5
+// http://dev.w3.org/html5/spec/Overview.html#void-elements
+var voidElements = makeMap("area,br,col,hr,img,wbr,input");
+
+// Elements that you can, intentionally, leave open (and which close themselves)
+// http://dev.w3.org/html5/spec/Overview.html#optional-tags
+var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
+ optionalEndTagInlineElements = makeMap("rp,rt"),
+ optionalEndTagElements = angular.extend({},
+ optionalEndTagInlineElements,
+ optionalEndTagBlockElements);
+
+// Safe Block Elements - HTML5
+var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
+ "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
+ "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
+
+// Inline Elements - HTML5
+var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
+ "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
+ "samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
+
+// SVG Elements
+// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
+var svgElements = makeMap("animate,animateColor,animateMotion,animateTransform,circle,defs," +
+ "desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient," +
+ "line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,set," +
+ "stop,svg,switch,text,title,tspan,use");
+
+// Special Elements (can contain anything)
+var specialElements = makeMap("script,style");
+
+var validElements = angular.extend({},
+ voidElements,
+ blockElements,
+ inlineElements,
+ optionalEndTagElements,
+ svgElements);
+
+//Attributes that have href and hence need to be sanitized
+var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap,xlink:href");
+
+var htmlAttrs = makeMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
+ 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
+ 'id,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
+ 'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
+ 'valign,value,vspace,width');
+
+// SVG attributes (without "id" and "name" attributes)
+// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
+var svgAttrs = makeMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
+ 'attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,' +
+ 'color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,' +
+ 'font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,' +
+ 'gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,' +
+ 'keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,' +
+ 'markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,' +
+ 'overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,' +
+ 'repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,' +
+ 'stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,' +
+ 'stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,' +
+ 'stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,' +
+ 'underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,' +
+ 'viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,' +
+ 'xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,' +
+ 'zoomAndPan');
+
+var validAttrs = angular.extend({},
+ uriAttrs,
+ svgAttrs,
+ htmlAttrs);
+
+function makeMap(str) {
+ var obj = {}, items = str.split(','), i;
+ for (i = 0; i < items.length; i++) obj[items[i]] = true;
+ return obj;
+}
+
+
+/**
+ * @example
+ * htmlParser(htmlString, {
+ * start: function(tag, attrs, unary) {},
+ * end: function(tag) {},
+ * chars: function(text) {},
+ * comment: function(text) {}
+ * });
+ *
+ * @param {string} html string
+ * @param {object} handler
+ */
+function htmlParser(html, handler) {
+ if (typeof html !== 'string') {
+ if (html === null || typeof html === 'undefined') {
+ html = '';
+ } else {
+ html = '' + html;
+ }
+ }
+ var index, chars, match, stack = [], last = html, text;
+ stack.last = function() { return stack[ stack.length - 1 ]; };
+
+ while (html) {
+ text = '';
+ chars = true;
+
+ // Make sure we're not in a script or style element
+ if (!stack.last() || !specialElements[ stack.last() ]) {
+
+ // White space
+ if (WHITE_SPACE_REGEXP.test(html)) {
+ match = html.match(WHITE_SPACE_REGEXP);
+
+ if (match) {
+ var mat = match[0];
+ if (handler.whitespace) handler.whitespace(match[0]);
+ html = html.replace(match[0], '');
+ chars = false;
+ }
+ //Comment
+ } else if (SINGLE_COMMENT_REGEXP.test(html)) {
+ match = html.match(SINGLE_COMMENT_REGEXP);
+
+ if (match) {
+ if (handler.comment) handler.comment(match[1]);
+ html = html.replace(match[0], '');
+ chars = false;
+ }
+ // DOCTYPE
+ } else if (DOCTYPE_REGEXP.test(html)) {
+ match = html.match(DOCTYPE_REGEXP);
+
+ if (match) {
+ html = html.replace(match[0], '');
+ chars = false;
+ }
+ // end tag
+ } else if (BEGING_END_TAGE_REGEXP.test(html)) {
+ match = html.match(END_TAG_REGEXP);
+
+ if (match) {
+ html = html.substring(match[0].length);
+ match[0].replace(END_TAG_REGEXP, parseEndTag);
+ chars = false;
+ }
+
+ // start tag
+ } else if (BEGIN_TAG_REGEXP.test(html)) {
+ match = html.match(START_TAG_REGEXP);
+
+ if (match) {
+ // We only have a valid start-tag if there is a '>'.
+ if (match[4]) {
+ html = html.substring(match[0].length);
+ match[0].replace(START_TAG_REGEXP, parseStartTag);
+ }
+ chars = false;
+ } else {
+ // no ending tag found --- this piece should be encoded as an entity.
+ text += '<';
+ html = html.substring(1);
+ }
+ }
+
+ if (chars) {
+ index = html.indexOf("<");
+
+ text += index < 0 ? html : html.substring(0, index);
+ html = index < 0 ? "" : html.substring(index);
+
+ if (handler.chars) handler.chars(decodeEntities(text));
+ }
+
+ } else {
+ html = html.replace(new RegExp("([^]*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'),
+ function(all, text) {
+ text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");
+
+ if (handler.chars) handler.chars(decodeEntities(text));
+
+ return "";
+ });
+
+ parseEndTag("", stack.last());
+ }
+
+ if (html == last) {
+ throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " +
+ "of html: {0}", html);
+ }
+ last = html;
+ }
+
+ // Clean up any remaining tags
+ parseEndTag();
+
+ function parseStartTag(tag, tagName, rest, unary) {
+ tagName = angular.lowercase(tagName);
+ if (blockElements[ tagName ]) {
+ while (stack.last() && inlineElements[ stack.last() ]) {
+ parseEndTag("", stack.last());
+ }
+ }
+
+ if (optionalEndTagElements[ tagName ] && stack.last() == tagName) {
+ parseEndTag("", tagName);
+ }
+
+ unary = voidElements[ tagName ] || !!unary;
+
+ if (!unary)
+ stack.push(tagName);
+
+ var attrs = {};
+
+ rest.replace(ATTR_REGEXP,
+ function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
+ var value = doubleQuotedValue
+ || singleQuotedValue
+ || unquotedValue
+ || '';
+
+ attrs[name] = decodeEntities(value);
+ });
+ if (handler.start) handler.start(tagName, attrs, unary);
+ }
+
+ function parseEndTag(tag, tagName) {
+ var pos = 0, i;
+ tagName = angular.lowercase(tagName);
+ if (tagName)
+ // Find the closest opened tag of the same type
+ for (pos = stack.length - 1; pos >= 0; pos--)
+ if (stack[ pos ] == tagName)
+ break;
+
+ if (pos >= 0) {
+ // Close all the open elements, up the stack
+ for (i = stack.length - 1; i >= pos; i--)
+ if (handler.end) handler.end(stack[ i ]);
+
+ // Remove the open elements from the stack
+ stack.length = pos;
+ }
+ }
+}
+
+var hiddenPre=document.createElement("pre");
+var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/;
+/**
+ * decodes all entities into regular string
+ * @param value
+ * @returns {string} A string with decoded entities.
+ */
+function decodeEntities(value) {
+ if (!value) { return ''; }
+
+ // Note: IE8 does not preserve spaces at the start/end of innerHTML
+ // so we must capture them and reattach them afterward
+ var parts = spaceRe.exec(value);
+ var spaceBefore = parts[1];
+ var spaceAfter = parts[3];
+ var content = parts[2];
+ if (content) {
+ hiddenPre.innerHTML=content.replace(/= 1536 && c <= 1540) ||
+ c == 1807 ||
+ c == 6068 ||
+ c == 6069 ||
+ (c >= 8204 && c <= 8207) ||
+ (c >= 8232 && c <= 8239) ||
+ (c >= 8288 && c <= 8303) ||
+ c == 65279 ||
+ (c >= 65520 && c <= 65535)) return '' + c + ';';
+ return value; // avoids multilingual issues
+ }).
+ replace(//g, '>');
+}
+
+var trim = (function() {
+ // native trim is way faster: http://jsperf.com/angular-trim-test
+ // but IE doesn't have it... :-(
+ // TODO: we should move this into IE/ES5 polyfill
+ if (!String.prototype.trim) {
+ return function(value) {
+ return angular.isString(value) ? value.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : value;
+ };
+ }
+ return function(value) {
+ return angular.isString(value) ? value.trim() : value;
+ };
+})();
+
+// Custom logic for accepting certain style options only - textAngular
+// Currently allows only the color, background-color, text-align, float, width and height attributes
+// all other attributes should be easily done through classes.
+function validStyles(styleAttr){
+ var result = '';
+ var styleArray = styleAttr.split(';');
+ angular.forEach(styleArray, function(value){
+ var v = value.split(':');
+ if(v.length == 2){
+ var key = trim(angular.lowercase(v[0]));
+ var value = trim(angular.lowercase(v[1]));
+ if(
+ (key === 'color' || key === 'background-color') && (
+ value.match(/^rgb\([0-9%,\. ]*\)$/i)
+ || value.match(/^rgba\([0-9%,\. ]*\)$/i)
+ || value.match(/^hsl\([0-9%,\. ]*\)$/i)
+ || value.match(/^hsla\([0-9%,\. ]*\)$/i)
+ || value.match(/^#[0-9a-f]{3,6}$/i)
+ || value.match(/^[a-z]*$/i)
+ )
+ ||
+ key === 'text-align' && (
+ value === 'left'
+ || value === 'right'
+ || value === 'center'
+ || value === 'justify'
+ )
+ ||
+ key === 'text-decoration' && (
+ value === 'underline'
+ || value === 'line-through'
+ )
+ || key === 'font-weight' && (
+ value === 'bold'
+ )
+ ||
+ key === 'float' && (
+ value === 'left'
+ || value === 'right'
+ || value === 'none'
+ )
+ ||
+ (key === 'width' || key === 'height') && (
+ value.match(/[0-9\.]*(px|em|rem|%)/)
+ )
+ || // Reference #520
+ (key === 'direction' && value.match(/^ltr|rtl|initial|inherit$/))
+ ) result += key + ': ' + value + ';';
+ }
+ });
+ return result;
+}
+
+// this function is used to manually allow specific attributes on specific tags with certain prerequisites
+function validCustomTag(tag, attrs, lkey, value){
+ // catch the div placeholder for the iframe replacement
+ if (tag === 'img' && attrs['ta-insert-video']){
+ if(lkey === 'ta-insert-video' || lkey === 'allowfullscreen' || lkey === 'frameborder' || (lkey === 'contenteditable' && value === 'false')) return true;
+ }
+ return false;
+}
+
+/**
+ * create an HTML/XML writer which writes to buffer
+ * @param {Array} buf use buf.jain('') to get out sanitized html string
+ * @returns {object} in the form of {
+ * start: function(tag, attrs, unary) {},
+ * end: function(tag) {},
+ * chars: function(text) {},
+ * comment: function(text) {}
+ * }
+ */
+function htmlSanitizeWriter(buf, uriValidator) {
+ var ignore = false;
+ var out = angular.bind(buf, buf.push);
+ return {
+ start: function(tag, attrs, unary) {
+ tag = angular.lowercase(tag);
+ if (!ignore && specialElements[tag]) {
+ ignore = tag;
+ }
+ if (!ignore && validElements[tag] === true) {
+ out('<');
+ out(tag);
+ angular.forEach(attrs, function(value, key) {
+ var lkey=angular.lowercase(key);
+ var isImage=(tag === 'img' && lkey === 'src') || (lkey === 'background');
+ if ((lkey === 'style' && (value = validStyles(value)) !== '') || validCustomTag(tag, attrs, lkey, value) || validAttrs[lkey] === true &&
+ (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
+ out(' ');
+ out(key);
+ out('="');
+ out(encodeEntities(value));
+ out('"');
+ }
+ });
+ out(unary ? '/>' : '>');
+ }
+ },
+ comment: function (com) {
+ out(com);
+ },
+ whitespace: function (ws) {
+ out(encodeEntities(ws));
+ },
+ end: function(tag) {
+ tag = angular.lowercase(tag);
+ if (!ignore && validElements[tag] === true) {
+ out('');
+ out(tag);
+ out('>');
+ }
+ if (tag == ignore) {
+ ignore = false;
+ }
+ },
+ chars: function(chars) {
+ if (!ignore) {
+ out(encodeEntities(chars));
+ }
+ }
+ };
+}
+
+
+// define ngSanitize module and register $sanitize service
+angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
+
+/* global sanitizeText: false */
+
+/**
+ * @ngdoc filter
+ * @name linky
+ * @kind function
+ *
+ * @description
+ * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
+ * plain email address links.
+ *
+ * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
+ *
+ * @param {string} text Input text.
+ * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
+ * @returns {string} Html-linkified text.
+ *
+ * @usage
+
+ *
+ * @example
+
+
+
+
+ Snippet:
+
+
+ Filter
+ Source
+ Rendered
+
+
+ linky filter
+
+ <div ng-bind-html="snippet | linky"> </div>
+
+
+
+
+
+
+ linky target
+
+ <div ng-bind-html="snippetWithTarget | linky:'_blank'"> </div>
+
+
+
+
+
+
+ no filter
+ <div ng-bind="snippet"> </div>
+
+
+
+
+
+ it('should linkify the snippet with urls', function() {
+ expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
+ toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
+ 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
+ expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
+ });
+
+ it('should not linkify snippet without the linky filter', function() {
+ expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
+ toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
+ 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
+ expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
+ });
+
+ it('should update', function() {
+ element(by.model('snippet')).clear();
+ element(by.model('snippet')).sendKeys('new http://link.');
+ expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
+ toBe('new http://link.');
+ expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
+ expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
+ .toBe('new http://link.');
+ });
+
+ it('should work with the target property', function() {
+ expect(element(by.id('linky-target')).
+ element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
+ toBe('http://angularjs.org/');
+ expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
+ });
+
+
+ */
+angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
+ var LINKY_URL_REGEXP =
+ /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"”’]/,
+ MAILTO_REGEXP = /^mailto:/;
+
+ return function(text, target) {
+ if (!text) return text;
+ var match;
+ var raw = text;
+ var html = [];
+ var url;
+ var i;
+ while ((match = raw.match(LINKY_URL_REGEXP))) {
+ // We can not end in these as they are sometimes found at the end of the sentence
+ url = match[0];
+ // if we did not match ftp/http/www/mailto then assume mailto
+ if (!match[2] && !match[4]) {
+ url = (match[3] ? 'http://' : 'mailto:') + url;
+ }
+ i = match.index;
+ addText(raw.substr(0, i));
+ addLink(url, match[0].replace(MAILTO_REGEXP, ''));
+ raw = raw.substring(i + match[0].length);
+ }
+ addText(raw);
+ return $sanitize(html.join(''));
+
+ function addText(text) {
+ if (!text) {
+ return;
+ }
+ html.push(sanitizeText(text));
+ }
+
+ function addLink(url, text) {
+ html.push('
');
+ addText(text);
+ html.push(' ');
+ }
+ };
+}]);
+
+
+})(window, window.angular);
diff --git a/static/js/textAngular-sanitize.min.js b/static/js/textAngular-sanitize.min.js
new file mode 100644
index 0000000..b1087b8
--- /dev/null
+++ b/static/js/textAngular-sanitize.min.js
@@ -0,0 +1,6 @@
+/**
+ * @license AngularJS v1.3.10
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+!function(a,b,c){"use strict";function d(){this.$get=["$$sanitizeUri",function(a){return function(b){"undefined"!=typeof arguments[1]&&(arguments[1].version="taSanitize");var c=[];return g(b,l(c,function(b,c){return!/^unsafe/.test(a(b,c))})),c.join("")}}]}function e(a){var c=[],d=l(c,b.noop);return d.chars(a),c.join("")}function f(a){var b,c={},d=a.split(",");for(b=0;b
=0&&k[f]!=d;f--);if(f>=0){for(e=k.length-1;e>=f;e--)c.end&&c.end(k[e]);k.length=f}}"string"!=typeof a&&(a=null===a||"undefined"==typeof a?"":""+a);var f,g,i,j,k=[],l=a;for(k.last=function(){return k[k.length-1]};a;){if(j="",g=!0,k.last()&&G[k.last()])a=a.replace(new RegExp("([^]*)<\\s*\\/\\s*"+k.last()+"[^>]*>","i"),function(a,b){return b=b.replace(s,"$1").replace(v,"$1"),c.chars&&c.chars(h(b)),""}),e("",k.last());else{if(y.test(a)){if(i=a.match(y)){i[0];c.whitespace&&c.whitespace(i[0]),a=a.replace(i[0],""),g=!1}}else t.test(a)?(i=a.match(t),i&&(c.comment&&c.comment(i[1]),a=a.replace(i[0],""),g=!1)):u.test(a)?(i=a.match(u),i&&(a=a.replace(i[0],""),g=!1)):r.test(a)?(i=a.match(o),i&&(a=a.substring(i[0].length),i[0].replace(o,e),g=!1)):q.test(a)&&(i=a.match(n),i?(i[4]&&(a=a.substring(i[0].length),i[0].replace(n,d)),g=!1):(j+="<",a=a.substring(1)));g&&(f=a.indexOf("<"),j+=0>f?a:a.substring(0,f),a=0>f?"":a.substring(f),c.chars&&c.chars(h(j)))}if(a==l)throw m("badparse","The sanitizer was unable to parse the following block of html: {0}",a);l=a}e()}function h(a){if(!a)return"";var b=N.exec(a),c=b[1],d=b[3],e=b[2];return e&&(M.innerHTML=e.replace(/=b||173==b||b>=1536&&1540>=b||1807==b||6068==b||6069==b||b>=8204&&8207>=b||b>=8232&&8239>=b||b>=8288&&8303>=b||65279==b||b>=65520&&65535>=b?""+b+";":a}).replace(//g,">")}function j(a){var c="",d=a.split(";");return b.forEach(d,function(a){var d=a.split(":");if(2==d.length){var e=O(b.lowercase(d[0])),a=O(b.lowercase(d[1]));(("color"===e||"background-color"===e)&&(a.match(/^rgb\([0-9%,\. ]*\)$/i)||a.match(/^rgba\([0-9%,\. ]*\)$/i)||a.match(/^hsl\([0-9%,\. ]*\)$/i)||a.match(/^hsla\([0-9%,\. ]*\)$/i)||a.match(/^#[0-9a-f]{3,6}$/i)||a.match(/^[a-z]*$/i))||"text-align"===e&&("left"===a||"right"===a||"center"===a||"justify"===a)||"text-decoration"===e&&("underline"===a||"line-through"===a)||"font-weight"===e&&"bold"===a||"float"===e&&("left"===a||"right"===a||"none"===a)||("width"===e||"height"===e)&&a.match(/[0-9\.]*(px|em|rem|%)/)||"direction"===e&&a.match(/^ltr|rtl|initial|inherit$/))&&(c+=e+": "+a+";")}}),c}function k(a,b,c,d){return"img"===a&&b["ta-insert-video"]&&("ta-insert-video"===c||"allowfullscreen"===c||"frameborder"===c||"contenteditable"===c&&"false"===d)?!0:!1}function l(a,c){var d=!1,e=b.bind(a,a.push);return{start:function(a,f,g){a=b.lowercase(a),!d&&G[a]&&(d=a),d||H[a]!==!0||(e("<"),e(a),b.forEach(f,function(d,g){var h=b.lowercase(g),l="img"===a&&"src"===h||"background"===h;("style"===h&&""!==(d=j(d))||k(a,f,h,d)||L[h]===!0&&(I[h]!==!0||c(d,l)))&&(e(" "),e(g),e('="'),e(i(d)),e('"'))}),e(g?"/>":">"))},comment:function(a){e(a)},whitespace:function(a){e(i(a))},end:function(a){a=b.lowercase(a),d||H[a]!==!0||(e(""),e(a),e(">")),a==d&&(d=!1)},chars:function(a){d||e(i(a))}}}var m=b.$$minErr("$sanitize"),n=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,o=/^<\/\s*([\w:-]+)[^>]*>/,p=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,q=/^,r=/^<\//,s=//g,t=/(^)/,u=/]*?)>/i,v=//g,w=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,x=/([^\#-~| |!])/g,y=/^(\s+)/,z=f("area,br,col,hr,img,wbr,input"),A=f("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),B=f("rp,rt"),C=b.extend({},B,A),D=b.extend({},A,f("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")),E=b.extend({},B,f("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var")),F=f("animate,animateColor,animateMotion,animateTransform,circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,set,stop,svg,switch,text,title,tspan,use"),G=f("script,style"),H=b.extend({},z,D,E,C,F),I=f("background,cite,href,longdesc,src,usemap,xlink:href"),J=f("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,id,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,size,span,start,summary,target,title,type,valign,value,vspace,width"),K=f("accent-height,accumulate,additive,alphabetic,arabic-form,ascent,attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan"),L=b.extend({},I,K,J),M=document.createElement("pre"),N=/^(\s*)([\s\S]*?)(\s*)$/,O=function(){return String.prototype.trim?function(a){return b.isString(a)?a.trim():a}:function(a){return b.isString(a)?a.replace(/^\s\s*/,"").replace(/\s\s*$/,""):a}}();b.module("ngSanitize",[]).provider("$sanitize",d),b.module("ngSanitize").filter("linky",["$sanitize",function(a){var c=/((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"”’]/,d=/^mailto:/;return function(f,g){function h(a){a&&n.push(e(a))}function i(a,c){n.push("'),h(c),n.push(" ")}if(!f)return f;for(var j,k,l,m=f,n=[];j=m.match(c);)k=j[0],j[2]||j[4]||(k=(j[3]?"http://":"mailto:")+k),l=j.index,h(m.substr(0,l)),i(k,j[0].replace(d,"")),m=m.substring(l+j[0].length);return h(m),a(n.join(""))}}])}(window,window.angular);
\ No newline at end of file
diff --git a/static/js/textAngular.js b/static/js/textAngular.js
new file mode 100644
index 0000000..127dbd4
--- /dev/null
+++ b/static/js/textAngular.js
@@ -0,0 +1,3069 @@
+/*
+@license textAngular
+Author : Austin Anderson
+License : 2013 MIT
+Version 1.5.1
+
+See README.md or https://github.com/fraywing/textAngular/wiki for requirements and use.
+*/
+
+/*
+Commonjs package manager support (eg componentjs).
+*/
+
+
+"use strict";
+// IE version detection - http://stackoverflow.com/questions/4169160/javascript-ie-detection-why-not-use-simple-conditional-comments
+// We need this as IE sometimes plays funny tricks with the contenteditable.
+// ----------------------------------------------------------
+// If you're not in IE (or IE version is less than 5) then:
+// ie === undefined
+// If you're in IE (>=5) then you can determine which version:
+// ie === 7; // IE7
+// Thus, to detect IE:
+// if (ie) {}
+// And to detect the version:
+// ie === 6 // IE6
+// ie > 7 // IE8, IE9, IE10 ...
+// ie < 9 // Anything less than IE9
+// ----------------------------------------------------------
+/* istanbul ignore next: untestable browser check */
+var _browserDetect = {
+ ie: (function(){
+ var undef,
+ v = 3,
+ div = document.createElement('div'),
+ all = div.getElementsByTagName('i');
+
+ while (
+ div.innerHTML = '',
+ all[0]
+ );
+
+ return v > 4 ? v : undef;
+ }()),
+ webkit: /AppleWebKit\/([\d.]+)/i.test(navigator.userAgent)
+};
+
+// fix a webkit bug, see: https://gist.github.com/shimondoodkin/1081133
+// this is set true when a blur occurs as the blur of the ta-bind triggers before the click
+var globalContentEditableBlur = false;
+/* istanbul ignore next: Browser Un-Focus fix for webkit */
+if(_browserDetect.webkit) {
+ document.addEventListener("mousedown", function(_event){
+ var e = _event || window.event;
+ var curelement = e.target;
+ if(globalContentEditableBlur && curelement !== null){
+ var isEditable = false;
+ var tempEl = curelement;
+ while(tempEl !== null && tempEl.tagName.toLowerCase() !== 'html' && !isEditable){
+ isEditable = tempEl.contentEditable === 'true';
+ tempEl = tempEl.parentNode;
+ }
+ if(!isEditable){
+ document.getElementById('textAngular-editableFix-010203040506070809').setSelectionRange(0, 0); // set caret focus to an element that handles caret focus correctly.
+ curelement.focus(); // focus the wanted element.
+ if (curelement.select) {
+ curelement.select(); // use select to place cursor for input elements.
+ }
+ }
+ }
+ globalContentEditableBlur = false;
+ }, false); // add global click handler
+ angular.element(document).ready(function () {
+ angular.element(document.body).append(angular.element(' '));
+ });
+}
+
+// Gloabl to textAngular REGEXP vars for block and list elements.
+
+var BLOCKELEMENTS = /^(address|article|aside|audio|blockquote|canvas|dd|div|dl|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|noscript|ol|output|p|pre|section|table|tfoot|ul|video)$/i;
+var LISTELEMENTS = /^(ul|li|ol)$/i;
+var VALIDELEMENTS = /^(address|article|aside|audio|blockquote|canvas|dd|div|dl|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|noscript|ol|output|p|pre|section|table|tfoot|ul|video|li)$/i;
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Compatibility
+/* istanbul ignore next: trim shim for older browsers */
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return this.replace(/^\s+|\s+$/g, '');
+ };
+}
+
+/*
+ Custom stylesheet for the placeholders rules.
+ Credit to: http://davidwalsh.name/add-rules-stylesheets
+*/
+var sheet, addCSSRule, removeCSSRule, _addCSSRule, _removeCSSRule, _getRuleIndex;
+/* istanbul ignore else: IE <8 test*/
+if(_browserDetect.ie > 8 || _browserDetect.ie === undefined){
+ var _sheets = document.styleSheets;
+ /* istanbul ignore next: preference for stylesheet loaded externally */
+ for(var i = 0; i < _sheets.length; i++){
+ if(_sheets[i].media.length === 0 || _sheets[i].media.mediaText.match(/(all|screen)/ig)){
+ if(_sheets[i].href){
+ if(_sheets[i].href.match(/textangular\.(min\.|)css/ig)){
+ sheet = _sheets[i];
+ break;
+ }
+ }
+ }
+ }
+ /* istanbul ignore next: preference for stylesheet loaded externally */
+ if(!sheet){
+ // this sheet is used for the placeholders later on.
+ sheet = (function() {
+ // Create the