diff --git a/Builds/NuGet/UmbracoForms.uCaptcha.nuspec b/Builds/NuGet/UmbracoForms.uCaptcha.nuspec
index a5b2146..f064cb8 100644
--- a/Builds/NuGet/UmbracoForms.uCaptcha.nuspec
+++ b/Builds/NuGet/UmbracoForms.uCaptcha.nuspec
@@ -2,7 +2,7 @@
AaronSadler.uCaptcha
- 1.0.3
+ 1.0.4
UmbracoForms.uCaptcha
Aaron Sadler
Aaron Sadler
@@ -17,9 +17,9 @@
umbraco, umbraco-cms, hCaptcha, umbraco-forms, reCaptcha
-
-
-
+
+
+
diff --git a/Builds/package.xml b/Builds/package.xml
index 9f36cca..d197ef9 100644
--- a/Builds/package.xml
+++ b/Builds/package.xml
@@ -3,13 +3,13 @@
UmbracoForms.uCaptcha
- 1.0.3
+ 1.0.4
MIT
https://github.com/AaronSadlerUK/UmbracoForms.uCaptcha
8
- 6
+ 13
0
diff --git a/TestSite-V8.7.3/App_Data/packages/installedPackages.config b/TestSite-V8.7.3/App_Data/packages/installedPackages.config
new file mode 100644
index 0000000..3299dfc
--- /dev/null
+++ b/TestSite-V8.7.3/App_Data/packages/installedPackages.config
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.hcaptcha.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.hcaptcha.js
new file mode 100644
index 0000000..935eb6a
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.hcaptcha.js
@@ -0,0 +1,11 @@
+//hCaptcha callback
+function onSubmit(token) {
+ //Find form which triggered hCaptcha
+ var uf = $("form");
+ uf.each(function () {
+ if ($(this).find('.h-captcha-response').val(token)) {
+ //Set hidden field to true if response matches
+ $(this).find('.u-captcha-bool').val("true");
+ }
+ });
+}
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.invisible.hcaptcha.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.invisible.hcaptcha.js
new file mode 100644
index 0000000..82e07a6
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.invisible.hcaptcha.js
@@ -0,0 +1,40 @@
+var submittedFormId = null;
+
+//hCaptcha callback
+function onSubmit(token) {
+ //Get form container with the id set earlier
+ var frm = $("#" + submittedFormId);
+ var form = frm.find('form').first();
+ //Check we have the correct form by comparing response token
+ if (form.length > 0 && form.find(".h-captcha-response").val(token)) {
+ //Set hCaptcha field to true
+ form.find(".u-captcha-bool").val("true");
+ //Submit the form
+ form.submit();
+ }
+}
+
+function validate() {
+ //trigger hCaptcha
+ hcaptcha.execute();
+}
+
+//Remove umbraco forms click event
+$(".umbraco-forms-form input[type=submit]").not(".cancel").off('click');
+
+//Replace with hCaptcha trigger
+$(".umbraco-forms-form input[type=submit]").not(".cancel").click(function (evt) {
+ evt.preventDefault();
+ var self = $(this);
+ var frm = self.closest("form");
+ //Validate the form as per usual Umbraco forms way
+ frm.validate();
+ if (frm.valid()) {
+ //Set form id for easy form finding on call back
+ submittedFormId = frm.parent(".umbraco-forms-form").attr('id');
+ //Start hCaptcha process
+ validate();
+ //Disable submit button
+ self.attr("disabled", "disabled");
+ }
+});
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.invisible.recaptcha.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.invisible.recaptcha.js
new file mode 100644
index 0000000..70831d6
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.invisible.recaptcha.js
@@ -0,0 +1,40 @@
+var submittedFormId = null;
+
+//hCaptcha callback
+function onSubmit(token) {
+ //Get form container with the id set earlier
+ var frm = $("#" + submittedFormId);
+ var form = frm.find('form').first();
+ //Check we have the correct form by comparing response token
+ if (form.length > 0 && form.find(".g-captcha-response").val(token)) {
+ //Set hCaptcha field to true
+ form.find(".u-captcha-bool").val("true");
+ //Submit the form
+ form.submit();
+ }
+}
+
+function validate() {
+ //trigger hCaptcha
+ hcaptcha.execute();
+}
+
+//Remove umbraco forms click event
+$(".umbraco-forms-form input[type=submit]").not(".cancel").off('click');
+
+//Replace with hCaptcha trigger
+$(".umbraco-forms-form input[type=submit]").not(".cancel").click(function (evt) {
+ evt.preventDefault();
+ var self = $(this);
+ var frm = self.closest("form");
+ //Validate the form as per usual Umbraco forms way
+ frm.validate();
+ if (frm.valid()) {
+ //Set form id for easy form finding on call back
+ submittedFormId = frm.parent(".umbraco-forms-form").attr('id');
+ //Start hCaptcha process
+ validate();
+ //Disable submit button
+ self.attr("disabled", "disabled");
+ }
+});
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.recaptcha.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.recaptcha.js
new file mode 100644
index 0000000..cc75373
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Assets/umbracoforms.recaptcha.js
@@ -0,0 +1,11 @@
+//hCaptcha callback
+function onSubmit(token) {
+ //Find form which triggered hCaptcha
+ var uf = $("form");
+ uf.each(function () {
+ if ($(this).find('.g-captcha-response').val(token)) {
+ //Set hidden field to true if response matches
+ $(this).find('.u-captcha-bool').val("true");
+ }
+ });
+}
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Backoffice/Common/FieldTypes/ucaptchafield.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Backoffice/Common/FieldTypes/ucaptchafield.html
new file mode 100644
index 0000000..3f78e23
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Backoffice/Common/FieldTypes/ucaptchafield.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Images/uCaptcha.png b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Images/uCaptcha.png
new file mode 100644
index 0000000..d748fa7
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms.uCaptcha/Images/uCaptcha.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2828675c304a4efa7205c23fd740992fed92cbfab8bfaca6a8994116de2f1416
+size 7245
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/BaremetricsCalendar/public/css/application.css b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/BaremetricsCalendar/public/css/application.css
new file mode 100644
index 0000000..09cd661
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/BaremetricsCalendar/public/css/application.css
@@ -0,0 +1 @@
+.daterange{position:relative}.daterange *{-webkit-box-sizing:border-box;box-sizing:border-box}.daterange div,.daterange li,.daterange span,.daterange ul{margin:0;padding:0;border:0}.daterange ul{list-style:none}.daterange.dr-active{z-index:10}.daterange .dr-input{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;border:1px solid #c3cacd;-webkit-border-radius:5px;border-radius:5px;background-color:#fff;position:relative;z-index:5;overflow:hidden;height:40px}.daterange .dr-input:hover{border-color:#2693d5}.daterange .dr-input.dr-active{-webkit-box-shadow:0 0 0 3px rgba(38,147,213,.3);box-shadow:0 0 0 3px rgba(38,147,213,.3);border-color:#2693d5}.daterange .dr-input .dr-dates{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:start;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;padding:0 1.5rem 0 .75rem;min-width:-webkit-calc(100% - 35px);min-width:calc(100% - 35px)}.daterange .dr-input .dr-dates .dr-date{font-size:.9375rem;padding:.65625rem 0;text-align:center;white-space:nowrap;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;outline:0}.daterange .dr-input .dr-dates .dr-date.dr-active,.daterange .dr-input .dr-dates .dr-date:focus,.daterange .dr-input .dr-dates .dr-date:hover{color:#2693d5}.daterange .dr-input .dr-dates .dr-date:empty:after{content:attr(placeholder);color:#9ba3a7}.daterange .dr-input .dr-dates .dr-dates-dash{color:#9ba3a7;padding:0 10px;-webkit-box-flex:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;font-weight:600}.daterange .dr-input .dr-presets{width:2.1875rem;border-left:1px solid #c3cacd;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.daterange .dr-input .dr-presets.dr-active,.daterange .dr-input .dr-presets:hover{border-color:#2693d5;-webkit-box-shadow:inset 0 2px 3px #ebf1f4;box-shadow:inset 0 2px 3px #ebf1f4}.daterange .dr-input .dr-presets.dr-active .dr-preset-bar,.daterange .dr-input .dr-presets:hover .dr-preset-bar{background-color:#2693d5}.daterange .dr-input .dr-presets .dr-preset-bar{height:2px;background-color:#c3cacd;margin:1px 0 1px 25%}.daterange .dr-input .dr-presets .dr-preset-bar:nth-child(1){width:50%}.daterange .dr-input .dr-presets .dr-preset-bar:nth-child(2){width:40%}.daterange .dr-input .dr-presets .dr-preset-bar:nth-child(3){width:30%}.daterange .dr-selections{position:absolute}.daterange .dr-selections .dr-calendar{background-color:#fff;font-size:.9375rem;-webkit-box-shadow:0 0 5px #c3cacd;box-shadow:0 0 5px #c3cacd;-webkit-border-radius:5px;border-radius:5px;position:relative;overflow:hidden;z-index:4;padding-top:5px;top:-5px;left:4px;-webkit-transition:width .2s;-o-transition:width .2s;transition:width .2s;min-width:210px}.daterange .dr-selections .dr-calendar .dr-range-switcher{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;padding:.375rem .5rem;font-size:.875rem}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;border:1px solid rgba(195,202,205,.5);-webkit-border-radius:5px;border-radius:5px;height:1.5625rem}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i{color:#c3cacd;position:relative;top:-1px;cursor:pointer;font-size:.75rem;height:100%;width:20px}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i:hover:after,.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i:hover:before{background-color:#2693d5}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i.dr-disabled{pointer-events:none;opacity:0}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i:after,.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i:before{content:"";position:absolute;width:7px;height:2px;background-color:#c3cacd;-webkit-border-radius:1px;border-radius:1px;left:50%}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i.dr-left:before{top:-webkit-calc(50% - 2px);top:calc(50% - 2px);-webkit-transform:translate(-50%,-50%) rotate(-45deg);-ms-transform:translate(-50%,-50%) rotate(-45deg);transform:translate(-50%,-50%) rotate(-45deg)}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i.dr-left:after{top:-webkit-calc(50% + 2px);top:calc(50% + 2px);-webkit-transform:translate(-50%,-50%) rotate(45deg);-ms-transform:translate(-50%,-50%) rotate(45deg);transform:translate(-50%,-50%) rotate(45deg)}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i.dr-right:before{top:-webkit-calc(50% - 2px);top:calc(50% - 2px);-webkit-transform:translate(-50%,-50%) rotate(45deg);-ms-transform:translate(-50%,-50%) rotate(45deg);transform:translate(-50%,-50%) rotate(45deg)}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i.dr-right:after{top:-webkit-calc(50% + 2px);top:calc(50% + 2px);-webkit-transform:translate(-50%,-50%) rotate(-45deg);-ms-transform:translate(-50%,-50%) rotate(-45deg);transform:translate(-50%,-50%) rotate(-45deg)}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-month-switcher{width:100%;margin-right:.375rem}.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-year-switcher{min-width:80px}.daterange .dr-selections .dr-calendar .dr-days-of-week-list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:#ebf1f4;font-size:.625rem;color:#9ba3a7;padding:.3125rem 0;border:1px solid rgba(195,202,205,.5);border-left:none;border-right:none}.daterange .dr-selections .dr-calendar .dr-days-of-week-list .dr-day-of-week{width:14.28%;text-align:center}.daterange .dr-selections .dr-calendar .dr-day-list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;font-size:.9375rem}.daterange .dr-selections .dr-calendar .dr-day-list .dr-day{padding:.3125rem;text-align:center;width:14.28%;cursor:pointer;color:#4f565c}.daterange .dr-selections .dr-calendar .dr-day-list .dr-day.dr-hover:not(.dr-current){background-color:#ebf1f4!important}.daterange .dr-selections .dr-calendar .dr-day-list .dr-day.dr-hover-before{border-left:2px solid #2693d5!important;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px;padding-left:.1875rem!important}.daterange .dr-selections .dr-calendar .dr-day-list .dr-day.dr-hover-after{border-right:2px solid #2693d5!important;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;padding-right:.1875rem!important}.daterange .dr-selections .dr-calendar .dr-day-list .dr-end,.daterange .dr-selections .dr-calendar .dr-day-list .dr-selected,.daterange .dr-selections .dr-calendar .dr-day-list .dr-start{background-color:#ebf1f4}.daterange .dr-selections .dr-calendar .dr-day-list .dr-maybe{background-color:#ebf1f4!important}.daterange .dr-selections .dr-calendar .dr-day-list .dr-fade{color:#c3cacd}.daterange .dr-selections .dr-calendar .dr-day-list .dr-start{border-left:2px solid #2693d5;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px;padding-left:.1875rem}.daterange .dr-selections .dr-calendar .dr-day-list .dr-end{border-right:2px solid #2693d5;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;padding-right:.1875rem}.daterange .dr-selections .dr-calendar .dr-day-list .dr-current{color:#2693d5!important;background-color:rgba(38,147,213,.2)!important}.daterange .dr-selections .dr-calendar .dr-day-list .dr-outside{pointer-events:none;cursor:default;color:rgba(195,202,205,.5)}.daterange .dr-selections .dr-preset-list{background-color:#fff;color:#2693d5;font-size:.9375rem;-webkit-box-shadow:0 0 5px #c3cacd;box-shadow:0 0 5px #c3cacd;-webkit-border-radius:5px;border-radius:5px;position:relative;overflow:hidden;z-index:4;padding-top:5px;top:-5px;left:4px;width:100%}.daterange .dr-selections .dr-list-item{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:end;-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end;padding:.75rem .625rem;border-bottom:1px solid #ebf1f4;cursor:pointer;white-space:nowrap}.daterange .dr-selections .dr-list-item:hover{background-color:#ebf1f4}.daterange .dr-selections .dr-list-item .dr-item-aside{color:#9ba3a7;font-size:.75rem;margin-left:.3125rem;position:relative;top:-1px}.daterange--single .dr-input{cursor:text}.daterange--single .dr-input .dr-dates{padding:0;min-width:160px;width:100%}.daterange--single .dr-input .dr-dates .dr-date{width:100%;padding:.65625rem .75rem;text-align:left;color:#4f565c}
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/BaremetricsCalendar/public/js/Calendar.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/BaremetricsCalendar/public/js/Calendar.js
new file mode 100644
index 0000000..4dabee8
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/BaremetricsCalendar/public/js/Calendar.js
@@ -0,0 +1,787 @@
+'use strict';
+
+
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['jquery', 'moment'], factory);
+ } else if (typeof exports === 'object') {
+ // Node/CommonJS
+ module.exports = factory(require('jquery'), require('moment'));
+ } else {
+ // Browser globals
+ root.Calendar = factory(jQuery, moment);
+ }
+} (this, function ($, moment) {
+ function Calendar(settings) {
+ var self = this;
+
+ this.settings = settings;
+
+ this.calIsOpen = false;
+ this.presetIsOpen = false;
+ this.sameDayRange = settings.same_day_range || false;
+
+ this.element = settings.element || $('.daterange');
+ this.selected = null;
+
+ this.type = this.element.hasClass('daterange--single') ? 'single' : 'double';
+ this.required = settings.required == false ? false : true;
+
+ this.format = settings.format || {};
+ this.format.input = settings.format && settings.format.input || 'MMMM D, YYYY';
+ this.format.preset = settings.format && settings.format.preset || 'll';
+ this.format.jump_month = settings.format && settings.format.jump_month || 'MMMM';
+ this.format.jump_year = settings.format && settings.format.jump_year || 'YYYY';
+
+ this.placeholder = settings.placeholder || this.format.input;
+
+ this.days_array = settings.days_array && settings.days_array.length == 7 ?
+ settings.days_array : moment.weekdaysMin();
+
+ this.orig_start_date = null;
+ this.orig_end_date = null;
+ this.orig_current_date = null;
+
+ this.earliest_date = settings.earliest_date ? moment(settings.earliest_date)
+ : moment('1900-01-01', 'YYYY-MM-DD');
+ this.latest_date = settings.latest_date ? moment(settings.latest_date)
+ : moment('2900-12-31', 'YYYY-MM-DD');
+ this.end_date = settings.end_date ? moment(settings.end_date)
+ : (this.type == 'double' ? moment() : null);
+ this.start_date = settings.start_date ? moment(settings.start_date)
+ : (this.type == 'double' ? this.end_date.clone().subtract(1, 'month') : null);
+ this.current_date = settings.current_date ? moment(settings.current_date)
+ : (this.type == 'single' ? moment() : null);
+
+ this.presets = settings.presets == false || this.type == 'single' ? false : true;
+
+ this.callback = settings.callback || this.calendarSetDates;
+
+ this.calendarHTML(this.type);
+
+ $('.dr-presets', this.element).click(function() {
+ self.presetToggle();
+ });
+
+ $('.dr-list-item', this.element).click(function() {
+ var start = $('.dr-item-aside', this).data('start');
+ var end = $('.dr-item-aside', this).data('end');
+
+ self.start_date = self.calendarCheckDate(start);
+ self.end_date = self.calendarCheckDate(end);
+
+ self.calendarSetDates();
+ self.presetToggle();
+ self.calendarSaveDates();
+ });
+
+ $('.dr-date', this.element).on({
+ 'click': function() {
+ self.calendarOpen(this);
+ },
+
+ 'keyup': function(event) {
+ if (event.keyCode == 9 && !self.calIsOpen && !self.start_date && !self.end_date)
+ self.calendarOpen(this);
+ },
+
+ 'keydown': function(event) {
+ switch (event.keyCode) {
+
+ case 9: // Tab
+ if ($(self.selected).hasClass('dr-date-start')) {
+ event.preventDefault();
+ self.calendarCheckDates();
+ self.calendarSetDates();
+ $('.dr-date-end', self.element).trigger('click');
+ } else {
+ self.calendarCheckDates();
+ self.calendarSetDates();
+ self.calendarSaveDates();
+ self.calendarClose('force');
+ }
+ break;
+
+ case 13: // Enter
+ event.preventDefault();
+ self.calendarCheckDates();
+ self.calendarSetDates();
+ self.calendarSaveDates();
+ self.calendarClose('force');
+ break;
+
+ case 27: // ESC
+ self.calendarSetDates();
+ self.calendarClose('force');
+ break;
+
+ case 38: // Up
+ event.preventDefault();
+ var timeframe = 'day';
+
+ if (event.shiftKey)
+ timeframe = 'week';
+
+ if (event.metaKey)
+ timeframe = 'month';
+
+ var back = moment(self.current_date).subtract(1, timeframe);
+
+ $(this).html(back.format(self.format.input));
+ self.current_date = back;
+ break;
+
+ case 40: // Down
+ event.preventDefault();
+ var timeframe = 'day';
+
+ if (event.shiftKey)
+ timeframe = 'week';
+
+ if (event.metaKey)
+ timeframe = 'month';
+
+ var forward = moment(self.current_date).add(1, timeframe);
+
+ $(this).html(forward.format(self.format.input));
+ self.current_date = forward;
+ break;
+ }
+ }
+ });
+
+ $('.dr-month-switcher i', this.element).click(function() {
+ var m = $('.dr-month-switcher span', self.element).data('month');
+ var y = $('.dr-year-switcher span', self.element).data('year');
+ var this_moment = moment([y, m, 1]);
+ var back = this_moment.clone().subtract(1, 'month');
+ var forward = this_moment.clone().add(1, 'month').startOf('day');
+
+ if ($(this).hasClass('dr-left')) {
+ self.calendarOpen(self.selected, back);
+ } else if ($(this).hasClass('dr-right')) {
+ self.calendarOpen(self.selected, forward);
+ }
+ });
+
+ $('.dr-year-switcher i', this.element).click(function() {
+ var m = $('.dr-month-switcher span', self.element).data('month');
+ var y = $('.dr-year-switcher span', self.element).data('year');
+ var this_moment = moment([y, m, 1]);
+ var back = this_moment.clone().subtract(1, 'year');
+ var forward = this_moment.clone().add(1, 'year').startOf('day');
+
+
+ if ($(this).hasClass('dr-left')) {
+ self.calendarOpen(self.selected, back);
+ } else if ($(this).hasClass('dr-right')) {
+ self.calendarOpen(self.selected, forward);
+ }
+ });
+
+ $('.dr-dates-dash', this.element).click(function() {
+ $('.dr-date-start', self.element).trigger('click');
+ });
+
+ // Once you click into a selection.. this lets you click out
+ this.element.on('click', function() {
+ document.addEventListener('click', function (event) {
+ var contains = $(event.target).parents(self.element);
+
+ if (!contains.length) {
+ if (self.presetIsOpen)
+ self.presetToggle();
+
+ if (self.calIsOpen) {
+ if ($(self.selected).hasClass('dr-date-end'))
+ self.calendarSaveDates();
+
+ self.calendarSetDates();
+ self.calendarClose('force');
+ }
+ }
+ });
+ });
+ }
+
+
+ Calendar.prototype.presetToggle = function() {
+ if (this.presetIsOpen == false) {
+ this.orig_start_date = this.start_date;
+ this.orig_end_date = this.end_date;
+ this.orig_current_date = this.current_date;
+
+ this.presetIsOpen = true;
+ } else if (this.presetIsOpen) {
+ this.presetIsOpen = false;
+ }
+
+ if (this.calIsOpen == true)
+ this.calendarClose();
+
+ $('.dr-preset-list', this.element).slideToggle(200);
+ $('.dr-input', this.element).toggleClass('dr-active');
+ $('.dr-presets', this.element).toggleClass('dr-active');
+ this.element.toggleClass('dr-active');
+ }
+
+
+ Calendar.prototype.presetCreate = function() {
+ var self = this;
+ var ul_presets = $('');
+ var presets = typeof self.settings.presets === 'object' ? self.settings.presets :
+ [{
+ label: 'Last 30 days',
+ start: moment(self.latest_date).subtract(29, 'days'),
+ end: self.latest_date
+ },{
+ label: 'Last month',
+ start: moment(self.latest_date).subtract(1, 'month').startOf('month'),
+ end: moment(self.latest_date).subtract(1, 'month').endOf('month')
+ },{
+ label: 'Last 3 months',
+ start: moment(self.latest_date).subtract(3, 'month').startOf('month'),
+ end: moment(self.latest_date).subtract(1, 'month').endOf('month')
+ },{
+ label: 'Last 6 months',
+ start: moment(self.latest_date).subtract(6, 'month').startOf('month'),
+ end: moment(self.latest_date).subtract(1, 'month').endOf('month')
+ },{
+ label: 'Last year',
+ start: moment(self.latest_date).subtract(1, 'year').startOf('year'),
+ end: moment(self.latest_date).subtract(1, 'year').endOf('year')
+ },{
+ label: 'All time',
+ start: self.earliest_date,
+ end: self.latest_date
+ }];
+
+ if (moment(self.latest_date).diff(moment(self.latest_date).startOf('month'), 'days') >= 6 &&
+ typeof self.settings.presets !== 'object'
+ ) {
+ presets.splice(1, 0, {
+ label: 'This month',
+ start: moment(self.latest_date).startOf('month'),
+ end: self.latest_date
+ });
+ }
+
+ $.each(presets, function(i, d) {
+ if (moment(d.start).isBefore(self.earliest_date)) {
+ d.start = self.earliest_date;
+ }
+ if (moment(d.start).isAfter(self.latest_date)) {
+ d.start = self.latest_date;
+ }
+ if (moment(d.end).isBefore(self.earliest_date)) {
+ d.end = self.earliest_date;
+ }
+ if (moment(d.end).isAfter(self.latest_date)) {
+ d.end = self.latest_date;
+ }
+
+ var startISO = moment(d.start).toISOString();
+ var endISO = moment(d.end).toISOString();
+ var string = moment(d.start).format(self.format.preset) +' – '+ moment(d.end).format(self.format.preset);
+
+ if ($('.dr-preset-list', self.element).length) {
+ var item = $('.dr-preset-list .dr-list-item:nth-of-type('+ (i + 1) +') .dr-item-aside', self.element);
+ item.data('start', startISO);
+ item.data('end', endISO);
+ item.html(string);
+ } else {
+ ul_presets.append(''+ d.label +
+ ''+ string +' '+
+ ' ');
+ }
+ });
+
+ return ul_presets;
+ }
+
+
+ Calendar.prototype.calendarSetDates = function() {
+ $('.dr-date-start', this.element).html(moment(this.start_date).format(this.format.input));
+ $('.dr-date-end', this.element).html(moment(this.end_date).format(this.format.input));
+
+ if (!this.start_date && !this.end_date) {
+ var old_date = $('.dr-date', this.element).html();
+ var new_date = moment(this.current_date).format(this.format.input);
+
+ if (old_date.length === 0 && !this.required)
+ new_date = '';
+
+ if (old_date != new_date)
+ $('.dr-date', this.element).html(new_date);
+ }
+ }
+
+
+ Calendar.prototype.calendarSaveDates = function() {
+ if (this.type === 'double') {
+ if (!moment(this.orig_end_date).isSame(this.end_date) || !moment(this.orig_start_date).isSame(this.start_date))
+ return this.callback();
+ } else {
+ if (!this.required || !moment(this.orig_current_date).isSame(this.current_date))
+ return this.callback();
+ }
+ }
+
+ Calendar.prototype.calendarCheckDate = function(d) {
+ // Today
+ if (d === 'today' || d === 'now')
+ return moment().isAfter(this.latest_date) ? this.latest_date :
+ moment().isBefore(this.earliest_date) ? this.earliest_date : moment();
+
+ // Earliest
+ if (d === 'earliest')
+ return this.earliest_date;
+
+ // Latest
+ if (d === 'latest')
+ return this.latest_date;
+
+ // Convert string to a date if keyword ago or ahead exists
+ if (d && (/\bago\b/.test(d) || /\bahead\b/.test(d)))
+ return this.stringToDate(d);
+
+ var regex = /(?:\d)((?:st|nd|rd|th)?,?)/;
+ var d_array = d ? d.replace(regex, '').split(' ') : [];
+
+ // Add current year if year is not included
+ if (d_array.length == 2) {
+ d_array.push(moment().format(this.format.jump_year));
+ d = d_array.join(' ');
+ }
+
+ // Convert using settings format
+ var parsed_d = this.parseDate(d);
+
+ if (!parsed_d.isValid())
+ return moment(d); // occurs when parsing preset dates
+
+ return parsed_d;
+ }
+
+ Calendar.prototype.calendarCheckDates = function() {
+ var startTxt = $('.dr-date-start', this.element).html();
+ var endTxt = $('.dr-date-end', this.element).html();
+ var c = this.calendarCheckDate($(this.selected).html());
+ var s;
+ var e;
+
+ // Modify strings via some specific keywords to create valid dates
+ // Finally set all strings as dates
+ if (startTxt === 'ytd' || endTxt === 'ytd') { // Year to date
+ s = moment().startOf('year');
+ e = moment().endOf('year');
+ } else {
+ s = this.calendarCheckDate(startTxt);
+ e = this.calendarCheckDate(endTxt);
+ }
+
+ if (c.isBefore(this.earliest_date))
+ c = this.earliest_date;
+ if (s.isBefore(this.earliest_date))
+ s = this.earliest_date;
+ if (e.isBefore(this.earliest_date) || e.isBefore(s))
+ e = s.clone().add(6, 'day');
+
+ if (c.isAfter(this.latest_date))
+ c = this.latest_date;
+ if (e.isAfter(this.latest_date))
+ e = this.latest_date;
+ if (s.isAfter(this.latest_date) || s.isAfter(e))
+ s = e.clone().subtract(6, 'day');
+
+ // Push and save if it's valid otherwise return to previous state
+ if (this.type === 'double') {
+
+ // Is this a valid date?
+ if (s.isSame(e) && !this.sameDayRange)
+ return this.calendarSetDates();
+
+ this.start_date = s.isValid() ? s : this.start_date;
+ this.end_date = e.isValid() ? e : this.end_date;
+ }
+
+ this.current_date = c.isValid() ? c : this.current_date;
+ }
+
+
+ Calendar.prototype.stringToDate = function(str) {
+ var date_arr = str.split(' ');
+
+ if (date_arr[2] === 'ago') {
+ return moment(this.current_date).subtract(date_arr[0], date_arr[1]);
+ }
+
+ else if (date_arr[2] === 'ahead') {
+ return moment(this.current_date).add(date_arr[0], date_arr[1]);
+ }
+
+ return this.current_date;
+ }
+
+
+ Calendar.prototype.calendarOpen = function(selected, switcher) {
+ var self = this;
+ var other;
+ var cal_width = $('.dr-dates', this.element).innerWidth() - 8;
+
+ this.selected = selected || this.selected;
+
+ if (this.presetIsOpen == true)
+ this.presetToggle();
+
+ if (this.calIsOpen == true) {
+ this.calendarClose(switcher ? 'switcher' : undefined);
+ } else if ($(this.selected).html().length) {
+ this.orig_start_date = this.start_date;
+ this.orig_end_date = this.end_date;
+ this.orig_current_date = this.current_date;
+ }
+
+ this.calendarCheckDates();
+ this.calendarCreate(switcher);
+ this.calendarSetDates();
+
+ var next_month = moment(switcher || this.current_date).add(1, 'month').startOf('month').startOf('day');
+ var past_month = moment(switcher || this.current_date).subtract(1, 'month').endOf('month');
+ var next_year = moment(switcher || this.current_date).add(1, 'year').startOf('month').startOf('day');
+ var past_year = moment(switcher || this.current_date).subtract(1, 'year').endOf('month');
+ var this_moment = moment(switcher || this.current_date);
+
+ $('.dr-month-switcher span', this.element)
+ .data('month', this_moment.month())
+ .html(this_moment.format(this.format.jump_month));
+ $('.dr-year-switcher span', this.element)
+ .data('year', this_moment.year())
+ .html(this_moment.format(this.format.jump_year));
+
+ $('.dr-switcher i', this.element).removeClass('dr-disabled');
+
+ if (next_month.isAfter(this.latest_date))
+ $('.dr-month-switcher .dr-right', this.element).addClass('dr-disabled');
+
+ if (past_month.isBefore(this.earliest_date))
+ $('.dr-month-switcher .dr-left', this.element).addClass('dr-disabled');
+
+ if (next_year.isAfter(this.latest_date))
+ $('.dr-year-switcher .dr-right', this.element).addClass('dr-disabled');
+
+ if (past_year.isBefore(this.earliest_date))
+ $('.dr-year-switcher .dr-left', this.element).addClass('dr-disabled');
+
+ $('.dr-day', this.element).on({
+ mouseenter: function() {
+ var selected = $(this);
+ var start_date = moment(self.start_date);
+ var end_date = moment(self.end_date);
+ var current_date = moment(self.current_date);
+
+ if ($(self.selected).hasClass("dr-date-start")) {
+ selected.addClass('dr-hover dr-hover-before');
+ $('.dr-start', self.element).css({'border': 'none', 'padding-left': '0.3125rem'});
+ setMaybeRange('start');
+ }
+
+ if ($(self.selected).hasClass("dr-date-end")) {
+ selected.addClass('dr-hover dr-hover-after');
+ $('.dr-end', self.element).css({'border': 'none', 'padding-right': '0.3125rem'});
+ setMaybeRange('end');
+ }
+
+ if (!self.start_date && !self.end_date)
+ selected.addClass('dr-maybe');
+
+ $('.dr-selected', self.element).css('background-color', 'transparent');
+
+ function setMaybeRange(type) {
+ other = undefined;
+
+ self.range(6 * 7).forEach(function(i) {
+ var next = selected.next().data('date');
+ var prev = selected.prev().data('date');
+ var curr = selected.data('date');
+
+ if (!curr)
+ return false;
+
+ if (!prev)
+ prev = curr;
+
+ if (!next)
+ next = curr;
+
+ if (type == 'start') {
+ if (moment(next).isSame(self.end_date) || (self.sameDayRange && moment(curr).isSame(self.end_date)))
+ return false;
+
+ if (moment(curr).isAfter(self.end_date)) {
+ other = other || moment(curr).add(6, 'day').startOf('day');
+
+ if (i > 5 || (next ? moment(next).isAfter(self.latest_date) : false)) {
+ $(selected).addClass('dr-end');
+ other = moment(curr);
+ return false;
+ }
+ }
+
+ selected = selected.next().addClass('dr-maybe');
+ } else if (type == 'end') {
+ if (moment(prev).isSame(self.start_date) || (self.sameDayRange && moment(curr).isSame(self.start_date)))
+ return false;
+
+ if (moment(curr).isBefore(self.start_date)) {
+ other = other || moment(curr).subtract(6, 'day');
+
+ if (i > 5 || (prev ? moment(prev).isBefore(self.earliest_date) : false)) {
+ $(selected).addClass('dr-start');
+ other = moment(curr);
+ return false;
+ }
+ }
+
+ selected = selected.prev().addClass('dr-maybe');
+ }
+ });
+ }
+ },
+ mouseleave: function() {
+ if ($(this).hasClass('dr-hover-before dr-end'))
+ $(this).removeClass('dr-end');
+
+ if ($(this).hasClass('dr-hover-after dr-start'))
+ $(this).removeClass('dr-start');
+
+ $(this).removeClass('dr-hover dr-hover-before dr-hover-after');
+ $('.dr-start, .dr-end', self.element).css({'border': '', 'padding': ''});
+ $('.dr-maybe:not(.dr-current)', self.element).removeClass('dr-start dr-end');
+ $('.dr-day', self.element).removeClass('dr-maybe');
+ $('.dr-selected', self.element).css('background-color', '');
+ }
+ });
+
+ if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
+ $('.dr-day', this.element).on({
+ touchstart: function() {
+ self.selectOneDate(other, self, $(this).data('date'));
+ }
+ });
+
+ $('div[contenteditable]', this.element).removeAttr('contenteditable');
+ } else {
+ $('.dr-day', this.element).on({
+ mousedown: function () {
+ self.selectOneDate(other, self, $(this).data('date'));
+ }
+ });
+ }
+
+ $('.dr-calendar', this.element)
+ .css('width', cal_width)
+ .slideDown(200);
+ $('.dr-input', this.element).addClass('dr-active');
+ $(selected).addClass('dr-active').focus();
+ this.element.addClass('dr-active');
+
+ this.calIsOpen = true;
+ }
+
+
+ Calendar.prototype.calendarClose = function(type) {
+ var self = this;
+
+ if (!this.calIsOpen || this.presetIsOpen || type == 'force') {
+ $('.dr-calendar', this.element).slideUp(200, function() {
+ $('.dr-day', self.element).remove();
+ });
+ } else {
+ $('.dr-day', this.element).remove();
+ }
+
+ if (type == 'switcher') {
+ return false;
+ }
+
+ $('.dr-input, .dr-date', this.element).removeClass('dr-active');
+ this.element.removeClass('dr-active');
+
+ this.calIsOpen = false;
+ }
+
+
+ Calendar.prototype.calendarCreate = function(switcher) {
+ var self = this;
+ var array = this.calendarArray(this.start_date, this.end_date, this.current_date, switcher);
+
+ array.forEach(function(d, i) {
+ var classString = "dr-day";
+
+ if (d.fade)
+ classString += " dr-fade";
+
+ if (d.start)
+ classString += " dr-start";
+
+ if (d.end)
+ classString += " dr-end";
+
+ if (d.current)
+ classString += " dr-current";
+
+ if (d.selected)
+ classString += " dr-selected";
+
+ if (d.outside)
+ classString += " dr-outside";
+
+ $('.dr-day-list', self.element).append(''+ d.str +' ');
+ });
+ }
+
+
+ Calendar.prototype.calendarArray = function(start, end, current, switcher) {
+ var self = this;
+ current = moment(current || start || end).startOf('day');
+
+ var reference = switcher || current || start || end;
+
+ var startRange = moment(reference).startOf('month').startOf('week');
+ var endRange = moment(startRange).add(6*7 - 1, 'days').endOf('day');
+
+ var daysInRange = [];
+ var d = moment(startRange);
+ while ( d.isBefore(endRange) ) {
+ daysInRange.push( {
+ str: +d.format('D'),
+ start: start && d.isSame(start, 'day'),
+ end: end && d.isSame(end, 'day'),
+ current: current && d.isSame(current, 'day'),
+ selected: start && end && d.isBetween(start, end),
+ date: d.toISOString(),
+ outside: d.isBefore(self.earliest_date) || d.isAfter(self.latest_date),
+ fade: !d.isSame(reference, 'month')
+ } );
+ d.add(1, 'd');
+ }
+
+ return daysInRange;
+ }
+
+
+ Calendar.prototype.calendarHTML = function(type) {
+ var ul_days_of_the_week = $('');
+ var days = this.days_array.splice(moment.localeData().firstDayOfWeek()).concat(this.days_array.splice(0, moment.localeData().firstDayOfWeek()));
+
+ $.each(days, function(i, elem) {
+ ul_days_of_the_week.append('' + elem + ' ');
+ });
+
+ if (type == "double")
+ return this.element.append('' +
+
+ '' +
+ '
' +
+ '
' +
+ '
' +
+ ' ' +
+ 'April ' +
+ ' ' +
+ '
' +
+ '
' +
+ ' ' +
+ '2015 ' +
+ ' ' +
+ '
' +
+ '
' +
+ ul_days_of_the_week[0].outerHTML +
+ '
' +
+ '
' +
+ (this.presets ? this.presetCreate()[0].outerHTML : '') +
+ '
');
+
+ return this.element.append('' +
+
+ '' +
+ '
' +
+ '
' +
+ '
' +
+ ' ' +
+ ' ' +
+ ' ' +
+ '
' +
+ '
' +
+ ' ' +
+ ' ' +
+ ' ' +
+ '
' +
+ '
' +
+ ul_days_of_the_week[0].outerHTML +
+ '
' +
+ '
' +
+ '
');
+ }
+
+
+ Calendar.prototype.parseDate = function(d) {
+ if (moment.defaultZone !== null && moment.hasOwnProperty('tz')) {
+ return moment.tz(d, this.format.input, moment.defaultZone.name);
+ } else {
+ return moment(d, this.format.input);
+ }
+ }
+
+
+ Calendar.prototype.range = function(length) {
+ var range = new Array(length);
+
+ for (var idx = 0; idx < length; idx++) {
+ range[idx] = idx;
+ }
+
+ return range;
+ }
+
+
+ Calendar.prototype.selectOneDate = function(other, cal, date) {
+ var string = moment(date).format(cal.format.input);
+
+ if (other) {
+ $('.dr-date', cal.element)
+ .not(cal.selected)
+ .html(other.format(cal.format.input));
+ }
+
+ $(cal.selected).html(string);
+ cal.calendarOpen(cal.selected);
+
+ if ($(cal.selected).hasClass('dr-date-start')) {
+ $('.dr-date-end', cal.element).trigger('click');
+ } else {
+ cal.calendarSaveDates();
+ cal.calendarClose('force');
+ }
+ }
+
+
+ return Calendar;
+}));
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/Email-Example/sample-image.jpg b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/Email-Example/sample-image.jpg
new file mode 100644
index 0000000..abd4aff
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/Email-Example/sample-image.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ff7f50829671436db61b15966bbf65d35edf52b21fb9ed88aa1d64757889d156
+size 273162
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/Email-Example/umbraco-logo.png b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/Email-Example/umbraco-logo.png
new file mode 100644
index 0000000..584ab69
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/Email-Example/umbraco-logo.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c47661c50db00434216915b2845a28aee86a6429c08e81ea8c1bb8773fad2125
+size 14066
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/aspnet-validation/dist/aspnet-validation.min.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/aspnet-validation/dist/aspnet-validation.min.js
new file mode 100644
index 0000000..e442df5
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/aspnet-validation/dist/aspnet-validation.min.js
@@ -0,0 +1,2 @@
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.aspnetValidation=t():e.aspnetValidation=t()}(window,function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var a=t[n]={i:n,l:!1,exports:{}};return e[n].call(a.exports,a,a.exports,r),a.l=!0,a.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(n,a,function(t){return e[t]}.bind(null,a));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t,r){"use strict";r.r(t),r.d(t,"MvcValidationProviders",function(){return o}),r.d(t,"ValidationService",function(){return s});var n=function(e,t,r,n){return new(r||(r=Promise))(function(a,i){function o(e){try{u(n.next(e))}catch(e){i(e)}}function s(e){try{u(n.throw(e))}catch(e){i(e)}}function u(e){e.done?a(e.value):new r(function(t){t(e.value)}).then(o,s)}u((n=n.apply(e,t||[])).next())})},a=function(e,t){var r,n,a,i,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;o;)try{if(r=1,n&&(a=2&i[0]?n.return:i[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,i[1])).done)return a;switch(n=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,n=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!(a=(a=o.trys).length>0&&a[a.length-1])&&(6===i[0]||2===i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]-1){var a=e.substr(0,n)+"."+r,i=document.getElementsByName(a)[0];if(i)return i}return document.getElementsByName(r)[0]}var o=function(){return function(){this.required=function(e,t,r){return Boolean(e)},this.stringLength=function(e,t,r){if(!e)return!0;if(r.min){var n=parseInt(r.min);if(e.lengtha)return!1}return!0},this.compare=function(e,t,r){if(!r.other)return!0;var n=i(t.name,r.other);return!n||n.value===e},this.range=function(e,t,r){if(!e)return!0;var n=parseFloat(e);return!isNaN(n)&&(!(r.min&&nparseFloat(r.max)))},this.regex=function(e,t,r){return!e||!r.pattern||new RegExp(r.pattern).test(e)},this.email=function(e,t,r){return!e||/^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*(\.\w{2,})+$/.test(e)},this.creditcard=function(e,t,r){if(!e)return!0;if(/[^0-9 \-]+/.test(e))return!1;var n,a,i=0,o=0,s=!1;if((e=e.replace(/\D/g,"")).length<13||e.length>19)return!1;for(n=e.length-1;n>=0;n--)a=e.charAt(n),o=parseInt(a,10),s&&(o*=2)>9&&(o-=9),i+=o,s=!s;return i%10==0},this.url=function(e,t,r){return!e||new RegExp("^(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))\\.?)(?::\\d{2,5})?(?:[/?#]\\S*)?$","i").test(e)},this.phone=function(e,t,r){return!e||!/[\+\-\s][\-\s]/g.test(e)&&/^\+?[0-9\-\s]+$/.test(e)},this.remote=function(e,t,r){if(!e)return!0;for(var n=r.additionalfields.split(","),a={},o=0,s=n;o=200&&n.status<300){var a=JSON.parse(n.responseText);e(a)}else t({status:n.status,statusText:n.statusText,data:n.responseText})},n.onerror=function(e){t({status:n.status,statusText:n.statusText,data:n.responseText})}})}}}(),s=function(){function e(){this.providers={},this.messageFor={},this.elementUIDs=[],this.elementByUID={},this.formInputs={},this.validators={},this.elementEvents={},this.summary={},this.debounce=300}return e.prototype.addProvider=function(e,t){this.providers[e]||(this.providers[e]=t)},e.prototype.addMvcProviders=function(){var e=new o;this.addProvider("required",e.required),this.addProvider("length",e.stringLength),this.addProvider("maxlength",e.stringLength),this.addProvider("minlength",e.stringLength),this.addProvider("equalto",e.compare),this.addProvider("range",e.range),this.addProvider("regex",e.regex),this.addProvider("creditcard",e.creditcard),this.addProvider("email",e.email),this.addProvider("url",e.url),this.addProvider("phone",e.phone),this.addProvider("remote",e.remote)},e.prototype.scanMessages=function(){for(var e=document.querySelectorAll("[data-valmsg-for]"),t=0;t>>0,s=0;sTe(e)?(d=e+1,_-Te(e)):(d=e,_),{year:d,dayOfYear:r}}function Ce(e,a,t){var s,n,d=Ne(e.year(),a,t),r=Math.floor((e.dayOfYear()-d-1)/7)+1;return r<1?s=r+Ie(n=e.year()-1,a,t):r>Ie(e.year(),a,t)?(s=r-Ie(e.year(),a,t),n=e.year()+1):(n=e.year(),s=r),{week:s,year:n}}function Ie(e,a,t){var s=Ne(e,a,t),n=Ne(e+1,a,t);return(Te(e)-s+n)/7}C("w",["ww",2],"wo","week"),C("W",["WW",2],"Wo","isoWeek"),O("week","w"),O("isoWeek","W"),E("week",5),E("isoWeek",5),ie("w",B),ie("ww",B,V),ie("W",B),ie("WW",B,V),Me(["w","ww","W","WW"],function(e,a,t,s){a[s.substr(0,1)]=g(e)});function Ue(e,a){return e.slice(a,7).concat(e.slice(0,a))}C("d",0,"do","day"),C("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),C("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),C("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),C("e",0,0,"weekday"),C("E",0,0,"isoWeekday"),O("day","d"),O("weekday","e"),O("isoWeekday","E"),E("day",11),E("weekday",11),E("isoWeekday",11),ie("d",B),ie("e",B),ie("E",B),ie("dd",function(e,a){return a.weekdaysMinRegex(e)}),ie("ddd",function(e,a){return a.weekdaysShortRegex(e)}),ie("dddd",function(e,a){return a.weekdaysRegex(e)}),Me(["dd","ddd","dddd"],function(e,a,t,s){var n=t._locale.weekdaysParse(e,s,t._strict);null!=n?a.d=n:Y(t).invalidWeekday=e}),Me(["d","e","E"],function(e,a,t,s){a[s]=g(e)});var Ge="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var Ve="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var Ke="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var Ze=re;var $e=re;var Be=re;function qe(){function e(e,a){return a.length-e.length}var a,t,s,n,d,r=[],_=[],i=[],o=[];for(a=0;a<7;a++)t=c([2e3,1]).day(a),s=this.weekdaysMin(t,""),n=this.weekdaysShort(t,""),d=this.weekdays(t,""),r.push(s),_.push(n),i.push(d),o.push(s),o.push(n),o.push(d);for(r.sort(e),_.sort(e),i.sort(e),o.sort(e),a=0;a<7;a++)_[a]=me(_[a]),i[a]=me(i[a]),o[a]=me(o[a]);this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+_.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function Qe(){return this.hours()%12||12}function Xe(e,a){C(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),a)})}function ea(e,a){return a._meridiemParse}C("H",["HH",2],0,"hour"),C("h",["hh",2],0,Qe),C("k",["kk",2],0,function(){return this.hours()||24}),C("hmm",0,0,function(){return""+Qe.apply(this)+F(this.minutes(),2)}),C("hmmss",0,0,function(){return""+Qe.apply(this)+F(this.minutes(),2)+F(this.seconds(),2)}),C("Hmm",0,0,function(){return""+this.hours()+F(this.minutes(),2)}),C("Hmmss",0,0,function(){return""+this.hours()+F(this.minutes(),2)+F(this.seconds(),2)}),Xe("a",!0),Xe("A",!1),O("hour","h"),E("hour",13),ie("a",ea),ie("A",ea),ie("H",B),ie("h",B),ie("k",B),ie("HH",B,V),ie("hh",B,V),ie("kk",B,V),ie("hmm",q),ie("hmmss",Q),ie("Hmm",q),ie("Hmmss",Q),le(["H","HH"],Ye),le(["k","kk"],function(e,a,t){var s=g(e);a[Ye]=24===s?0:s}),le(["a","A"],function(e,a,t){t._isPm=t._locale.isPM(e),t._meridiem=e}),le(["h","hh"],function(e,a,t){a[Ye]=g(e),Y(t).bigHour=!0}),le("hmm",function(e,a,t){var s=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s)),Y(t).bigHour=!0}),le("hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s,2)),a[fe]=g(e.substr(n)),Y(t).bigHour=!0}),le("Hmm",function(e,a,t){var s=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s))}),le("Hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[Ye]=g(e.substr(0,s)),a[ye]=g(e.substr(s,2)),a[fe]=g(e.substr(n))});var aa,ta=Se("Hours",!0),sa={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Oe,monthsShort:Pe,week:{dow:0,doy:6},weekdays:Ge,weekdaysMin:Ke,weekdaysShort:Ve,meridiemParse:/[ap]\.?m?\.?/i},na={},da={};function ra(e){return e?e.toLowerCase().replace("_","-"):e}function _a(e){var a=null;if(!na[e]&&"undefined"!=typeof module&&module&&module.exports)try{a=aa._abbr,require("./locale/"+e),ia(a)}catch(e){}return na[e]}function ia(e,a){var t;return e&&((t=o(a)?ma(e):oa(e,a))?aa=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),aa._abbr}function oa(e,a){if(null===a)return delete na[e],null;var t,s=sa;if(a.abbr=e,null!=na[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=na[e]._config;else if(null!=a.parentLocale)if(null!=na[a.parentLocale])s=na[a.parentLocale]._config;else{if(null==(t=_a(a.parentLocale)))return da[a.parentLocale]||(da[a.parentLocale]=[]),da[a.parentLocale].push({name:e,config:a}),null;s=t._config}return na[e]=new j(b(s,a)),da[e]&&da[e].forEach(function(e){oa(e.name,e.config)}),ia(e),na[e]}function ma(e){var a;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return aa;if(!_(e)){if(a=_a(e))return a;e=[e]}return function(e){for(var a,t,s,n,d=0;d=a&&r(n,t,!0)>=a-1)break;a--}d++}return aa}(e)}function ua(e){var a,t=e._a;return t&&-2===Y(e).overflow&&(a=t[Le]<0||11je(t[he],t[Le])?ce:t[Ye]<0||24Ie(t,d,r)?Y(e)._overflowWeeks=!0:null!=i?Y(e)._overflowWeekday=!0:(_=Re(t,s,n,d,r),e._a[he]=_.year,e._dayOfYear=_.dayOfYear)}(e),null!=e._dayOfYear&&(d=la(e._a[he],s[he]),(e._dayOfYear>Te(d)||0===e._dayOfYear)&&(Y(e)._overflowDayOfYear=!0),t=Je(d,0,e._dayOfYear),e._a[Le]=t.getUTCMonth(),e._a[ce]=t.getUTCDate()),a=0;a<3&&null==e._a[a];++a)e._a[a]=r[a]=s[a];for(;a<7;a++)e._a[a]=r[a]=null==e._a[a]?2===a?1:0:e._a[a];24===e._a[Ye]&&0===e._a[ye]&&0===e._a[fe]&&0===e._a[ke]&&(e._nextDay=!0,e._a[Ye]=0),e._d=(e._useUTC?Je:function(e,a,t,s,n,d,r){var _;return e<100&&0<=e?(_=new Date(e+400,a,t,s,n,d,r),isFinite(_.getFullYear())&&_.setFullYear(e)):_=new Date(e,a,t,s,n,d,r),_}).apply(null,r),n=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[Ye]=24),e._w&&void 0!==e._w.d&&e._w.d!==n&&(Y(e).weekdayMismatch=!0)}}var ha=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,La=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ca=/Z|[+-]\d\d(?::?\d\d)?/,Ya=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],ya=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],fa=/^\/?Date\((\-?\d+)/i;function ka(e){var a,t,s,n,d,r,_=e._i,i=ha.exec(_)||La.exec(_);if(i){for(Y(e).iso=!0,a=0,t=Ya.length;at.valueOf():t.valueOf()this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},Mt.isLocal=function(){return!!this.isValid()&&!this._isUTC},Mt.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},Mt.isUtc=Ra,Mt.isUTC=Ra,Mt.zoneAbbr=function(){return this._isUTC?"UTC":""},Mt.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},Mt.dates=t("dates accessor is deprecated. Use date instead.",_t),Mt.months=t("months accessor is deprecated. Use month instead",Ae),Mt.years=t("years accessor is deprecated. Use year instead",ve),Mt.zone=t("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,a){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,a),this):-this.utcOffset()}),Mt.isDSTShifted=t("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var e={};if(k(e,this),(e=va(e))._a){var a=e._isUTC?c(e._a):Ha(e._a);this._isDSTShifted=this.isValid()&&0 11) {
+ calendar.year += Math.floor(Math.abs(calendar.month)/12);
+ calendar.month -= 12;
+ }
+ return calendar;
+ },
+
+ /**
+ * defaults and localisation
+ */
+ defaults = {
+
+ // bind the picker to a form field
+ field: null,
+
+ // automatically show/hide the picker on `field` focus (default `true` if `field` is set)
+ bound: undefined,
+
+ // data-attribute on the input field with an aria assistance tekst (only applied when `bound` is set)
+ ariaLabel: 'Use the arrow keys to pick a date',
+
+ // position of the datepicker, relative to the field (default to bottom & left)
+ // ('bottom' & 'left' keywords are not used, 'top' & 'right' are modifier on the bottom/left position)
+ position: 'bottom left',
+
+ // automatically fit in the viewport even if it means repositioning from the position option
+ reposition: true,
+
+ // the default output format for `.toString()` and `field` value
+ format: 'YYYY-MM-DD',
+
+ // the toString function which gets passed a current date object and format
+ // and returns a string
+ toString: null,
+
+ // used to create date object from current input string
+ parse: null,
+
+ // the initial date to view when first opened
+ defaultDate: null,
+
+ // make the `defaultDate` the initial selected value
+ setDefaultDate: false,
+
+ // first day of week (0: Sunday, 1: Monday etc)
+ firstDay: 0,
+
+ // the default flag for moment's strict date parsing
+ formatStrict: false,
+
+ // the minimum/earliest date that can be selected
+ minDate: null,
+ // the maximum/latest date that can be selected
+ maxDate: null,
+
+ // number of years either side, or array of upper/lower range
+ yearRange: 10,
+
+ // show week numbers at head of row
+ showWeekNumber: false,
+
+ // Week picker mode
+ pickWholeWeek: false,
+
+ // used internally (don't config outside)
+ minYear: 0,
+ maxYear: 9999,
+ minMonth: undefined,
+ maxMonth: undefined,
+
+ startRange: null,
+ endRange: null,
+
+ isRTL: false,
+
+ // Additional text to append to the year in the calendar title
+ yearSuffix: '',
+
+ // Render the month after year in the calendar title
+ showMonthAfterYear: false,
+
+ // Render days of the calendar grid that fall in the next or previous month
+ showDaysInNextAndPreviousMonths: false,
+
+ // Allows user to select days that fall in the next or previous month
+ enableSelectionDaysInNextAndPreviousMonths: false,
+
+ // how many months are visible
+ numberOfMonths: 1,
+
+ // when numberOfMonths is used, this will help you to choose where the main calendar will be (default `left`, can be set to `right`)
+ // only used for the first display or when a selected date is not visible
+ mainCalendar: 'left',
+
+ // Specify a DOM element to render the calendar in
+ container: undefined,
+
+ // Blur field when date is selected
+ blurFieldOnSelect : true,
+
+ // internationalization
+ i18n: {
+ previousMonth : 'Previous Month',
+ nextMonth : 'Next Month',
+ months : ['January','February','March','April','May','June','July','August','September','October','November','December'],
+ weekdays : ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
+ weekdaysShort : ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
+ },
+
+ // Theme Classname
+ theme: null,
+
+ // events array
+ events: [],
+
+ // callback function
+ onSelect: null,
+ onOpen: null,
+ onClose: null,
+ onDraw: null,
+
+ // Enable keyboard input
+ keyboardInput: true
+ },
+
+
+ /**
+ * templating functions to abstract HTML rendering
+ */
+ renderDayName = function(opts, day, abbr)
+ {
+ day += opts.firstDay;
+ while (day >= 7) {
+ day -= 7;
+ }
+ return abbr ? opts.i18n.weekdaysShort[day] : opts.i18n.weekdays[day];
+ },
+
+ renderDay = function(opts)
+ {
+ var arr = [];
+ var ariaSelected = 'false';
+ if (opts.isEmpty) {
+ if (opts.showDaysInNextAndPreviousMonths) {
+ arr.push('is-outside-current-month');
+
+ if(!opts.enableSelectionDaysInNextAndPreviousMonths) {
+ arr.push('is-selection-disabled');
+ }
+
+ } else {
+ return ' ';
+ }
+ }
+ if (opts.isDisabled) {
+ arr.push('is-disabled');
+ }
+ if (opts.isToday) {
+ arr.push('is-today');
+ }
+ if (opts.isSelected) {
+ arr.push('is-selected');
+ ariaSelected = 'true';
+ }
+ if (opts.hasEvent) {
+ arr.push('has-event');
+ }
+ if (opts.isInRange) {
+ arr.push('is-inrange');
+ }
+ if (opts.isStartRange) {
+ arr.push('is-startrange');
+ }
+ if (opts.isEndRange) {
+ arr.push('is-endrange');
+ }
+ return '' +
+ '' +
+ opts.day +
+ ' ' +
+ ' ';
+ },
+
+ renderWeek = function (d, m, y) {
+ // Lifted from http://javascript.about.com/library/blweekyear.htm, lightly modified.
+ var onejan = new Date(y, 0, 1),
+ weekNum = Math.ceil((((new Date(y, m, d) - onejan) / 86400000) + onejan.getDay()+1)/7);
+ return '' + weekNum + ' ';
+ },
+
+ renderRow = function(days, isRTL, pickWholeWeek, isRowSelected)
+ {
+ return '' + (isRTL ? days.reverse() : days).join('') + ' ';
+ },
+
+ renderBody = function(rows)
+ {
+ return '' + rows.join('') + ' ';
+ },
+
+ renderHead = function(opts)
+ {
+ var i, arr = [];
+ if (opts.showWeekNumber) {
+ arr.push(' ');
+ }
+ for (i = 0; i < 7; i++) {
+ arr.push('' + renderDayName(opts, i, true) + ' ');
+ }
+ return '' + (opts.isRTL ? arr.reverse() : arr).join('') + ' ';
+ },
+
+ renderTitle = function(instance, c, year, month, refYear, randId)
+ {
+ var i, j, arr,
+ opts = instance._o,
+ isMinYear = year === opts.minYear,
+ isMaxYear = year === opts.maxYear,
+ html = '',
+ monthHtml,
+ yearHtml,
+ prev = true,
+ next = true;
+
+ for (arr = [], i = 0; i < 12; i++) {
+ arr.push('
opts.maxMonth) ? 'disabled="disabled"' : '') + '>' +
+ opts.i18n.months[i] + ' ');
+ }
+
+ monthHtml = '
' + opts.i18n.months[month] + '' + arr.join('') + '
';
+
+ if (isArray(opts.yearRange)) {
+ i = opts.yearRange[0];
+ j = opts.yearRange[1] + 1;
+ } else {
+ i = year - opts.yearRange;
+ j = 1 + year + opts.yearRange;
+ }
+
+ for (arr = []; i < j && i <= opts.maxYear; i++) {
+ if (i >= opts.minYear) {
+ arr.push('
' + (i) + ' ');
+ }
+ }
+ yearHtml = '
' + year + opts.yearSuffix + '' + arr.join('') + '
';
+
+ if (opts.showMonthAfterYear) {
+ html += yearHtml + monthHtml;
+ } else {
+ html += monthHtml + yearHtml;
+ }
+
+ if (isMinYear && (month === 0 || opts.minMonth >= month)) {
+ prev = false;
+ }
+
+ if (isMaxYear && (month === 11 || opts.maxMonth <= month)) {
+ next = false;
+ }
+
+ if (c === 0) {
+ html += '
' + opts.i18n.previousMonth + ' ';
+ }
+ if (c === (instance._o.numberOfMonths - 1) ) {
+ html += '
' + opts.i18n.nextMonth + ' ';
+ }
+
+ return html += '
';
+ },
+
+ renderTable = function(opts, data, randId)
+ {
+ return '' + renderHead(opts) + renderBody(data) + '
';
+ },
+
+
+ /**
+ * Pikaday constructor
+ */
+ Pikaday = function(options)
+ {
+ var self = this,
+ opts = self.config(options);
+
+ self._onMouseDown = function(e)
+ {
+ if (!self._v) {
+ return;
+ }
+ e = e || window.event;
+ var target = e.target || e.srcElement;
+ if (!target) {
+ return;
+ }
+
+ if (!hasClass(target, 'is-disabled')) {
+ if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty') && !hasClass(target.parentNode, 'is-disabled')) {
+ self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day')));
+ if (opts.bound) {
+ sto(function() {
+ self.hide();
+ if (opts.blurFieldOnSelect && opts.field) {
+ opts.field.blur();
+ }
+ }, 100);
+ }
+ }
+ else if (hasClass(target, 'pika-prev')) {
+ self.prevMonth();
+ }
+ else if (hasClass(target, 'pika-next')) {
+ self.nextMonth();
+ }
+ }
+ if (!hasClass(target, 'pika-select')) {
+ // if this is touch event prevent mouse events emulation
+ if (e.preventDefault) {
+ e.preventDefault();
+ } else {
+ e.returnValue = false;
+ return false;
+ }
+ } else {
+ self._c = true;
+ }
+ };
+
+ self._onChange = function(e)
+ {
+ e = e || window.event;
+ var target = e.target || e.srcElement;
+ if (!target) {
+ return;
+ }
+ if (hasClass(target, 'pika-select-month')) {
+ self.gotoMonth(target.value);
+ }
+ else if (hasClass(target, 'pika-select-year')) {
+ self.gotoYear(target.value);
+ }
+ };
+
+ self._onKeyChange = function(e)
+ {
+ e = e || window.event;
+
+ if (self.isVisible()) {
+
+ switch(e.keyCode){
+ case 13:
+ case 27:
+ if (opts.field) {
+ opts.field.blur();
+ }
+ break;
+ case 37:
+ e.preventDefault();
+ self.adjustDate('subtract', 1);
+ break;
+ case 38:
+ self.adjustDate('subtract', 7);
+ break;
+ case 39:
+ self.adjustDate('add', 1);
+ break;
+ case 40:
+ self.adjustDate('add', 7);
+ break;
+ }
+ }
+ };
+
+ self._onInputChange = function(e)
+ {
+ var date;
+
+ if (e.firedBy === self) {
+ return;
+ }
+ if (opts.parse) {
+ date = opts.parse(opts.field.value, opts.format);
+ } else if (hasMoment) {
+ date = moment(opts.field.value, opts.format, opts.formatStrict);
+ date = (date && date.isValid()) ? date.toDate() : null;
+ }
+ else {
+ date = new Date(Date.parse(opts.field.value));
+ }
+ if (isDate(date)) {
+ self.setDate(date);
+ }
+ if (!self._v) {
+ self.show();
+ }
+ };
+
+ self._onInputFocus = function()
+ {
+ self.show();
+ };
+
+ self._onInputClick = function()
+ {
+ self.show();
+ };
+
+ self._onInputBlur = function()
+ {
+ // IE allows pika div to gain focus; catch blur the input field
+ var pEl = document.activeElement;
+ do {
+ if (hasClass(pEl, 'pika-single')) {
+ return;
+ }
+ }
+ while ((pEl = pEl.parentNode));
+
+ if (!self._c) {
+ self._b = sto(function() {
+ self.hide();
+ }, 50);
+ }
+ self._c = false;
+ };
+
+ self._onClick = function(e)
+ {
+ e = e || window.event;
+ var target = e.target || e.srcElement,
+ pEl = target;
+ if (!target) {
+ return;
+ }
+ if (!hasEventListeners && hasClass(target, 'pika-select')) {
+ if (!target.onchange) {
+ target.setAttribute('onchange', 'return;');
+ addEvent(target, 'change', self._onChange);
+ }
+ }
+ do {
+ if (hasClass(pEl, 'pika-single') || pEl === opts.trigger) {
+ return;
+ }
+ }
+ while ((pEl = pEl.parentNode));
+ if (self._v && target !== opts.trigger && pEl !== opts.trigger) {
+ self.hide();
+ }
+ };
+
+ self.el = document.createElement('div');
+ self.el.className = 'pika-single' + (opts.isRTL ? ' is-rtl' : '') + (opts.theme ? ' ' + opts.theme : '');
+
+ addEvent(self.el, 'mousedown', self._onMouseDown, true);
+ addEvent(self.el, 'touchend', self._onMouseDown, true);
+ addEvent(self.el, 'change', self._onChange);
+
+ if (opts.keyboardInput) {
+ addEvent(document, 'keydown', self._onKeyChange);
+ }
+
+ if (opts.field) {
+ if (opts.container) {
+ opts.container.appendChild(self.el);
+ } else if (opts.bound) {
+ document.body.appendChild(self.el);
+ } else {
+ opts.field.parentNode.insertBefore(self.el, opts.field.nextSibling);
+ }
+ addEvent(opts.field, 'change', self._onInputChange);
+
+ if (!opts.defaultDate) {
+ if (hasMoment && opts.field.value) {
+ opts.defaultDate = moment(opts.field.value, opts.format).toDate();
+ } else {
+ opts.defaultDate = new Date(Date.parse(opts.field.value));
+ }
+ opts.setDefaultDate = true;
+ }
+ }
+
+ var defDate = opts.defaultDate;
+
+ if (isDate(defDate)) {
+ if (opts.setDefaultDate) {
+ self.setDate(defDate, true);
+ } else {
+ self.gotoDate(defDate);
+ }
+ } else {
+ self.gotoDate(new Date());
+ }
+
+ if (opts.bound) {
+ this.hide();
+ self.el.className += ' is-bound';
+ addEvent(opts.trigger, 'click', self._onInputClick);
+ addEvent(opts.trigger, 'focus', self._onInputFocus);
+ addEvent(opts.trigger, 'blur', self._onInputBlur);
+ } else {
+ this.show();
+ }
+ };
+
+
+ /**
+ * public Pikaday API
+ */
+ Pikaday.prototype = {
+
+
+ /**
+ * configure functionality
+ */
+ config: function(options)
+ {
+ if (!this._o) {
+ this._o = extend({}, defaults, true);
+ }
+
+ var opts = extend(this._o, options, true);
+
+ opts.isRTL = !!opts.isRTL;
+
+ opts.field = (opts.field && opts.field.nodeName) ? opts.field : null;
+
+ opts.theme = (typeof opts.theme) === 'string' && opts.theme ? opts.theme : null;
+
+ opts.bound = !!(opts.bound !== undefined ? opts.field && opts.bound : opts.field);
+
+ opts.trigger = (opts.trigger && opts.trigger.nodeName) ? opts.trigger : opts.field;
+
+ opts.disableWeekends = !!opts.disableWeekends;
+
+ opts.disableDayFn = (typeof opts.disableDayFn) === 'function' ? opts.disableDayFn : null;
+
+ var nom = parseInt(opts.numberOfMonths, 10) || 1;
+ opts.numberOfMonths = nom > 4 ? 4 : nom;
+
+ if (!isDate(opts.minDate)) {
+ opts.minDate = false;
+ }
+ if (!isDate(opts.maxDate)) {
+ opts.maxDate = false;
+ }
+ if ((opts.minDate && opts.maxDate) && opts.maxDate < opts.minDate) {
+ opts.maxDate = opts.minDate = false;
+ }
+ if (opts.minDate) {
+ this.setMinDate(opts.minDate);
+ }
+ if (opts.maxDate) {
+ this.setMaxDate(opts.maxDate);
+ }
+
+ if (isArray(opts.yearRange)) {
+ var fallback = new Date().getFullYear() - 10;
+ opts.yearRange[0] = parseInt(opts.yearRange[0], 10) || fallback;
+ opts.yearRange[1] = parseInt(opts.yearRange[1], 10) || fallback;
+ } else {
+ opts.yearRange = Math.abs(parseInt(opts.yearRange, 10)) || defaults.yearRange;
+ if (opts.yearRange > 100) {
+ opts.yearRange = 100;
+ }
+ }
+
+ return opts;
+ },
+
+ /**
+ * return a formatted string of the current selection (using Moment.js if available)
+ */
+ toString: function(format)
+ {
+ format = format || this._o.format;
+ if (!isDate(this._d)) {
+ return '';
+ }
+ if (this._o.toString) {
+ return this._o.toString(this._d, format);
+ }
+ if (hasMoment) {
+ return moment(this._d).format(format);
+ }
+ return this._d.toDateString();
+ },
+
+ /**
+ * return a Moment.js object of the current selection (if available)
+ */
+ getMoment: function()
+ {
+ return hasMoment ? moment(this._d) : null;
+ },
+
+ /**
+ * set the current selection from a Moment.js object (if available)
+ */
+ setMoment: function(date, preventOnSelect)
+ {
+ if (hasMoment && moment.isMoment(date)) {
+ this.setDate(date.toDate(), preventOnSelect);
+ }
+ },
+
+ /**
+ * return a Date object of the current selection
+ */
+ getDate: function()
+ {
+ return isDate(this._d) ? new Date(this._d.getTime()) : null;
+ },
+
+ /**
+ * set the current selection
+ */
+ setDate: function(date, preventOnSelect)
+ {
+ if (!date) {
+ this._d = null;
+
+ if (this._o.field) {
+ this._o.field.value = '';
+ fireEvent(this._o.field, 'change', { firedBy: this });
+ }
+
+ return this.draw();
+ }
+ if (typeof date === 'string') {
+ date = new Date(Date.parse(date));
+ }
+ if (!isDate(date)) {
+ return;
+ }
+
+ var min = this._o.minDate,
+ max = this._o.maxDate;
+
+ if (isDate(min) && date < min) {
+ date = min;
+ } else if (isDate(max) && date > max) {
+ date = max;
+ }
+
+ this._d = new Date(date.getTime());
+ setToStartOfDay(this._d);
+ this.gotoDate(this._d);
+
+ if (this._o.field) {
+ this._o.field.value = this.toString();
+ fireEvent(this._o.field, 'change', { firedBy: this });
+ }
+ if (!preventOnSelect && typeof this._o.onSelect === 'function') {
+ this._o.onSelect.call(this, this.getDate());
+ }
+ },
+
+ /**
+ * change view to a specific date
+ */
+ gotoDate: function(date)
+ {
+ var newCalendar = true;
+
+ if (!isDate(date)) {
+ return;
+ }
+
+ if (this.calendars) {
+ var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1),
+ lastVisibleDate = new Date(this.calendars[this.calendars.length-1].year, this.calendars[this.calendars.length-1].month, 1),
+ visibleDate = date.getTime();
+ // get the end of the month
+ lastVisibleDate.setMonth(lastVisibleDate.getMonth()+1);
+ lastVisibleDate.setDate(lastVisibleDate.getDate()-1);
+ newCalendar = (visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate);
+ }
+
+ if (newCalendar) {
+ this.calendars = [{
+ month: date.getMonth(),
+ year: date.getFullYear()
+ }];
+ if (this._o.mainCalendar === 'right') {
+ this.calendars[0].month += 1 - this._o.numberOfMonths;
+ }
+ }
+
+ this.adjustCalendars();
+ },
+
+ adjustDate: function(sign, days) {
+
+ var day = this.getDate() || new Date();
+ var difference = parseInt(days)*24*60*60*1000;
+
+ var newDay;
+
+ if (sign === 'add') {
+ newDay = new Date(day.valueOf() + difference);
+ } else if (sign === 'subtract') {
+ newDay = new Date(day.valueOf() - difference);
+ }
+
+ this.setDate(newDay);
+ },
+
+ adjustCalendars: function() {
+ this.calendars[0] = adjustCalendar(this.calendars[0]);
+ for (var c = 1; c < this._o.numberOfMonths; c++) {
+ this.calendars[c] = adjustCalendar({
+ month: this.calendars[0].month + c,
+ year: this.calendars[0].year
+ });
+ }
+ this.draw();
+ },
+
+ gotoToday: function()
+ {
+ this.gotoDate(new Date());
+ },
+
+ /**
+ * change view to a specific month (zero-index, e.g. 0: January)
+ */
+ gotoMonth: function(month)
+ {
+ if (!isNaN(month)) {
+ this.calendars[0].month = parseInt(month, 10);
+ this.adjustCalendars();
+ }
+ },
+
+ nextMonth: function()
+ {
+ this.calendars[0].month++;
+ this.adjustCalendars();
+ },
+
+ prevMonth: function()
+ {
+ this.calendars[0].month--;
+ this.adjustCalendars();
+ },
+
+ /**
+ * change view to a specific full year (e.g. "2012")
+ */
+ gotoYear: function(year)
+ {
+ if (!isNaN(year)) {
+ this.calendars[0].year = parseInt(year, 10);
+ this.adjustCalendars();
+ }
+ },
+
+ /**
+ * change the minDate
+ */
+ setMinDate: function(value)
+ {
+ if(value instanceof Date) {
+ setToStartOfDay(value);
+ this._o.minDate = value;
+ this._o.minYear = value.getFullYear();
+ this._o.minMonth = value.getMonth();
+ } else {
+ this._o.minDate = defaults.minDate;
+ this._o.minYear = defaults.minYear;
+ this._o.minMonth = defaults.minMonth;
+ this._o.startRange = defaults.startRange;
+ }
+
+ this.draw();
+ },
+
+ /**
+ * change the maxDate
+ */
+ setMaxDate: function(value)
+ {
+ if(value instanceof Date) {
+ setToStartOfDay(value);
+ this._o.maxDate = value;
+ this._o.maxYear = value.getFullYear();
+ this._o.maxMonth = value.getMonth();
+ } else {
+ this._o.maxDate = defaults.maxDate;
+ this._o.maxYear = defaults.maxYear;
+ this._o.maxMonth = defaults.maxMonth;
+ this._o.endRange = defaults.endRange;
+ }
+
+ this.draw();
+ },
+
+ setStartRange: function(value)
+ {
+ this._o.startRange = value;
+ },
+
+ setEndRange: function(value)
+ {
+ this._o.endRange = value;
+ },
+
+ /**
+ * refresh the HTML
+ */
+ draw: function(force)
+ {
+ if (!this._v && !force) {
+ return;
+ }
+ var opts = this._o,
+ minYear = opts.minYear,
+ maxYear = opts.maxYear,
+ minMonth = opts.minMonth,
+ maxMonth = opts.maxMonth,
+ html = '',
+ randId;
+
+ if (this._y <= minYear) {
+ this._y = minYear;
+ if (!isNaN(minMonth) && this._m < minMonth) {
+ this._m = minMonth;
+ }
+ }
+ if (this._y >= maxYear) {
+ this._y = maxYear;
+ if (!isNaN(maxMonth) && this._m > maxMonth) {
+ this._m = maxMonth;
+ }
+ }
+
+ randId = 'pika-title-' + Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 2);
+
+ for (var c = 0; c < opts.numberOfMonths; c++) {
+ html += '' + renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId) + '
';
+ }
+
+ this.el.innerHTML = html;
+
+ if (opts.bound) {
+ if(opts.field.type !== 'hidden') {
+ sto(function() {
+ opts.trigger.focus();
+ }, 1);
+ }
+ }
+
+ if (typeof this._o.onDraw === 'function') {
+ this._o.onDraw(this);
+ }
+
+ if (opts.bound) {
+ // let the screen reader user know to use arrow keys
+ opts.field.setAttribute('aria-label', opts.ariaLabel);
+ }
+ },
+
+ adjustPosition: function()
+ {
+ var field, pEl, width, height, viewportWidth, viewportHeight, scrollTop, left, top, clientRect, leftAligned, bottomAligned;
+
+ if (this._o.container) return;
+
+ this.el.style.position = 'absolute';
+
+ field = this._o.trigger;
+ pEl = field;
+ width = this.el.offsetWidth;
+ height = this.el.offsetHeight;
+ viewportWidth = window.innerWidth || document.documentElement.clientWidth;
+ viewportHeight = window.innerHeight || document.documentElement.clientHeight;
+ scrollTop = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
+ leftAligned = true;
+ bottomAligned = true;
+
+ if (typeof field.getBoundingClientRect === 'function') {
+ clientRect = field.getBoundingClientRect();
+ left = clientRect.left + window.pageXOffset;
+ top = clientRect.bottom + window.pageYOffset;
+ } else {
+ left = pEl.offsetLeft;
+ top = pEl.offsetTop + pEl.offsetHeight;
+ while((pEl = pEl.offsetParent)) {
+ left += pEl.offsetLeft;
+ top += pEl.offsetTop;
+ }
+ }
+
+ // default position is bottom & left
+ if ((this._o.reposition && left + width > viewportWidth) ||
+ (
+ this._o.position.indexOf('right') > -1 &&
+ left - width + field.offsetWidth > 0
+ )
+ ) {
+ left = left - width + field.offsetWidth;
+ leftAligned = false;
+ }
+ if ((this._o.reposition && top + height > viewportHeight + scrollTop) ||
+ (
+ this._o.position.indexOf('top') > -1 &&
+ top - height - field.offsetHeight > 0
+ )
+ ) {
+ top = top - height - field.offsetHeight;
+ bottomAligned = false;
+ }
+
+ this.el.style.left = left + 'px';
+ this.el.style.top = top + 'px';
+
+ addClass(this.el, leftAligned ? 'left-aligned' : 'right-aligned');
+ addClass(this.el, bottomAligned ? 'bottom-aligned' : 'top-aligned');
+ removeClass(this.el, !leftAligned ? 'left-aligned' : 'right-aligned');
+ removeClass(this.el, !bottomAligned ? 'bottom-aligned' : 'top-aligned');
+ },
+
+ /**
+ * render HTML for a particular month
+ */
+ render: function(year, month, randId)
+ {
+ var opts = this._o,
+ now = new Date(),
+ days = getDaysInMonth(year, month),
+ before = new Date(year, month, 1).getDay(),
+ data = [],
+ row = [];
+ setToStartOfDay(now);
+ if (opts.firstDay > 0) {
+ before -= opts.firstDay;
+ if (before < 0) {
+ before += 7;
+ }
+ }
+ var previousMonth = month === 0 ? 11 : month - 1,
+ nextMonth = month === 11 ? 0 : month + 1,
+ yearOfPreviousMonth = month === 0 ? year - 1 : year,
+ yearOfNextMonth = month === 11 ? year + 1 : year,
+ daysInPreviousMonth = getDaysInMonth(yearOfPreviousMonth, previousMonth);
+ var cells = days + before,
+ after = cells;
+ while(after > 7) {
+ after -= 7;
+ }
+ cells += 7 - after;
+ var isWeekSelected = false;
+ for (var i = 0, r = 0; i < cells; i++)
+ {
+ var day = new Date(year, month, 1 + (i - before)),
+ isSelected = isDate(this._d) ? compareDates(day, this._d) : false,
+ isToday = compareDates(day, now),
+ hasEvent = opts.events.indexOf(day.toDateString()) !== -1 ? true : false,
+ isEmpty = i < before || i >= (days + before),
+ dayNumber = 1 + (i - before),
+ monthNumber = month,
+ yearNumber = year,
+ isStartRange = opts.startRange && compareDates(opts.startRange, day),
+ isEndRange = opts.endRange && compareDates(opts.endRange, day),
+ isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange,
+ isDisabled = (opts.minDate && day < opts.minDate) ||
+ (opts.maxDate && day > opts.maxDate) ||
+ (opts.disableWeekends && isWeekend(day)) ||
+ (opts.disableDayFn && opts.disableDayFn(day));
+
+ if (isEmpty) {
+ if (i < before) {
+ dayNumber = daysInPreviousMonth + dayNumber;
+ monthNumber = previousMonth;
+ yearNumber = yearOfPreviousMonth;
+ } else {
+ dayNumber = dayNumber - days;
+ monthNumber = nextMonth;
+ yearNumber = yearOfNextMonth;
+ }
+ }
+
+ var dayConfig = {
+ day: dayNumber,
+ month: monthNumber,
+ year: yearNumber,
+ hasEvent: hasEvent,
+ isSelected: isSelected,
+ isToday: isToday,
+ isDisabled: isDisabled,
+ isEmpty: isEmpty,
+ isStartRange: isStartRange,
+ isEndRange: isEndRange,
+ isInRange: isInRange,
+ showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths,
+ enableSelectionDaysInNextAndPreviousMonths: opts.enableSelectionDaysInNextAndPreviousMonths
+ };
+
+ if (opts.pickWholeWeek && isSelected) {
+ isWeekSelected = true;
+ }
+
+ row.push(renderDay(dayConfig));
+
+ if (++r === 7) {
+ if (opts.showWeekNumber) {
+ row.unshift(renderWeek(i - before, month, year));
+ }
+ data.push(renderRow(row, opts.isRTL, opts.pickWholeWeek, isWeekSelected));
+ row = [];
+ r = 0;
+ isWeekSelected = false;
+ }
+ }
+ return renderTable(opts, data, randId);
+ },
+
+ isVisible: function()
+ {
+ return this._v;
+ },
+
+ show: function()
+ {
+ if (!this.isVisible()) {
+ this._v = true;
+ this.draw();
+ removeClass(this.el, 'is-hidden');
+ if (this._o.bound) {
+ addEvent(document, 'click', this._onClick);
+ this.adjustPosition();
+ }
+ if (typeof this._o.onOpen === 'function') {
+ this._o.onOpen.call(this);
+ }
+ }
+ },
+
+ hide: function()
+ {
+ var v = this._v;
+ if (v !== false) {
+ if (this._o.bound) {
+ removeEvent(document, 'click', this._onClick);
+ }
+ this.el.style.position = 'static'; // reset
+ this.el.style.left = 'auto';
+ this.el.style.top = 'auto';
+ addClass(this.el, 'is-hidden');
+ this._v = false;
+ if (v !== undefined && typeof this._o.onClose === 'function') {
+ this._o.onClose.call(this);
+ }
+ }
+ },
+
+ /**
+ * GAME OVER
+ */
+ destroy: function()
+ {
+ var opts = this._o;
+
+ this.hide();
+ removeEvent(this.el, 'mousedown', this._onMouseDown, true);
+ removeEvent(this.el, 'touchend', this._onMouseDown, true);
+ removeEvent(this.el, 'change', this._onChange);
+ if (opts.keyboardInput) {
+ removeEvent(document, 'keydown', this._onKeyChange);
+ }
+ if (opts.field) {
+ removeEvent(opts.field, 'change', this._onInputChange);
+ if (opts.bound) {
+ removeEvent(opts.trigger, 'click', this._onInputClick);
+ removeEvent(opts.trigger, 'focus', this._onInputFocus);
+ removeEvent(opts.trigger, 'blur', this._onInputBlur);
+ }
+ }
+ if (this.el.parentNode) {
+ this.el.parentNode.removeChild(this.el);
+ }
+ }
+
+ };
+
+ return Pikaday;
+}));
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/promise-polyfill/dist/polyfill.min.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/promise-polyfill/dist/polyfill.min.js
new file mode 100644
index 0000000..09fa4d5
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/promise-polyfill/dist/polyfill.min.js
@@ -0,0 +1 @@
+!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n():"function"==typeof define&&define.amd?define(n):n()}(0,function(){"use strict";function e(e){var n=this.constructor;return this.then(function(t){return n.resolve(e()).then(function(){return t})},function(t){return n.resolve(e()).then(function(){return n.reject(t)})})}function n(e){return!(!e||"undefined"==typeof e.length)}function t(){}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=undefined,this._deferreds=[],c(e,this)}function r(e,n){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,o._immediateFn(function(){var t=1===e._state?n.onFulfilled:n.onRejected;if(null!==t){var o;try{o=t(e._value)}catch(r){return void f(n.promise,r)}i(n.promise,o)}else(1===e._state?i:f)(n.promise,e._value)})):e._deferreds.push(n)}function i(e,n){try{if(n===e)throw new TypeError("A promise cannot be resolved with itself.");if(n&&("object"==typeof n||"function"==typeof n)){var t=n.then;if(n instanceof o)return e._state=3,e._value=n,void u(e);if("function"==typeof t)return void c(function(e,n){return function(){e.apply(n,arguments)}}(t,n),e)}e._state=1,e._value=n,u(e)}catch(r){f(e,r)}}function f(e,n){e._state=2,e._value=n,u(e)}function u(e){2===e._state&&0===e._deferreds.length&&o._immediateFn(function(){e._handled||o._unhandledRejectionFn(e._value)});for(var n=0,t=e._deferreds.length;t>n;n++)r(e,e._deferreds[n]);e._deferreds=null}function c(e,n){var t=!1;try{e(function(e){t||(t=!0,i(n,e))},function(e){t||(t=!0,f(n,e))})}catch(o){if(t)return;t=!0,f(n,o)}}var a=setTimeout;o.prototype["catch"]=function(e){return this.then(null,e)},o.prototype.then=function(e,n){var o=new this.constructor(t);return r(this,new function(e,n,t){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof n?n:null,this.promise=t}(e,n,o)),o},o.prototype["finally"]=e,o.all=function(e){return new o(function(t,o){function r(e,n){try{if(n&&("object"==typeof n||"function"==typeof n)){var u=n.then;if("function"==typeof u)return void u.call(n,function(n){r(e,n)},o)}i[e]=n,0==--f&&t(i)}catch(c){o(c)}}if(!n(e))return o(new TypeError("Promise.all accepts an array"));var i=Array.prototype.slice.call(e);if(0===i.length)return t([]);for(var f=i.length,u=0;i.length>u;u++)r(u,i[u])})},o.resolve=function(e){return e&&"object"==typeof e&&e.constructor===o?e:new o(function(n){n(e)})},o.reject=function(e){return new o(function(n,t){t(e)})},o.race=function(e){return new o(function(t,r){if(!n(e))return r(new TypeError("Promise.race accepts an array"));for(var i=0,f=e.length;f>i;i++)o.resolve(e[i]).then(t,r)})},o._immediateFn="function"==typeof setImmediate&&function(e){setImmediate(e)}||function(e){a(e,0)},o._unhandledRejectionFn=function(e){void 0!==console&&console&&console.warn("Possible Unhandled Promise Rejection:",e)};var l=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if("undefined"!=typeof global)return global;throw Error("unable to locate global object")}();"Promise"in l?l.Promise.prototype["finally"]||(l.Promise.prototype["finally"]=e):l.Promise=o});
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/themes/default/style.css b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/themes/default/style.css
new file mode 100644
index 0000000..a37c729
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/themes/default/style.css
@@ -0,0 +1,150 @@
+
+.umbraco-forms-form
+{
+ padding: 10px 0px 10px 0px;
+}
+
+.umbraco-forms-caption
+{
+ font-size: 2em !important;
+ line-height: 2em !important;
+}
+
+.umbraco-forms-field
+{
+ clear: both;
+}
+
+.umbraco-forms-field div label
+{
+ display: inline;
+}
+
+label.umbraco-forms-label
+{
+ font-weight: bold;
+ display: block;
+ background: transparent !important;
+}
+
+.umbraco-forms-form small
+{
+ display: block;
+ float: left;
+ clear: both;
+ padding: 5px 5px 5px 200px;
+}
+
+
+.umbraco-forms-form fieldset
+{
+ padding: 1em 1em 0em 0em;
+ margin: 0 0 1.5em 0;
+ border: none !Important;
+}
+
+.umbraco-forms-form .umbraco-forms-navigation {
+ padding: 1em 0em;
+}
+
+.umbraco-forms-form legend
+{
+ font-weight: bold;
+ font-size: 1.2em;
+ line-height: 1.2em;
+ display: block;
+}
+
+.umbraco-forms-form input.text, .umbraco-forms-form input.title, .umbraco-forms-form textarea,
+.umbraco-forms-form select
+{
+ margin: 0.5em 0;
+ border: 1px solid #bbb;
+}
+.umbraco-forms-form input.text:focus, .umbraco-forms-form input.title:focus,.umbraco-forms-form textarea:focus, .umbraco-forms-form select:focus
+{
+ border: 1px solid #666;
+}
+
+.umbraco-forms-form input.text,.umbraco-forms-form textarea
+{
+ max-width: 400px !important;
+ padding: 5px;
+ display: block;
+ width: 95%;
+}
+
+.umbraco-forms-form textarea
+{
+ height: 250px;
+}
+.umbraco-forms-form input.fileupload
+{
+ height: auto !important;
+}
+
+.umbraco-forms-form span.checkboxlist, .umbraco-forms-form span.radiobuttonlist, .umbraco-forms-form span.checkbox
+{
+ display: block;
+ float: left;
+ padding: 10px;
+}
+
+.umbraco-forms-form .checkboxlist label {
+ float: left;
+ clear: left;
+}
+
+.umbraco-forms-form .checkboxlist input, .umbraco-forms-form .radiobuttonlist input, .umbraco-forms-form .checkbox input
+{
+ width: auto !important;
+ height: auto !important;
+ border: none !important;
+ display: inline !important;
+}
+
+.umbraco-forms-form .hiddenfield
+{
+ display:none;
+}
+
+.umbraco-forms-button
+{
+ margin-right: 10px;
+ padding: 2px 10px;
+}
+.umbraco-forms-error-message
+{
+ padding: .8em;
+ margin-bottom: .5em;
+ border: 2px solid #FBC2C4;
+}
+
+.umbraco-forms-error-message
+{
+ background: #FBE3E4;
+ color: #8a1f11;
+}
+
+.umbraco-forms-form input.contourError, .umbraco-forms-form textarea.contourError,.umbraco-forms-form input.input-validation-error,
+.umbraco-forms-form textarea.input-validation-error
+{
+ background: #FBE3E4;
+ border-color: #FBC2C4;
+}
+
+.umbraco-forms-form span.contourError, .umbraco-forms-form span.field-validation-error
+{
+ color: #8a1f11 !important;
+ background: transparent !important;
+}
+
+.umbraco-forms-form #recaptcha_widget_div
+{
+ margin-left: 200px;
+}
+
+.umbraco-forms-form .field-validation-error
+{
+ padding-left: 5px;
+}
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/themes/default/umbracoforms.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/themes/default/umbracoforms.js
new file mode 100644
index 0000000..47d52e4
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/themes/default/umbracoforms.js
@@ -0,0 +1,567 @@
+(function () {
+
+
+ // polyfill for matches and closest
+ if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector;
+ if (!Element.prototype.closest) Element.prototype.closest = function (selector) {
+ var el = this;
+ while (el) {
+ if (el.matches(selector)) {
+ return el;
+ }
+ el = el.parentElement;
+ }
+ };
+
+
+
+ //execute init() on document ready
+ if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) {
+ listen();
+ } else {
+ document.addEventListener("DOMContentLoaded", listen);
+ }
+
+ function listen() {
+ if (typeof umbracoFormsCollection === "undefined") {
+ //this will occur if this js file is loaded before the inline scripts, in which case
+ //we'll listen for the inline scripts to execute a custom event.
+ document.addEventListener("umbracoFormLoaded", init);
+ }
+ else {
+ initCollection(umbracoFormsCollection);
+ }
+ }
+
+ function initCollection(formsCollection) {
+ configureUmbracoFormsValidation();
+
+ for (var i = 0; i < formsCollection.length; i++) {
+ init({ form: formsCollection[i] });
+ }
+ }
+
+ function init(e) {
+
+ var formItem = JSON.parse(decodeURI(e.form));
+
+ var forms = document.querySelectorAll('.umbraco-forms-form');
+
+ for( var i = 0; i < forms.length; i++) {
+ var form = forms[i];
+
+ dependencyCheck(form);
+
+ var page = form.querySelector('.umbraco-forms-page');
+ var conditions = new UmbracoFormsConditions(page,
+ formItem.fieldSetConditions,
+ formItem.fieldConditions,
+ formItem.recordValues);
+ conditions.watch();
+ };
+ }
+
+ /** Configures the jquery validation for Umbraco forms */
+ function configureUmbracoFormsValidation() {
+
+ if (window.aspnetValidation !== undefined) {
+ // Asp-net validation setup:
+
+ var validationService = new aspnetValidation.ValidationService();
+
+ // TODO: equivilant to this:
+ /*
+ $.validator.setDefaults({
+ ignore: ":hidden"
+ });
+ */
+
+ function required(value, element, params) {
+ // Handle single and multiple checkboxes:
+ if(element.type.toLowerCase() === "checkbox" || element.type.toLowerCase() === "radio") {
+ var allCheckboxesOfThisName = element.form.querySelectorAll("input[name='"+element.name+"']");
+ for (var i=0; i {
+
+ // Wrap all providers with ignorer hidden fields logic:
+ for (var key in validationService.providers) {
+ validationService.providers[key] = wrapProviderWithIgnorerBehaviour(validationService.providers[key]);
+ }
+ });
+
+ // bootstrap validation service.
+ validationService.bootstrap();
+
+ // Without jquery validation, the previous page submit button click isn't sent with it's name,
+ // so can't be used server-side to determine whether to go forward or back.
+ // Hence we'll use an alternate method, setting a hidden field that's also used in the check.
+ var handlePreviousClicked = function () {
+ this.form.elements["PreviousClicked"].value = "clicked";
+ };
+ var previousButtonElements = document.getElementsByClassName("prev cancel");
+ for (var i = 0; i < previousButtonElements.length; i++) {
+ previousButtonElements[i].form.elements["PreviousClicked"].value = "";
+ previousButtonElements[i].addEventListener('click', handlePreviousClicked, false);
+ }
+
+ } else if (typeof jQuery === "function" && $.validator) {
+ //Jquery validation setup
+
+ $.validator.setDefaults({
+ ignore: ":hidden"
+ });
+
+ $.validator.unobtrusive.adapters.addBool("requiredcb", "required");
+
+
+ $.validator.addMethod("umbracoforms_regex", function (value, element) {
+
+ var regex = $(element).attr("data-regex");
+ var val = $(element).val();
+ if (val.length === 0) {
+ return true;
+ }
+ return val.match(regex);
+ });
+
+ $.validator.unobtrusive.adapters.addBool("regex", "umbracoforms_regex");
+
+ var submitInputs = document.querySelectorAll(".umbraco-forms-form input[type=submit]:not(.cancel)");
+ for (var i = 0; i < submitInputs.length; i++) {
+ var input = submitInputs[i];
+ input.addEventListener("click", function (evt) {
+ evt.preventDefault();
+ var frm = $(this).closest("form");
+ frm.validate();
+ if (frm.valid()) {
+ frm.submit();
+ this.setAttribute("disabled", "disabled");
+
+ }
+ }.bind(input));
+ }
+ }
+
+ }
+
+ /**
+ * method to determine if Umbraco Forms can run and has the required dependencies loaded
+ * @param {Form Element} formEl the element of the form
+ */
+ function dependencyCheck(formEl) {
+ // Only perform check if the global 'Umbraco.Sys' is null/undefined.
+ // If present means we are in backoffice & that this is being rendered as a macro preview and We do not need to perform this check here.
+ // Similarly we need a check for if running in a rich text editor.
+ var isBackOffice = function () {
+ return typeof Umbraco !== "undefined" && typeof Umbraco.Sys !== "undefined";
+ };
+ var isBackOfficeRte = function () {
+ return document.body.id === "tinymce";
+ };
+ if (isBackOffice() || isBackOfficeRte()) {
+ return;
+ }
+
+ var errorElement = document.createElement("div");
+ errorElement.className = "umbraco-forms missing-library";
+ errorElement.style.color = "#fff";
+ errorElement.style.backgroundColor = "#9d261d";
+ errorElement.style.padding = "15px";
+ errorElement.style.margin = "10px 0";
+ var errorMessage = "";
+
+ //Ensure umbracoForm is not null
+ if (formEl) {
+
+ //Check to see if the message for the form has been inserted already
+ var checkForExistinhgErr = formEl.getElementsByClassName('umbraco-forms missing-library');
+ if (checkForExistinhgErr.length > 0) {
+ return;
+ }
+
+ var hasValidationFramework = false;
+
+ if (window.jQuery && $ && $.validator !== undefined) {
+ hasValidationFramework = true;
+ } else if (window.aspnetValidation !== undefined) {
+ hasValidationFramework = true;
+ }
+
+ if(hasValidationFramework === false) {
+ errorMessage = errorMessage + "Umbraco Forms requires a validation framework to run, please read documentation for posible options.";
+ }
+
+ if (errorMessage !== "") {
+ errorElement.innerHTML = errorMessage + ' See Umbraco Forms Documentation ';
+
+ formEl.insertBefore(errorElement, formEl.childNodes[0]);
+ }
+ }
+ }
+
+ /**
+ * Class to handle Umbraco Forms conditional statements
+ * @param {any} form a reference to the form
+ * @param {any} fieldsetConditions a reference to the fieldset conditions
+ * @param {any} fieldConditions a reference to the field conditions
+ * @param {any} values the form values
+ * @return {Object} reference to the created class
+ */
+ function UmbracoFormsConditions(form, fieldsetConditions, fieldConditions, values) {
+
+ //our conditions "class" - must always be newed to work as it uses a form instance to operate on
+ //load all the information from the dom and serverside info and then the class will take care of the rest
+
+ var self = {};
+ self.form = form;
+ self.fieldsetConditions = fieldsetConditions;
+ self.fieldConditions = fieldConditions;
+ self.values = values;
+ self.dataTypes = {};
+
+ //Iterates through all the form elements found on the page to update the registered value
+ function populateFieldValues(page, formValues, dataTypes) {
+
+ var selectFields = page.querySelectorAll("select");
+ for(var i=0; i 0;
+ },
+ IsNot: function (value, unexpected, dataType) {
+ if (value == null) {
+ return (unexpected != value);
+ }
+ var values = value.split(';;');
+ var matchingUnexpected = values.filter(
+ function (o) {
+ return o === unexpected;
+ });
+
+ if (dataType === "checkbox") {
+ if (unexpected.toUpperCase() === "TRUE" || unexpected.toUpperCase() === "ON") {
+ unexpected = "true"
+ } else if (unexpected.toUpperCase() === "FALSE" || unexpected.toUpperCase() === "OFF") {
+ unexpected = "false"
+ }
+ }
+ return (value || "") !== unexpected && matchingUnexpected.length === 0;
+ },
+ GreaterThen: function (value, limit, dataType) {
+ return parseInt(value) > parseInt(limit);
+ },
+ LessThen: function (value, limit, dataType) {
+ return parseInt(value) < parseInt(limit);
+ },
+ StartsWith: function (value, criteria, dataType) {
+ return value && value.indexOf(criteria) === 0;
+ },
+ EndsWith: function (value, criteria, dataType) {
+ return value && value.indexOf(criteria) === value.length - criteria.length;
+ },
+ Contains: function (value, criteria, dataType) {
+ return value && value.indexOf(criteria) > -1;
+ }
+ };
+
+ self.watch = function () {
+ // This is a special case for pikaday
+ // The only way around to pickup the value, for now, is to
+ // subscribe to blur events
+ var datepickerfields = self.form.querySelectorAll('.datepickerfield');
+ for(var i = 0; i < datepickerfields.length; i++) {
+ var field = datepickerfields[i];
+ field.addEventListener('blur', function () {
+ if(this.value===""){
+ // Here comes the hack
+ // Force the hidden datepicker field the datepicker field
+ var id = this.getAttribute("id");
+ var hiddenDatePickerField = id.substr(0, id.length-2);
+ self.values[hiddenDatePickerField]="";
+ document.getElementById(hiddenDatePickerField).value="";// sadly we cant use querySelector with current mark-up (would need to prefix IDs)
+ }
+
+ populateFieldValues(self.form, self.values, self.dataTypes);
+ //process the conditions
+ self.run();
+ }.bind(field));
+ }
+ //subscribe to change events
+ var changeablefields = self.form.querySelectorAll("input, textarea, select");
+ for(var i = 0; i < changeablefields.length; i++) {
+ var field = changeablefields[i];
+ field.addEventListener("change", function () {
+ populateFieldValues(self.form, self.values, self.dataTypes);
+ //process the conditions
+ self.run();
+ }.bind(field));
+ }
+
+ //register all values from the current fields on the page
+ populateFieldValues(self.form, self.values, self.dataTypes);
+
+ //the initial run-through of all the conditions
+ self.run();
+ };
+
+ self.run = function () {
+ var fsId,
+ fieldId,
+
+ /*
+ fsConditions = params.fsConditions || {},
+ fieldConditions = params.fieldConditions || {},
+ values = params.values || {},*/
+
+ cachedResults = {};
+
+ function evaluateRuleInstance(rule) {
+ var value = self.values[rule.field],
+ dataType = self.dataTypes[rule.field],
+ func = self.operators[rule.operator],
+ result = value !== null && func(value, rule.value, dataType);
+ return result;
+ }
+
+ function evaluateRule(rule) {
+ var dependencyIsVisible = true;
+
+ if (self.fieldConditions[rule.field]) {
+ dependencyIsVisible = isVisible(rule.field, self.fieldConditions[rule.field]);
+ }
+
+ if (dependencyIsVisible) {
+ return evaluateRuleInstance(rule);
+ }
+ else {
+ return false;
+ }
+ }
+
+ function evaluateCondition(id, condition) {
+ // This was once pretty. Now it needs refactoring again. :)
+
+ var any = condition.logicType === "Any",
+ all = condition.logicType === "All",
+ fieldsetVisibilities = {},
+ hasHiddenFieldset = false,
+ success = true,
+ rule,
+ i;
+
+ for (i = 0; i < condition.rules.length; i++) {
+ rule = condition.rules[i];
+
+ if (id === rule.field || id === rule.fieldsetId) {
+ throw new Error("Field or fieldset " + id + " has a condition on itself.");
+ }
+
+ if (fieldsetVisibilities[rule.fieldsetId] !== undefined) {
+ continue;
+ }
+
+ if (self.fieldsetConditions[rule.fieldsetId]) {
+
+ fieldsetVisibilities[rule.fieldsetId] =
+ isVisible(rule.fieldsetId, self.fieldsetConditions[rule.fieldsetId]);
+
+ if (!fieldsetVisibilities[rule.fieldsetId]) {
+ hasHiddenFieldset = true;
+ }
+ }
+ else {
+ fieldsetVisibilities[rule.fieldsetId] = true;
+ }
+ }
+
+ if (all && hasHiddenFieldset) {
+ return false;
+ }
+
+ for (i = 0; i < condition.rules.length; i++) {
+ rule = condition.rules[i];
+
+ if (fieldsetVisibilities[rule.fieldsetId]) {
+ success = evaluateRule(condition.rules[i]);
+ }
+ else {
+ success = false;
+ }
+
+ if (any && success) {
+ break;
+ }
+ if (all && !success) {
+ break;
+ }
+ }
+ return success;
+ }
+
+ function evaluateConditionVisibility(id, condition) {
+ var show = condition.actionType === "Show",
+ cachedResult = cachedResults[id];
+
+ var success;
+ if (cachedResult === undefined) {
+ cachedResults[id] = show; // set default value to avoid circular issues
+ success = (cachedResults[id] = evaluateCondition(id, condition));
+ } else {
+ success = cachedResult;
+ }
+
+ var visible = !(success ^ show);
+ return visible;
+ }
+
+ function isVisible(id, condition) {
+ if (condition) {
+ return evaluateConditionVisibility(id, condition);
+ }
+ return true;
+ }
+
+ function handleCondition(element, id, condition, type) {
+ var shouldShow = isVisible(id, condition);
+ if (element) {
+ if (shouldShow) {
+ element.style.display = "";
+ }
+ else {
+ element.style.display = "none";
+ }
+ }
+ }
+
+ for (fsId in self.fieldsetConditions) {
+ if (self.fieldsetConditions.hasOwnProperty(fsId)) {
+ handleCondition(document.getElementById(fsId), fsId, self.fieldsetConditions[fsId], "Fieldset");// sadly we cant use querySelector with current mark-up (would need to prefix IDs)
+ }
+ }
+
+ for (fieldId in self.fieldConditions) {
+ if (self.fieldConditions.hasOwnProperty(fieldId)) {
+ if (document.getElementById(fieldId)) {
+ handleCondition(document.getElementById(fieldId).closest(".umbraco-forms-field"),// sadly we cant use querySelector with current mark-up (would need to prefix IDs)
+ fieldId,
+ self.fieldConditions[fieldId],
+ "Field");
+ }
+ }
+ }
+ };
+
+ return self;
+ }
+})();
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/umbracoforms-conditions.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/umbracoforms-conditions.js
new file mode 100644
index 0000000..dd72ec4
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/umbracoforms-conditions.js
@@ -0,0 +1,156 @@
+var umbracoForms = umbracoForms || {};
+(function (uf) {
+ var conditions = uf.conditions || {},
+ operators = conditions.operators || {
+ Is: function (value, expected) {
+ return (value || "") === expected;
+ },
+ IsNot: function (value, unexpected) {
+ return (value || "") !== unexpected;
+ },
+ GreaterThen: function (value, limit) {
+ return parseInt(value) > parseInt(limit);
+ },
+ LessThen: function (value, limit) {
+ return parseInt(value) < parseInt(limit);
+ },
+ StartsWith: function (value, criteria) {
+ return value && value.indexOf(criteria) === 0;
+ },
+ EndsWith: function (value, criteria) {
+ return value && value.indexOf(criteria) === value.length - criteria.length;
+ },
+ Contains: function (value, criteria) {
+ return value && value.indexOf(criteria) > -1;
+ }
+ };
+
+ uf.conditions = conditions;
+ uf.conditions.operators = operators;
+
+ conditions.handle = function (params) {
+ var fsId,
+ fieldId,
+ fsConditions = params.fsConditions || {},
+ fieldConditions = params.fieldConditions || {},
+ values = params.values || {},
+ dataTypes = params.dataTypes || {},
+ cachedResults = {};
+
+ function evaluateRuleInstance(rule) {
+ var value = values[rule.field],
+ dataType = dataTypes[rule.Field],
+ func = operators[rule.operator],
+ result = value !== null && func(value, rule.value, dataType);
+ // console.log(rule.field + ": " + value + " " + rule.operator + " " + rule.value + " = " + result + "\n");
+ return result;
+ }
+
+ function evaluateRule(rule) {
+ var dependencyIsVisible = true;
+
+ if (fieldConditions[rule.field]) {
+ dependencyIsVisible = isVisible(rule.field, fieldConditions[rule.field]);
+ }
+
+ if (dependencyIsVisible) {
+ return evaluateRuleInstance(rule);
+ } else {
+ return false;
+ }
+ }
+
+ function evaluateCondition(id, condition) {
+ // This was once pretty. Now it needs refactoring again. :)
+
+ var any = condition.logicType === "Any",
+ all = condition.logicType === "All",
+ fieldsetVisibilities = {},
+ hasHiddenFieldset = false,
+ success = true,
+ rule,
+ i;
+
+ for (i = 0; i < condition.rules.length; i++) {
+ rule = condition.rules[i];
+
+ if (id === rule.field || id === rule.fieldsetId) {
+ throw new Error("Field or fieldset " + id + " has a condition on itself.");
+ }
+
+ if (fieldsetVisibilities[rule.fieldsetId] !== undefined) {
+ continue;
+ }
+
+ if (fsConditions[rule.fieldsetId]) {
+ fieldsetVisibilities[rule.fieldsetId] = isVisible(rule.fieldsetId, fsConditions[rule.fieldsetId]);
+ if (!fieldsetVisibilities[rule.fieldsetId]) {
+ hasHiddenFieldset = true;
+ }
+ } else {
+ fieldsetVisibilities[rule.fieldsetId] = true;
+ }
+ }
+
+ if (all && hasHiddenFieldset) {
+ return false;
+ }
+
+ for (i = 0; i < condition.rules.length; i++) {
+ rule = condition.rules[i];
+
+ if (fieldsetVisibilities[rule.fieldsetId]) {
+ success = evaluateRule(condition.rules[i]);
+ } else {
+ success = false;
+ }
+
+ if (any && success) {
+ break;
+ }
+ if (all && !success) {
+ break;
+ }
+ }
+ return success;
+ }
+
+ function evaluateConditionVisibility(id, condition) {
+ var show = condition.actionType === "Show",
+ cachedResult = cachedResults[id],
+ success = cachedResult === undefined
+ ? (cachedResults[id] = evaluateCondition(id, condition))
+ : cachedResult,
+ visible = !(success ^ show);
+ return visible;
+ }
+
+ function isVisible(id, condition) {
+ if (condition) {
+ return evaluateConditionVisibility(id, condition);
+ }
+ return true;
+ }
+
+ function handleCondition(element, id, condition, type) {
+ // console.log(type + " " + id);
+ var shouldShow = isVisible(id, condition);
+ if (shouldShow) {
+ // console.log("showing " + id + "\n");
+ element.show();
+ } else {
+ // console.log("hiding " + id + "\n");
+ element.hide();
+ }
+ }
+
+ for (fsId in fsConditions) {
+ handleCondition($("#" + fsId), fsId, fsConditions[fsId], "Fieldset");
+ }
+
+ for (fieldId in fieldConditions) {
+ handleCondition($("#" + fieldId).closest(".contourField"), fieldId, fieldConditions[fieldId], "Field");
+ }
+ }
+
+}(umbracoForms));
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/umbracoforms-dependencies.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/umbracoforms-dependencies.js
new file mode 100644
index 0000000..779cb67
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/umbracoforms-dependencies.js
@@ -0,0 +1,57 @@
+/*
+ Umbraco Forms - Dependencies Checker
+*/
+
+function performDependencyChecks(formId){
+
+ //Only perform check if the global 'Umbraco.Sys' is null/undefined
+ //If present means we are in backoffice & that this is being rendered as a macro preview
+ //We do not need to perform this check here
+ if (typeof Umbraco !== 'undefined' && typeof Umbraco.Sys !== 'undefined'){
+ return;
+ }
+ else {
+ //Check that a Form ID is passed into the function
+ if(formId){
+
+ //Select the wrapping div around the form
+ //umbraco_form_GUID
+ var umbracoForm = document.getElementById('contour_form_' + formId);
+
+ var errorElement = document.createElement('div');
+ errorElement.className='umbraco-forms missing-library';
+ errorElement.style.color = '#fff';
+ errorElement.style.backgroundColor = '#9d261d';
+ errorElement.style.padding = '15px';
+ errorElement.style.margin = '10px 0';
+ var errorMessage = "";
+
+ //Ensure umbracoForm is not null
+ if(umbracoForm) {
+
+ //Check for jQuery
+ if (typeof jQuery == 'undefined') {
+ errorMessage = errorMessage + 'jQuery has not been loaded & is required for Umbraco Forms.';
+ } else {
+ //These only work if jQuery is present, so it's in the else block
+
+ //Check for jQuery Validation
+ if(!$.validator) {
+ errorMessage = errorMessage + ' jQuery Validate has not been loaded & is required for Umbraco Forms.'
+ }
+
+ //Check for jQuery Validation Unobtrusive
+ //Only works if jQuery validator has been loaded
+ if($.validator && !$.validator.unobtrusive) {
+ errorMessage = errorMessage + ' jQuery Validate Unobtrusive has not been loaded & is required for Umbraco Forms.';
+ }
+ }
+ if(errorMessage !== "") {
+ errorElement.innerHTML = errorMessage + ' See Umbraco Forms Documentation ';
+ umbracoForm.insertBefore(errorElement, umbracoForm.childNodes[0]);
+ }
+ }
+ }
+ }
+}
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/umbracoforms.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/umbracoforms.js
new file mode 100644
index 0000000..0027d0f
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Assets/umbracoforms.js
@@ -0,0 +1,36 @@
+(function ($) {
+
+ if ($.validator != undefined) {
+
+ $.validator.setDefaults({
+ ignore: ":hidden"
+ });
+
+ $.validator.unobtrusive.adapters.addBool("requiredcb", "required");
+
+ $.validator.addMethod('umbracoforms_regex', function(value, element) {
+
+ var regex = $(element).attr("data-regex");
+ var val = $(element).val();
+ if (val.length == 0) {
+ return true;
+ }
+ return val.match(regex);
+ });
+
+ $.validator.unobtrusive.adapters.addBool("regex", "umbracoforms_regex");
+
+ $('.contour input[type=submit]').not('.cancel').click(function (evt) {
+ evt.preventDefault();
+ var self = $(this);
+ var frm = self.closest('form');
+ frm.validate();
+ if (frm.valid()) {
+ frm.submit();
+ self.attr('disabled', 'disabled');
+
+ }
+ });
+ }
+} (jQuery));
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/Recaptcha2.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/Recaptcha2.html
new file mode 100644
index 0000000..81f522a
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/Recaptcha2.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/checkbox.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/checkbox.html
new file mode 100644
index 0000000..a68767c
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/checkbox.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/checkboxlist.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/checkboxlist.html
new file mode 100644
index 0000000..18242a6
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/checkboxlist.html
@@ -0,0 +1,12 @@
+
+
+ {{preValue}}
+
+
+
+ {{preValue.value}}
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/dataconsent.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/dataconsent.html
new file mode 100644
index 0000000..8199910
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/dataconsent.html
@@ -0,0 +1,3 @@
+
+ {{ field.settings.AcceptCopy }}
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/datepicker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/datepicker.html
new file mode 100644
index 0000000..b836474
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/datepicker.html
@@ -0,0 +1 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/dropdownlist.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/dropdownlist.html
new file mode 100644
index 0000000..8bf0786
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/dropdownlist.html
@@ -0,0 +1,12 @@
+
+
+ Choose...
+ {{preValue}}
+ {{preValue.value}}
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/fileupload.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/fileupload.html
new file mode 100644
index 0000000..cb75843
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/fileupload.html
@@ -0,0 +1,2 @@
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/hiddenfield.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/hiddenfield.html
new file mode 100644
index 0000000..7c048d0
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/hiddenfield.html
@@ -0,0 +1,3 @@
+
+ {{field.caption}}
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/password.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/password.html
new file mode 100644
index 0000000..9f486d2
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/password.html
@@ -0,0 +1 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/radiobuttonlist.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/radiobuttonlist.html
new file mode 100644
index 0000000..999ca23
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/radiobuttonlist.html
@@ -0,0 +1,12 @@
+
+
+ {{preValue}}
+
+
+
+ {{preValue.value}}
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/recaptcha.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/recaptcha.html
new file mode 100644
index 0000000..d5411e1
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/recaptcha.html
@@ -0,0 +1 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/recaptcha3.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/recaptcha3.html
new file mode 100644
index 0000000..8c5acec
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/recaptcha3.html
@@ -0,0 +1 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/text.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/text.html
new file mode 100644
index 0000000..620589b
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/text.html
@@ -0,0 +1,17 @@
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/textarea.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/textarea.html
new file mode 100644
index 0000000..aa624de
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/textarea.html
@@ -0,0 +1,8 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/textfield.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/textfield.html
new file mode 100644
index 0000000..b5ea8d7
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/FieldTypes/textfield.html
@@ -0,0 +1,6 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/date.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/date.html
new file mode 100644
index 0000000..371c060
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/date.html
@@ -0,0 +1 @@
+{{field | date:'medium'}}
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/file.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/file.html
new file mode 100644
index 0000000..8a768a8
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/file.html
@@ -0,0 +1,15 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/member.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/member.html
new file mode 100644
index 0000000..7422b52
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/member.html
@@ -0,0 +1,14 @@
+
+
No member submitted this record
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/text.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/text.html
new file mode 100644
index 0000000..98f6063
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/RenderTypes/text.html
@@ -0,0 +1 @@
+{{ field }}
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/checkbox.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/checkbox.html
new file mode 100644
index 0000000..de3c24d
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/checkbox.html
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/documentmapper.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/documentmapper.html
new file mode 100644
index 0000000..05f7f5f
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/documentmapper.html
@@ -0,0 +1,59 @@
+
+
+
+ -- choose type --
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/dropdownlist.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/dropdownlist.html
new file mode 100644
index 0000000..c0ac84f
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/dropdownlist.html
@@ -0,0 +1,3 @@
+
+ -- choose --
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/emailtemplatepicker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/emailtemplatepicker.html
new file mode 100644
index 0000000..495fb98
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/emailtemplatepicker.html
@@ -0,0 +1,8 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/fieldmapper.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/fieldmapper.html
new file mode 100644
index 0000000..4e2ed0b
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/fieldmapper.html
@@ -0,0 +1,57 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/file-upload.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/file-upload.html
new file mode 100644
index 0000000..097f4f6
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/file-upload.html
@@ -0,0 +1,18 @@
+
+
+
+
Pick File
+
+
+
+
Uploading: {{vm.filePercentage}}%
+
+
+
+
+ Current File: {{vm.savedPath}}
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/file.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/file.html
new file mode 100644
index 0000000..7b4f0f8
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/file.html
@@ -0,0 +1,5 @@
+
+ {{setting.value}}
+
+
Pick
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/numericfield.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/numericfield.html
new file mode 100644
index 0000000..72fa799
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/numericfield.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/password.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/password.html
new file mode 100644
index 0000000..50091c4
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/password.html
@@ -0,0 +1 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/passwordnoautocomplete.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/passwordnoautocomplete.html
new file mode 100644
index 0000000..9a4d019
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/passwordnoautocomplete.html
@@ -0,0 +1 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.connectionstring.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.connectionstring.html
new file mode 100644
index 0000000..b094e60
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.connectionstring.html
@@ -0,0 +1,5 @@
+
+
+ -- choose connectionstring --
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.content.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.content.html
new file mode 100644
index 0000000..b0e6df9
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.content.html
@@ -0,0 +1,16 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.contentwithxpath.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.contentwithxpath.html
new file mode 100644
index 0000000..a351931
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.contentwithxpath.html
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Show xpath query help
+ Hide xpath query help
+
+
+
+
+ Use Xpath query to set a root node on the tree, either based on a search from the root of the content tree, or by using a context-aware placeholder.
+
+
+
+ Placeholders finds the nearest published ID and runs its query from there. so for instance:
+
+
$parent/newsArticle
+
+ Will try to get the parent if available, but will then fall back to the nearest ancestor and query for all news articles there.
+
+
+
+ Available placeholders:
+
+ $current
: current page or closest found ancestor
+ $parent
: parent page or closest found ancestor
+ $root
: root of the content tree
+ $site
: Ancestor node at level 1
+
+
+
+
+
+
+ Cancel and clear query
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.datatype.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.datatype.html
new file mode 100644
index 0000000..cffd019
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.datatype.html
@@ -0,0 +1,5 @@
+
+
+ -- choose type --
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.documenttype.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.documenttype.html
new file mode 100644
index 0000000..980b10b
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/pickers.documenttype.html
@@ -0,0 +1,6 @@
+
+
+
+ -- choose type --
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/range.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/range.html
new file mode 100644
index 0000000..96ffeb3
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/range.html
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textarea.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textarea.html
new file mode 100644
index 0000000..bee0c24
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textarea.html
@@ -0,0 +1 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textfield.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textfield.html
new file mode 100644
index 0000000..1b67e3c
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textfield.html
@@ -0,0 +1 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textfieldnoautocomplete.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textfieldnoautocomplete.html
new file mode 100644
index 0000000..bc1f45c
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textfieldnoautocomplete.html
@@ -0,0 +1 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textstring.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textstring.html
new file mode 100644
index 0000000..1b18253
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/textstring.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Dashboards/forms.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Dashboards/forms.html
new file mode 100644
index 0000000..14571f3
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Dashboards/forms.html
@@ -0,0 +1,257 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/DataSource/delete.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/DataSource/delete.html
new file mode 100644
index 0000000..c1951d8
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/DataSource/delete.html
@@ -0,0 +1,16 @@
+
+
+ Are you sure you want to delete {{currentNode.name}}?
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/DataSource/dialogs/wizard.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/DataSource/dialogs/wizard.html
new file mode 100644
index 0000000..ff74ef7
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/DataSource/dialogs/wizard.html
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Select fields
+ Fields from the datasource you wish to include in the form.
+
+
+
+
+
+
+
+ Cancel
+ Previous
+ Next
+
+
+
+
+
+
+
+
+
+ Setup foreign keys
+ Select the value column for foreign key fields
+
+
+
+ {{mapping.name}}
+
+
+
+
+
+
+
+
+
+
+ Cancel
+ Previous
+ Next
+
+
+
+
+
+
+
+
+
+ Select type
+ Field type you wish to use for the included fields (or default value)
+
+
+
+
+
+
+
+ Cancel
+ Previous
+ Create
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/DataSource/edit.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/DataSource/edit.html
new file mode 100644
index 0000000..fe130cd
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/DataSource/edit.html
@@ -0,0 +1,81 @@
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/copy.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/copy.html
new file mode 100644
index 0000000..140fc4d
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/copy.html
@@ -0,0 +1,22 @@
+
+
+
+
Copying form '{{ currentNode.name }}'
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/create.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/create.html
new file mode 100644
index 0000000..4d38d27
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/create.html
@@ -0,0 +1,37 @@
+
+
+
+
+
Create a new form
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/delete.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/delete.html
new file mode 100644
index 0000000..d7fa728
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/delete.html
@@ -0,0 +1,26 @@
+
+
+ Are you sure you want to delete {{currentNode.name}}?
+
+
+ Please note this can take lots of time depending on the number of records.
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/additem.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/additem.html
new file mode 100644
index 0000000..8d2a887
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/additem.html
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/entriesdetail.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/entriesdetail.html
new file mode 100644
index 0000000..7e6286c
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/entriesdetail.html
@@ -0,0 +1,47 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/entriessettings.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/entriessettings.html
new file mode 100644
index 0000000..82c23ce
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/entriessettings.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Choose a format to export form records to
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/fieldsetsettings.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/fieldsetsettings.html
new file mode 100644
index 0000000..d389649
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/fieldsetsettings.html
@@ -0,0 +1,72 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/fieldsettings.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/fieldsettings.html
new file mode 100644
index 0000000..19f1313
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/fieldsettings.html
@@ -0,0 +1,146 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/formsettings.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/formsettings.html
new file mode 100644
index 0000000..a4be74e
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/dialogs/formsettings.html
@@ -0,0 +1,129 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/edit.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/edit.html
new file mode 100644
index 0000000..3fcde33
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/edit.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/entries.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/entries.html
new file mode 100644
index 0000000..9c99a9c
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/entries.html
@@ -0,0 +1,302 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/fieldsetsettings/fieldset-settings.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/fieldsetsettings/fieldset-settings.html
new file mode 100644
index 0000000..2ab712d
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/fieldsetsettings/fieldset-settings.html
@@ -0,0 +1,116 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/fieldsettings/field-settings.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/fieldsettings/field-settings.html
new file mode 100644
index 0000000..307a5f4
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/fieldsettings/field-settings.html
@@ -0,0 +1,280 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/fieldtypepicker/field-type-picker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/fieldtypepicker/field-type-picker.html
new file mode 100644
index 0000000..24d124d
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/fieldtypepicker/field-type-picker.html
@@ -0,0 +1,61 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/formpicker/formpicker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/formpicker/formpicker.html
new file mode 100644
index 0000000..477b544
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/formpicker/formpicker.html
@@ -0,0 +1,38 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/themepicker/themepicker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/themepicker/themepicker.html
new file mode 100644
index 0000000..acd95b9
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/themepicker/themepicker.html
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+ No themes available. Add themes to /Views/Partials/Forms/Themes
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/submit-message-workflow-settings.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/submit-message-workflow-settings.html
new file mode 100644
index 0000000..52f3c72
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/submit-message-workflow-settings.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-settings.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-settings.html
new file mode 100644
index 0000000..cce679c
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-settings.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-types.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-types.html
new file mode 100644
index 0000000..1e0eb68
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-types.html
@@ -0,0 +1,58 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflows-overview.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflows-overview.html
new file mode 100644
index 0000000..e6e9f95
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflows-overview.html
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/views/design/design.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/views/design/design.html
new file mode 100644
index 0000000..deec519
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/views/design/design.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/views/settings/settings.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/views/settings/settings.html
new file mode 100644
index 0000000..61ddc8a
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/views/settings/settings.html
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+ 'Submit' button label
+
+
+
+ 'Next' button label
+
+
+
+ 'Previous' button label
+
+
+
+
+
+
+
+ Form CSS class
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/workflows.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/workflows.html
new file mode 100644
index 0000000..c5a1721
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/Form/workflows.html
@@ -0,0 +1,54 @@
+
+
+
+
+
Form workflows
+
+
+
+
+
+
+
Form workflows allow you to add additional functionality to a form, like sending an email, posting to a third party service...
+
When the form is submitted, it should...
+
These actions will execute when the user has filled in the fields and submits the final step of the form.
+
+
+
Add an action
+
+
When form records are approved I want to ...
+
These actions wil execute when the submitted form record is approved. In case your form is set to manual approve these actions will be triggered from the records viewer.
+
+
Add an action
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/FormSecurity/edit.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/FormSecurity/edit.html
new file mode 100644
index 0000000..c1cd09a
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/FormSecurity/edit.html
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form Name
+ Has Access
+
+
+
+
+
+ {{ form.FormName }}
+ {{ form.Fields }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/GridEditors/FormPicker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/GridEditors/FormPicker.html
new file mode 100644
index 0000000..f523e9b
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/GridEditors/FormPicker.html
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PreValueSource/delete.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PreValueSource/delete.html
new file mode 100644
index 0000000..c600f76
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PreValueSource/delete.html
@@ -0,0 +1,16 @@
+
+
+ Are you sure you want to delete {{currentNode.name}}?
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PreValueSource/edit.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PreValueSource/edit.html
new file mode 100644
index 0000000..789ea0f
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PreValueSource/edit.html
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -- choose type --
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Id
+ Value
+
+
+ {{prevalue.id}}
+ {{prevalue.value}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/formpicker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/formpicker.html
new file mode 100644
index 0000000..29f7e7b
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/formpicker.html
@@ -0,0 +1,36 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/formpicker.prevalues.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/formpicker.prevalues.html
new file mode 100644
index 0000000..96f7841
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/formpicker.prevalues.html
@@ -0,0 +1,29 @@
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/themepicker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/themepicker.html
new file mode 100644
index 0000000..437821d
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/themepicker.html
@@ -0,0 +1,28 @@
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Data/Templates/commentform.json b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Data/Templates/commentform.json
new file mode 100644
index 0000000..f7d0768
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Data/Templates/commentform.json
@@ -0,0 +1,108 @@
+{
+ "name": "Comment form",
+ "created": "2014-11-25T10:40:19.605+01:00",
+ "pages": [
+ {
+ "fieldSets": [
+ {
+ "caption": null,
+ "sortOrder": 0,
+ "id": "00000000-0000-0000-0000-000000000000",
+ "page": "00000000-0000-0000-0000-000000000000",
+ "containers": [
+ {
+ "caption": null,
+ "width": 12,
+ "fields": [
+ {
+ "caption": "Name",
+ "tooltip": null,
+ "placeholder": null,
+ "cssClass": null,
+ "alias": "name",
+ "id": "8eb355c3-ad0c-4037-8005-2c102378af24",
+ "fieldTypeId": "3f92e01b-29e2-4a30-bf33-9df5580ed52c",
+ "prevalueSourceId": "00000000-0000-0000-0000-000000000000",
+ "dataSourceFieldKey": null,
+ "mandatory": true,
+ "regex": null,
+ "requiredErrorMessage": null,
+ "invalidErrorMessage": null,
+ "condition": null,
+ "settings": {
+ "DefaultValue": ""
+ },
+ "preValues": []
+ },
+ {
+ "caption": "Email",
+ "tooltip": null,
+ "placeholder": null,
+ "cssClass": null,
+ "alias": "email",
+ "id": "391d2431-5de3-4614-8da0-96f835bddc2a",
+ "fieldTypeId": "3f92e01b-29e2-4a30-bf33-9df5580ed52c",
+ "prevalueSourceId": "00000000-0000-0000-0000-000000000000",
+ "dataSourceFieldKey": null,
+ "mandatory": true,
+ "regex": "^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,4})$",
+ "requiredErrorMessage": null,
+ "invalidErrorMessage": null,
+ "condition": null,
+ "settings": {
+ "DefaultValue": ""
+ },
+ "preValues": []
+ },
+ {
+ "caption": "Comment",
+ "tooltip": null,
+ "placeholder": null,
+ "cssClass": null,
+ "alias": "comment",
+ "id": "7259baad-caa7-46a3-b506-1ced1e749b47",
+ "fieldTypeId": "023f09ac-1445-4bcb-b8fa-ab49f33bd046",
+ "prevalueSourceId": "00000000-0000-0000-0000-000000000000",
+ "dataSourceFieldKey": null,
+ "mandatory": true,
+ "regex": null,
+ "requiredErrorMessage": null,
+ "invalidErrorMessage": null,
+ "condition": null,
+ "settings": {
+ "DefaultValue": ""
+ },
+ "preValues": []
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "caption": "Your comment",
+ "sortOrder": 0,
+ "id": "00000000-0000-0000-0000-000000000000",
+ "form": "00000000-0000-0000-0000-000000000000"
+ }
+ ],
+ "id": "c4d184f7-cd28-47f7-b3f7-c2637f7aa937",
+ "fieldIndicationType": "MarkMandatoryFields",
+ "indicator": "*",
+ "showValidationSummary": false,
+ "hideFieldValidation": false,
+ "requiredErrorMessage": "Please provide a value for {0}",
+ "invalidErrorMessage": "Please provide a valid value for {0}",
+ "messageOnSubmit": "Thank you",
+ "goToPageOnSubmit": 0,
+ "xPathOnSubmit": null,
+ "manualApproval": false,
+ "storeRecordsLocally": true,
+ "cssClass": null,
+ "disableDefaultStylesheet": false,
+ "useClientDependency": false,
+ "workflows": [],
+ "datasource": null,
+ "submitLabel": "Submit",
+ "nextLabel": "Next",
+ "prevLabel": "Previous"
+}
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Data/Templates/contactform.json b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Data/Templates/contactform.json
new file mode 100644
index 0000000..0682d8d
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Data/Templates/contactform.json
@@ -0,0 +1,106 @@
+{
+ "name": "Contact form",
+ "created": "2014-09-26T10:25:42.7504+02:00",
+ "pages": [
+ {
+ "fieldSets": [
+ {
+ "caption": null,
+ "sortOrder": 0,
+ "id": "00000000-0000-0000-0000-000000000000",
+ "page": "00000000-0000-0000-0000-000000000000",
+ "containers": [
+ {
+ "caption": null,
+ "width": 12,
+ "fields": [
+ {
+ "caption": "Name",
+ "tooltip": null,
+ "placeholder": null,
+ "cssClass": null,
+ "alias": "name",
+ "id": "f6718dda-0e45-48f9-bf8f-ecfe8a500a9e",
+ "fieldTypeId": "3f92e01b-29e2-4a30-bf33-9df5580ed52c",
+ "prevalueSourceId": "00000000-0000-0000-0000-000000000000",
+ "dataSourceFieldKey": null,
+ "mandatory": false,
+ "regex": null,
+ "requiredErrorMessage": null,
+ "invalidErrorMessage": null,
+ "condition": null,
+ "settings": {
+ "DefaultValue": ""
+ },
+ "preValues": []
+ },
+ {
+ "caption": "Email",
+ "tooltip": null,
+ "placeholder": null,
+ "cssClass": null,
+ "alias": "email",
+ "id": "c9204231-7756-4e10-cb50-60870fb4bb73",
+ "fieldTypeId": "3f92e01b-29e2-4a30-bf33-9df5580ed52c",
+ "prevalueSourceId": "00000000-0000-0000-0000-000000000000",
+ "dataSourceFieldKey": null,
+ "mandatory": false,
+ "regex": null,
+ "requiredErrorMessage": null,
+ "invalidErrorMessage": null,
+ "condition": null,
+ "settings": {
+ "DefaultValue": ""
+ },
+ "preValues": []
+ },
+ {
+ "caption": "Message",
+ "tooltip": null,
+ "placeholder": null,
+ "cssClass": null,
+ "alias": "message",
+ "id": "d69e4ea5-4957-4b27-f572-cae872e2dc75",
+ "fieldTypeId": "023f09ac-1445-4bcb-b8fa-ab49f33bd046",
+ "prevalueSourceId": "00000000-0000-0000-0000-000000000000",
+ "dataSourceFieldKey": null,
+ "mandatory": false,
+ "regex": null,
+ "requiredErrorMessage": null,
+ "invalidErrorMessage": null,
+ "condition": null,
+ "settings": {
+ "DefaultValue": ""
+ },
+ "preValues": []
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "caption": "Contact Us",
+ "sortOrder": 0,
+ "id": "00000000-0000-0000-0000-000000000000",
+ "form": "00000000-0000-0000-0000-000000000000"
+ }
+ ],
+ "id": "0369af3b-8b18-438b-8b3a-87feedec84ea",
+ "fieldIndicationType": "MarkMandatoryFields",
+ "indicator": "*",
+ "showValidationSummary": false,
+ "hideFieldValidation": false,
+ "requiredErrorMessage": "Please provide a value for {0}",
+ "invalidErrorMessage": "Please provide a valid value for {0}",
+ "messageOnSubmit": "Thank you",
+ "goToPageOnSubmit": 0,
+ "xPathOnSubmit": null,
+ "manualApproval": false,
+ "storeRecordsLocally": true,
+ "disableDefaultStylesheet": false,
+ "workflows": [],
+ "datasource": null,
+ "submitLabel": "Submit",
+ "nextLabel": "Next",
+ "prevLabel": "Prev"
+}
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Data/Web.config b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Data/Web.config
new file mode 100644
index 0000000..fd3add7
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Data/Web.config
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-content-picker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-content-picker.html
new file mode 100644
index 0000000..437e690
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-content-picker.html
@@ -0,0 +1,21 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-designer-new.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-designer-new.html
new file mode 100644
index 0000000..97be8c8
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-designer-new.html
@@ -0,0 +1,325 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-entry-detail.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-entry-detail.html
new file mode 100644
index 0000000..34062cd
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-entry-detail.html
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+ {{ detail.name }}
+
+
+
+ Is sensitive data
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-file-upload-editor.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-file-upload-editor.html
new file mode 100644
index 0000000..1686439
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-file-upload-editor.html
@@ -0,0 +1,38 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-inline-prevalue-editor.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-inline-prevalue-editor.html
new file mode 100644
index 0000000..d9e0f93
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-inline-prevalue-editor.html
@@ -0,0 +1,4 @@
+
+
+ Press enter to add a value
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-prevalue-editor.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-prevalue-editor.html
new file mode 100644
index 0000000..a1e92f8
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-prevalue-editor.html
@@ -0,0 +1,31 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-regexpicker.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-regexpicker.html
new file mode 100644
index 0000000..7674500
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-regexpicker.html
@@ -0,0 +1,19 @@
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-render-type.html b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-render-type.html
new file mode 100644
index 0000000..3762d24
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Directives/umb-forms-render-type.html
@@ -0,0 +1,5 @@
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.eot b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.eot
new file mode 100644
index 0000000..2f4b5cd
Binary files /dev/null and b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.eot differ
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.svg b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.svg
new file mode 100644
index 0000000..140a8df
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.svg
@@ -0,0 +1,26 @@
+
+
+
+Generated by IcoMoon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.ttf b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.ttf
new file mode 100644
index 0000000..4010977
Binary files /dev/null and b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.ttf differ
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.woff b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.woff
new file mode 100644
index 0000000..d9e1562
Binary files /dev/null and b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Fonts/icomoon.woff differ
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/close.png b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/close.png
new file mode 100644
index 0000000..ce418fe
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/close.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3aaf803e2afd7ee691abe81b3adf5f610d81e227f399a39875b22ee53bf561a2
+size 563
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/recaptcha.png b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/recaptcha.png
new file mode 100644
index 0000000..1a837f9
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/recaptcha.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:05366d876a1b1d1cb2ebb01b56658947fd1968ece5b63cc6f784ac2211973e65
+size 23585
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/recaptcha2.png b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/recaptcha2.png
new file mode 100644
index 0000000..8422c93
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/recaptcha2.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:651f500e83ba804edb02615cbe6f59480ebc5ad9f68de7c123d0a1f695e02e5f
+size 3329
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/recaptcha3.png b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/recaptcha3.png
new file mode 100644
index 0000000..037e612
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/recaptcha3.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:68763abcbe6582d8966d21e83858f0a33f4ce082552ce2db28c0e1ec2d4ceaf6
+size 10228
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/succes-green.png b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/succes-green.png
new file mode 100644
index 0000000..e5f41b2
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/succes-green.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a85e94e8c30a45bad90eef08fbe96498d8bdd9788e103c724b03a9ad64e83434
+size 1578
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/workflows/slack/icon.svg b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/workflows/slack/icon.svg
new file mode 100644
index 0000000..df3987a
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Images/workflows/slack/icon.svg
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/RazorTemplates/HtmlTable.cshtml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/RazorTemplates/HtmlTable.cshtml
new file mode 100644
index 0000000..e69de29
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/UmbracoForms.config b/TestSite-V8.7.3/App_Plugins/UmbracoForms/UmbracoForms.config
new file mode 100644
index 0000000..9fa3229
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/UmbracoForms.config
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/DataTables_json.xslt b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/DataTables_json.xslt
new file mode 100644
index 0000000..537f691
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/DataTables_json.xslt
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+ function date2number(s) { return Number(new Date(s)); }
+
+
+
+
+
+ { "iTotalDisplayRecords": " ","iTotalRecords": " ",
+ "formFields" : [
+ "Id","Created","IP","Page Id","Link",
+
+ " ",
+
+ ],
+ "aaData": [
+
+
+
+
+
+ [
+ " ",
+ " ",
+ " ",
+ " ",
+ "<a href=' ' target='_blank'> </a>"
+
+
+
+
+
+
+
+
+
+
+ ,
+
+
+
+
+
+
+
+
+
+
+ ," "
+
+
+
+ ,
+ " ",
+
+
+
+ " ",
+
+
+
+ " "
+
+
+
+
+
+
+
+
+
+ ],
+
+ ]}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/DataTables_json_medtrust.xslt b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/DataTables_json_medtrust.xslt
new file mode 100644
index 0000000..fecdfea
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/DataTables_json_medtrust.xslt
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { "iTotalDisplayRecords": " ","iTotalRecords": " ", "aaData": [
+
+
+
+
+
+ [
+ " ",
+ " ",
+ " ",
+ " ",
+ "<a href=' ' target='_blank'> </a>"
+
+
+
+
+
+
+
+
+
+
+ ,
+
+
+
+
+
+
+
+
+
+
+ ," "
+
+
+ ,
+ " ",
+
+
+
+ " ",
+
+
+
+ " "
+
+
+
+
+
+
+
+
+
+ ],
+
+ ]}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/Html.xslt b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/Html.xslt
new file mode 100644
index 0000000..76214ad
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/Html.xslt
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Export of data from umbraco forms
+
+
+
+
+ Export of data from umbraco forms
+
+
+
+ State
+
+
+ Submitted
+
+
+ Page ID
+
+
+ IP
+
+
+ Member Key
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ,
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/Templates/Schema2/UmbracoContourListComments.xslt b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/Templates/Schema2/UmbracoContourListComments.xslt
new file mode 100644
index 0000000..606a171
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/Templates/Schema2/UmbracoContourListComments.xslt
@@ -0,0 +1,65 @@
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No comments
+
+
+ 1 comment
+
+
+ comments
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Says:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/Templates/UmbracoContourListComments.xslt b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/Templates/UmbracoContourListComments.xslt
new file mode 100644
index 0000000..e08ee63
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/Templates/UmbracoContourListComments.xslt
@@ -0,0 +1,59 @@
+
+ ]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No comments
+
+
+ 1 comment
+
+
+ comments
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/excel.xslt b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/excel.xslt
new file mode 100644
index 0000000..8cb5463
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/excel.xslt
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+ "State","Submitted","PageId","URL","IP","MemberId",
+
+
+
+
+ " "
+
+ ,
+
+
+
+
+
+ " "," / / "," "," "," ","",
+
+
+
+
+
+
+
+
+ " "
+
+
+
+ ,
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/postAsXmlSample.xslt b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/postAsXmlSample.xslt
new file mode 100644
index 0000000..f692ee5
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/postAsXmlSample.xslt
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+ 1
+ new
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/sendXsltEmailSample.xslt b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/sendXsltEmailSample.xslt
new file mode 100644
index 0000000..67ba9cb
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/sendXsltEmailSample.xslt
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+ Intro
+
+ Hello, this is a sample email using xslt to convert a record into a custom email
+
+
+ the fields
+
+
+
+
+ Caption:
+
+
+
+
+
+
+
+
+ The actual xml
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/xml.xslt b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/xml.xslt
new file mode 100644
index 0000000..d3d3e23
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/Xslt/xml.xslt
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/css/umbraco.forms.css b/TestSite-V8.7.3/App_Plugins/UmbracoForms/css/umbraco.forms.css
new file mode 100644
index 0000000..b191b07
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/css/umbraco.forms.css
@@ -0,0 +1,2151 @@
+input.umb-forms__hacky-hidden-field {
+ opacity: 0;
+ cursor: default;
+}
+.control-row.-margin-bottom {
+ margin-bottom: 10px;
+}
+.control-label.-block {
+ display: block;
+}
+.radio.-block {
+ display: block;
+}
+.radio.-no-indent {
+ padding-left: 0;
+}
+.usky-grid .help-text i.icon {
+ font-size: 16px;
+}
+.umb-forms-page {
+ position: relative;
+}
+.umb-forms-designer label.checkbox i.icon {
+ margin-left: -22px;
+}
+select.-full-width {
+ width: 100%;
+ box-sizing: border-box;
+}
+.umb-forms-designer .inline-editor {
+ background: transparent;
+ border: 2px solid transparent;
+ resize: none;
+ overflow: hidden;
+ max-width: 400px;
+ clear: right;
+ display: block;
+}
+.umb-forms-designer .inline-editor.prevalue {
+ display: inline;
+ margin: 0;
+}
+.umb-form-prevalue {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+.umb-form-prevalue small {
+ color: #817f85;
+}
+.umb-forms-designer .inline-editor:hover,
+.umb-forms-designer .inline-editor:focus {
+ border-bottom-color: #413659;
+}
+.umb-forms-designer .inline-editor::-webkit-input-placeholder {
+ color: #a2a1a6;
+}
+.umb-forms-designer .inline-editor.page-name {
+ font-size: 27px;
+ display: block !important;
+ height: 35px;
+ max-width: initial;
+ width: 100%;
+}
+.umb-forms-designer .inline-editor.field-tooltip {
+ color: #a2a1a6;
+ padding: 1px;
+ height: 20px;
+ min-height: 20px;
+ margin: 0;
+ font-size: 13px;
+ color: #d8d7d9;
+}
+.umb-forms-designer .inline-editor.field-name {
+ height: 20px;
+ min-height: 20px;
+ padding: 1px;
+ margin-top: -5px;
+}
+.umb-forms-designer .inline-editor.fieldset-name {
+ font-size: 20px;
+ height: 20px;
+}
+.umb-forms-designer .umb-forms-editor-text .inline-editor {
+ display: block;
+ width: 100%;
+}
+.umb-forms-designer .umb-forms-editor-text {
+ width: 90%;
+}
+.umb-forms-designer .usky-control-inner {
+ min-height: 100px;
+}
+.umb-forms-designer .umb-forms-placeholder {
+ text-align: center;
+ padding: 30px;
+}
+.umb-forms-designer .umb-forms-fields-container {
+ min-height: 1px;
+}
+.umb-forms-designer .row-tools {
+ right: 0;
+ top: 0;
+ bottom: 0;
+ z-index: 200;
+}
+.umb-forms-designer .cell-tools:hover > div {
+ opacity: 1;
+}
+.umb-forms-designer .umb-forms-field-preview {
+ min-height: 90px;
+ margin-right: 40px;
+ border: 1px solid transparent;
+ position: relative;
+ overflow: hidden;
+ padding: 5px;
+}
+.umb-forms-fields .cell-tools-edit {
+ position: absolute;
+ top: 80px;
+ right: 5px;
+}
+.umb-forms-fields .cell-tools-add {
+ margin-right: 45px;
+}
+.umb-forms-fields .cell-tools-add .iconBox {
+ visibility: hidden;
+}
+.umb-forms-fields .cell-tools-add:hover .iconBox {
+ visibility: visible;
+}
+.umb-forms-designer .umb-forms-pager {
+ display: block;
+ padding: 0;
+ margin: 20px 0 0 0;
+}
+.umb-forms-designer .umb-forms-pager a {
+ text-decoration: none;
+ color: #d8d7d9;
+}
+.umb-forms-designer .umb-forms-pager li {
+ display: inline-block;
+ height: 60px;
+ padding: 10px;
+ color: #d8d7d9;
+ overflow: hidden;
+}
+.umb-forms-designer .umb-forms-pager i {
+ font-size: 40px;
+ line-height: 45px;
+ display: block;
+ color: #d8d7d9;
+}
+.umb-forms-designer .umb-forms-pager li.current {
+ background: #f3f3f5;
+}
+.umb-forms-buttons {
+ opacity: 0.9;
+ padding: 15px;
+}
+.umb-forms-designer .umb-forms__page-sort-handle,
+.umb-forms-designer .umb-forms__fieldset-sort-handle,
+.umb-forms-designer .umb-forms__field-sort-handle {
+ margin-right: 10px;
+}
+.umb-forms-designer .umb-forms__field.-collapsed .umb-forms__fieldset-header {
+ padding-left: 10px;
+}
+.umb-forms-designer .umb-forms__field.-collapsed .umb-forms__field-info {
+ padding-top: 8px;
+}
+.umb-forms-designer .umb-forms__field.-collapsed .umb-locked-field__input {
+ margin-right: 4px;
+}
+.umb-forms-designer .umb-forms__field.-collapsed .umb-forms__field-mandatory {
+ display: none;
+}
+.umb-forms-designer .umb-forms__field.-collapsed .umb-group-builder__property-tag {
+ display: none;
+}
+.umb-forms-recaptcha {
+ background: url(../Images/Recaptcha.png) no-repeat top left;
+ height: 70px;
+}
+.umb-forms-hidden {
+ border: 1px dashed #e9e9eb;
+ color: #d8d7d9;
+ padding: 10px;
+ text-align: center;
+}
+.umb-forms-designer .checkbox {
+ padding-left: 0px;
+ font-size: 14px;
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ align-items: center;
+}
+.umb-forms-designer .checkbox input {
+ margin: 0 5px 0 0;
+}
+.umb-forms-designer input[type="file"] {
+ display: flex;
+}
+.show-validation .ng-invalid-val-required-component .forms-question-type {
+ border-color: #fe3e39;
+ color: #fe3e39;
+}
+.umb-forms__member {
+ display: flex;
+ align-items: flex-start;
+}
+.umb-forms__member p {
+ margin: 0;
+}
+.umb-forms__member-edit {
+ margin-top: -25px;
+ margin-left: auto;
+ color: #2e2246;
+ font-size: 14px;
+}
+.umb-forms__member-edit:hover {
+ color: #2e2246;
+ text-decoration: underline;
+}
+.grid-container {
+ display: grid;
+ grid-template-columns: auto auto;
+}
+.label-input {
+ padding-bottom: 2px;
+ vertical-align: text-top;
+ padding-top: 2px;
+}
+.form-search {
+ margin-right: 5px;
+}
+.umb-forms-grid-picker .umb-card-grid .umb-card-grid-item {
+ padding: 20% 4px;
+ height: 80px;
+}
+textarea.-full-width-input {
+ width: 100%;
+ box-sizing: border-box;
+ padding: 4px 6px;
+}
+.entries-table-wrapper {
+ width: 100%;
+ overflow-x: auto;
+ overflow-y: visible;
+ padding-bottom: 1px;
+}
+.entries-table-wrapper table {
+ border: none;
+}
+.entries-table-wrapper td {
+ white-space: nowrap;
+}
+.entries-table-wrapper tr {
+ padding-left: 60px;
+}
+.entries-table-wrapper .header-col {
+ position: absolute !important;
+ width: 35px;
+ top: auto;
+ z-index: 666;
+ border-right: 1px solid #d8d7d9 !important;
+}
+.entries-table-wrapper thead .header-col {
+ background: #f3f3f5;
+}
+.entries-table-wrapper tbody > tr:nth-child(odd) > td {
+ background: #ffffff;
+}
+.umb-forms-rendertype-file .file {
+ text-align: center;
+ text-decoration: none;
+ color: #817f85;
+ padding: 20px;
+}
+.umb-forms-rendertype-file .thumbnail {
+ display: inline-block;
+}
+.umb-forms-rendertype-file .icon {
+ font-size: 80px;
+ line-height: 90px;
+ color: #d8d7d9;
+ display: block;
+}
+.umb-forms-entries-actions .arrow {
+ left: 10%;
+}
+.umb-forms-entries .date-range-filter {
+ padding: 0 5px;
+}
+.umb-forms-entries .date-range-filter span {
+ color: #817f85;
+ font-size: 13px;
+}
+.umb-forms-entries label {
+ display: inline-block;
+ margin-top: 5px;
+ padding-left: 5px;
+}
+.umb-forms-no-entries {
+ margin-top: 60px;
+}
+.-faded {
+ color: #817f85;
+}
+.umb-forms-entry {
+ display: flex;
+ align-items: flex-start;
+}
+.umb-forms-entry-main {
+ flex: 1 1 auto;
+ padding-right: 30px;
+ box-sizing: border-box;
+}
+.umb-forms-entry-main .umb-box {
+ padding: 20px;
+}
+.umb-forms-entry-main .umb-group-builder__property-tag-icon {
+ /* Styles the "sensitive data" indicator which comes through from the field rendering. */
+ display: inline;
+}
+.umb-forms-entry-sidebar {
+ flex: 0 0 300px;
+ box-sizing: border-box;
+}
+.umb-forms-entry-sidebar .umb-box {
+ padding: 20px;
+}
+.umb-forms-entry-sidebar .umb-control-group {
+ padding-bottom: 5px;
+}
+.umb-dashboard-control hr {
+ clear: both;
+}
+.umb-forms-title {
+ margin-top: 30px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+.umb-forms__show-all {
+ height: 28px;
+ padding-top: 5px;
+ margin-left: auto;
+}
+.umb-forms-title .btn {
+ margin-top: 0;
+ padding: 0;
+ font-size: 14px;
+ opacity: .6;
+ font-weight: bold;
+}
+.umb-forms-title .btn:hover {
+ opacity: 1;
+}
+.umb-forms-list {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ margin: 0;
+ padding: 0;
+ margin: -15px 0 0 -15px;
+}
+.umb-forms-form {
+ flex: 0 0 25%;
+ list-style: none;
+ padding: 15px 0 0 15px;
+ box-sizing: border-box;
+ overflow: hidden;
+ display: inline-block;
+ min-width: 0;
+}
+.umb-forms-dashboard .green-link {
+ color: #1fb572;
+ text-decoration: underline;
+}
+.umb-forms-card {
+ background: #ffffff;
+ display: block;
+ transition: all 100ms ease;
+ color: #303033;
+ text-align: center;
+}
+a.umb-forms-card .umb-box:hover {
+ background: #f3f3f5;
+ transition: all 100ms ease;
+ color: #000000;
+}
+.umb-forms-card *,
+.umb-forms-card {
+ text-decoration: none !important;
+}
+.umb-forms-card h4 {
+ font-size: 16px;
+ font-weight: bold;
+ text-overflow: ellipsis;
+ margin: 0;
+}
+.umb-forms-card h4 .icon {
+ padding-right: 5px;
+}
+.umb-forms-card .card-name {
+ white-space: nowrap;
+ overflow: hidden;
+ margin: 0 20px;
+ padding: 20px 0;
+}
+.umb-forms-card .card-body {
+ font-size: 50px;
+ font-weight: 700;
+ line-height: 1.1;
+ text-decoration: none;
+ padding: 0 0 20px;
+}
+.umb-forms-card .card-body small {
+ font-size: 13px;
+ line-height: 12px;
+ display: block;
+}
+.umb-forms-card .card-body .icon {
+ color: #2e2246;
+ font-size: 14px;
+}
+.umb-db-form-action {
+ margin-top: 15px;
+}
+.umb-db-form-action .btn-blue {
+ min-width: 150px;
+}
+.btn.btn-install {
+ margin: 40px auto;
+ display: block;
+ padding: 15px 50px;
+ font-size: 16px;
+ border: none;
+ background: #35c786;
+ color: #ffffff;
+}
+.btn.btn-install:hover {
+ background: #1fb572;
+}
+.btn.btn-blue {
+ padding: 15px 30px;
+ font-size: 14px;
+ border: none;
+ background: #2e8aea;
+ color: #ffffff;
+ text-shadow: none;
+ transition: background 200ms ease;
+}
+.btn.btn-blue:hover {
+ background: #0064cd;
+}
+.btn.btn-tiny {
+ padding: 0;
+ margin-top: 10px;
+ font-size: 12px;
+ color: #817f85;
+ text-align: left;
+}
+.btn.btn-tiny:hover {
+ color: #000000;
+}
+.umb-forms-install-overlay {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ left: 0;
+ background: rgba(255, 255, 255, 0.95);
+ color: #000000;
+ padding: 100px 40px 40px;
+ text-align: center;
+ z-index: 99;
+}
+.umb-forms-install-overlay .succes {
+ background: url('../images/succes-green.png');
+ background-size: 50%;
+ background-position: center;
+ background-repeat: no-repeat;
+ display: block;
+ margin: 0 auto 30px;
+ width: 90px;
+ height: 90px;
+ border: 1px solid #e9e9eb;
+ border-radius: 50%;
+ padding: 10px;
+}
+.umb-forms-install-overlay .close {
+ position: absolute;
+ top: 40px;
+ right: 40px;
+ font-size: 13px;
+ font-weight: 300;
+ cursor: pointer;
+ opacity: .5;
+ transition: all 200 ease;
+}
+.umb-forms-install-overlay .close:before {
+ content: "";
+ display: inline-block;
+ height: 20px;
+ width: 20px;
+ background: url('../images/close.png');
+ background-size: 20px 20px;
+ background-repeat: no-repeat;
+ vertical-align: middle;
+ margin-right: 5px;
+}
+.umb-forms-install-overlay .close:hover {
+ opacity: 1;
+}
+.umb-forms-install-overlay > div h2 {
+ font-size: 42px;
+ margin-bottom: 20px;
+}
+.umb-forms-install-overlay > div p {
+ font-size: 15px;
+ line-height: 1.5;
+ color: #303033;
+}
+.umb-forms-install-overlay > div .divider {
+ width: 1px;
+ height: 60px;
+ padding: 10px 0;
+ margin: 15px auto;
+ background: #d8d7d9;
+}
+.umb-forms-install-overlay > div small {
+ font-size: 13px;
+}
+.umb-forms-install-overlay > div p + small {
+ margin-bottom: 10px;
+ display: inline-block;
+}
+@media (max-width: 1160px) {
+ .umb-forms-form {
+ flex: 0 0 33.33%;
+ }
+}
+@media (max-width: 992px) {
+ .umb-forms-form {
+ flex: 0 0 50%;
+ }
+}
+@media (max-width: 768px) {
+ .umb-forms-form {
+ flex: 0 0 100%;
+ }
+}
+.umb-forms-designer .tb {
+ display: table !important;
+ width: 100%;
+ table-layout: fixed;
+}
+.umb-forms-designer .td {
+ display: table-cell !important;
+}
+.umb-forms-designer .tr {
+ display: table-row !important;
+}
+.mceContentBody {
+ overflow-y: hidden!important;
+}
+IFRAME {
+ overflow: hidden;
+}
+.usky-grid .ui-sortable-helper {
+ border: dashed 1px #000000 !important;
+ background: #d8d7d9;
+ opacity: 0.4;
+ height: 80px !important;
+ width: 160px !important;
+ overflow: hidden;
+ padding: 5px;
+ border-radius: 5px;
+ -webkit-box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
+ -moz-box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
+ box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
+}
+.usky-grid .ui-sortable-helper * {
+ border: none !important;
+ background: none !important;
+ color: #a2a1a6 !important;
+ padding: 0 !important;
+ margin: 0 !important;
+}
+.usky-grid .ui-sortable-helper .cell-tools {
+ display: none !important;
+}
+.usky-grid .ui-sortable-placeholder {
+ border: 2px dashed #d8d7d9;
+ padding: 20px;
+ font-family: icomoon;
+ text-align: center;
+ font-size: 85px;
+ line-height: 65px;
+ color: #f3f3f5;
+ vertical-align: middle;
+}
+.usky-grid .ui-sortable-placeholder:hover {
+ border-color: #817f85;
+}
+.usky-grid .ui-sortable-placeholder:before {
+ content: "\e1bd";
+}
+.usky-grid-width {
+ margin: 20px auto;
+ width: 100%;
+}
+.usky-grid .right {
+ float: right;
+}
+.usky-grid .tb {
+ width: 100%;
+}
+.usky-grid .td {
+ width: 100%;
+ display: inline-block;
+ vertical-align: top;
+ border-right: 1px dashed transparent;
+ box-sizing: border-box;
+}
+.usky-grid .tb:hover .td {
+ border-right: 1px dashed #e9e9eb;
+}
+.usky-grid .td.last {
+ border-right: 1px dashed transparent !important;
+}
+.usky-grid .middle {
+ text-align: center;
+}
+.usky-grid .mainTb {
+ border-collapse: separate;
+}
+.usky-grid .mainTd {
+ position: relative;
+}
+.usky-grid .usky-row {
+ position: relative;
+ border: 1px dashed transparent;
+}
+.usky-grid .tb:hover .usky-row {
+ border-bottom: 1px dashed #e9e9eb;
+}
+.usky-grid .usky-cell {
+ position: relative;
+ border: 1px dashed transparent;
+}
+.usky-grid .cell-tools {
+ transition: all 0.2s ease-in-out;
+ -moz-transition: all 0.2s ease-in-out;
+ -webkit-transition: all 0.2s ease-in-out;
+ position: absolute;
+ bottom: 0;
+ top: 0;
+ right: 0;
+ width: 150px;
+ opacity: 0.3;
+ z-index: 50;
+}
+.usky-grid .cell-tools:hover {
+ opacity: 1;
+}
+.usky-grid .cell-tools-add {
+ position: absolute;
+ text-align: center;
+ bottom: 0px;
+ left: 0;
+ right: 0;
+}
+.usky-grid .usky-control:hover .cell-tools-add {
+ opacity: 1;
+}
+.usky-grid .cell-tools-remove {
+ display: inline-block;
+ position: absolute;
+ top: 0px;
+ right: 5px;
+ text-align: right;
+ z-index: 500;
+}
+.usky-grid .cell-tools-remove .iconBox:hover,
+.usky-grid .cell-tools-remove .iconBox:hover * {
+ background: #fe3e39 !important;
+ border-color: #fe3e39 !important;
+}
+.usky-grid .cell-tools-move {
+ display: inline-block;
+ position: absolute;
+ top: 40px;
+ right: 5px;
+ z-index: 500;
+ cursor: move;
+}
+.usky-grid .cell-tools-edit {
+ position: absolute;
+ top: 80px;
+ right: 5px;
+}
+.usky-grid .usky-control {
+ position: relative;
+ display: block;
+ -webkit-background-clip: padding-box;
+ /* for Safari */
+ background-clip: padding-box;
+ /* for IE9+, Firefox 4+, Opera, Chrome */
+ margin: 10px 0 0 0;
+}
+.usky-grid .warnhighlight {
+ border: 1px dashed #fe3e39 !important;
+}
+.usky-grid .infohighlight {
+ border: 1px dashed #413659 !important;
+}
+.usky-grid .defaulthighlight {
+ border: 1px dashed #d8d7d9 !important;
+}
+.usky-grid .usky-control-inner {
+ min-height: 60px;
+}
+.usky-grid .usky-control-placeholder {
+ min-height: 20px;
+ position: relative;
+ text-align: center;
+ text-align: -moz-center;
+ cursor: text;
+}
+.usky-grid .usky-control-placeholder .placeholder {
+ font-size: 14px;
+ opacity: 0.7;
+ text-align: left;
+ padding: 5px;
+ border: 1px solid #e9e9eb;
+ height: 20px;
+}
+.usky-grid .usky-control-placeholder:hover .placeholder {
+ border: 1px solid #bbbabf;
+}
+.usky-grid .usky-editor-placeholder {
+ min-height: 65px;
+ padding: 20px;
+ padding-bottom: 30px;
+ position: relative;
+ background-color: #ffffff;
+ border: 4px dashed #d8d7d9;
+ text-align: center;
+ text-align: -moz-center;
+}
+.usky-grid .usky-editor-placeholder i {
+ color: #d8d7d9;
+ font-size: 85px;
+ line-height: 85px;
+ display: block;
+ margin-bottom: 10px;
+}
+.usky-grid textarea.textstring {
+ display: block;
+ overflow: hidden;
+ border: none;
+ background: #ffffff;
+ outline: none;
+ resize: none;
+ color: #817f85;
+}
+.usky-grid .usky-cell-rte textarea {
+ display: none !important;
+}
+.usky-grid .usky-cell-media .caption {
+ display: block;
+ overflow: hidden;
+ border: none;
+ background: #ffffff;
+ outline: none;
+ width: 98%;
+ resize: none;
+ font-style: italic;
+}
+.usky-grid .cellPanelRte {
+ min-height: 60px;
+}
+.usky-grid .iconBox {
+ padding: 4px 7px 4px 7px;
+ display: inline-block;
+ cursor: pointer;
+ border-radius: 200px;
+ background: #ffffff;
+ border: 1px solid #bbbabf;
+ margin: 2px;
+}
+.usky-grid .iconBox:hover,
+.usky-grid .iconBox:hover * {
+ background: #413659 !important;
+ color: #ffffff !important;
+ border-color: #413659 !important;
+}
+.usky-grid .iconBox a:hover {
+ text-decoration: none;
+ color: #ffffff !important;
+}
+.usky-grid .iconBox.selected {
+ -webkit-appearance: none;
+ background-image: -moz-linear-gradient(top, #d8d7d9, #bbbabf);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#d8d7d9), to(#bbbabf));
+ background-image: -webkit-linear-gradient(top, #d8d7d9, #bbbabf);
+ background-image: -o-linear-gradient(top, #d8d7d9, #bbbabf);
+ background-image: linear-gradient(to bottom, #d8d7d9, #bbbabf);
+ background-repeat: repeat-x;
+ border-color: #bbbabf #bbbabf #a2a1a6;
+ -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ background: transparent;
+}
+.usky-grid .iconBox i {
+ font-size: 16px !important;
+ color: #515054;
+}
+.usky-grid ul {
+ display: inline-block;
+ list-style: none;
+ padding: 0;
+ margin: 10px 0 0 0;
+ text-align: center;
+}
+.usky-grid .help-text {
+ background: #f3f3f5;
+ color: #817f85;
+ font-size: 14px;
+ padding: 10px 20px 10px 20px;
+ border-radius: 15px;
+ display: inline-block;
+ clear: both;
+}
+.usky-grid ul li {
+ display: inline-block;
+ width: 120px;
+ margin: 8px 8px 0px 8px;
+}
+.usky-grid .mce-panel {
+ border: none !important;
+ clear: both;
+}
+.usky-grid .mce-btn button {
+ padding: 8px 6px;
+ line-height: inherit;
+}
+.usky-grid .mce-toolbar {
+ border: 1px solid #d8d7d9;
+ background-color: #ffffff;
+ z-index: 100;
+ display: inline-block;
+ padding: -1px;
+ position: absolute;
+ margin: -1px -1px 0 -1px;
+ -webkit-box-shadow: 2px 2px 10px 0px rgba(50, 50, 50, 0.14);
+ -moz-box-shadow: 2px 2px 10px 0px rgba(50, 50, 50, 0.14);
+ box-shadow: 2px 2px 10px 0px rgba(50, 50, 50, 0.14);
+ z-index: 9999999;
+}
+.mce-flow-layout-item {
+ margin: 0;
+}
+.usky-grid .mce-panel {
+ background: transparent !important;
+}
+.usky-grid .mce-floatpanel {
+ background-color: #f3f3f5 !important;
+}
+.usky-grid .fullSizeImage {
+ width: 100%;
+}
+/**************************************************************************************************/
+/* Width */
+/**************************************************************************************************/
+.usky-grid .boxWidth {
+ text-align: right;
+ margin-bottom: 10px;
+}
+.usky-grid .boxWidth input {
+ text-align: center;
+ width: 40px;
+}
+.usky-grid .boxWidth label {
+ font-size: 11px;
+ padding: 0;
+ margin: 5px 5px 0 0;
+ color: #817f85;
+}
+/**************************************************************************************************/
+/* Margin control */
+/**************************************************************************************************/
+.usky-grid .usky-cell {
+ padding-bottom: 20px;
+}
+.usky-grid .usky-control {
+ margin: 10px 0 0 0;
+ padding: 5px;
+}
+.usky-grid .usky-templates-columns {
+ margin-top: 30px;
+}
+.usky-grid .usky-row-inner {
+ margin-right: 45px;
+ border: 1px dashed transparent;
+}
+.usky-grid .usky-control-inner {
+ padding: 5px;
+ margin-right: 45px;
+ margin-bottom: 10px;
+ border: 1px dashed transparent;
+}
+/**************************************************************************************************/
+/* template */
+/**************************************************************************************************/
+.usky-grid .uSky-templates {
+ text-align: center;
+ overflow: hidden;
+ width: 100%;
+}
+.usky-grid .uSky-templates-template {
+ display: inline-block;
+ width: 100px;
+ padding-right: 30px;
+ margin: 20px;
+}
+.usky-grid .uSky-templates-template a.tb:hover {
+ border: 5px solid #413659;
+}
+.usky-grid .uSky-templates-template .tb {
+ width: 100%;
+ height: 150px;
+ padding: 10px;
+ background-color: #f3f3f5;
+ border: 5px solid #d8d7d9;
+ cursor: pointer;
+ position: relative;
+}
+.usky-grid .uSky-templates-template .tr {
+ height: 100%;
+ position: relative;
+}
+.usky-grid .uSky-templates-template .tb .uSky-templates-column {
+ height: 100%;
+ border: 1px dashed #d8d7d9;
+ border-right: none;
+}
+.usky-grid .uSky-templates-template .tb .uSky-templates-column.last {
+ border-right: 1px dashed #d8d7d9 !important;
+}
+.usky-grid a.uSky-templates-column:hover,
+.usky-grid a.uSky-templates-column.selected {
+ background-color: #413659;
+}
+/**************************************************************************************************/
+/* template column */
+/**************************************************************************************************/
+.usky-grid .usky-templates-columns .td {
+ border: none !important;
+ vertical-align: middle;
+}
+.usky-grid .usky-templates-columns .td i {
+ color: #817f85;
+ opacity: 0.8;
+}
+.usky-grid .mainTbpt:hover {
+ border-color: #413659;
+}
+.usky-grid .mainTbpt {
+ cursor: pointer;
+ border-collapse: separate;
+ min-height: 35px;
+ border: 2px solid #d8d7d9;
+ margin: 0px;
+ padding: 1px;
+}
+.usky-grid .mainTdpt {
+ padding: 1px;
+}
+.usky-grid .mainTbpt {
+ height: auto;
+}
+.usky-grid .mainTdpt {
+ height: 11px;
+ margin: 0;
+ overflow: hidden;
+ border: 1px dashed #bbbabf;
+ display: block;
+ float: left;
+}
+.mainTdpt span {
+ width: 100%;
+ display: block;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 0 1px;
+ height: 10px;
+ background: #d8d7d9;
+}
+/**************************************************************************************************/
+/* overlay */
+/**************************************************************************************************/
+.usky-grid .cell-tools-menu {
+ position: absolute;
+ width: 360px;
+ height: 380px;
+ overflow: auto;
+ border: 1px solid #d8d7d9;
+ margin-top: -270px;
+ margin-left: -150px;
+ background: #ffffff;
+ padding: 7px;
+ top: 0;
+ left: 50%;
+ z-index: 6660;
+ -webkit-box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
+ -moz-box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
+ box-shadow: 3px 3px 12px 0px rgba(50, 50, 50, 0.45);
+}
+.usky-grid .cell-tools-menu h5 {
+ border-bottom: 1px solid #d8d7d9;
+ color: #a2a1a6;
+ padding: 10px;
+ margin-top: 0;
+}
+.usky-grid .elements {
+ display: block;
+ padding: 0;
+ margin: 0;
+}
+.usky-grid .elements li {
+ display: inline-block;
+ width: 90px;
+ height: 80px;
+ margin: 5px;
+ padding: 5px;
+ overflow: hidden;
+ font-size: 12px;
+}
+.usky-grid .elements li:hover,
+.usky-grid .elements li:hover * {
+ background: #413659;
+ color: #ffffff;
+}
+.usky-grid .elements a {
+ color: #1e1c1c;
+ text-decoration: none;
+}
+.usky-grid .elements i {
+ font-size: 30px;
+ line-height: 50px;
+ color: #a2a1a6;
+ display: block;
+}
+/**************************************************************************************************/
+/* Configuration specific styles */
+/**************************************************************************************************/
+.usky-grid-configuration .uSky-templates {
+ text-align: left;
+}
+.usky-grid-configuration ul {
+ display: block;
+}
+.usky-grid-configuration ul li {
+ display: block;
+ width: auto;
+ text-align: left;
+}
+.usky-grid-configuration .uSky-templates .uSky-templates-template {
+ margin: 0px 20px 20px 0px;
+ width: 80px;
+}
+.usky-grid-configuration .uSky-templates .uSky-templates-template .tb {
+ max-height: 50px;
+ border-width: 2px !important;
+ padding: 0px;
+ border-spacing: 2px;
+ overflow: hidden;
+}
+.usky-grid-configuration .uSky-templates .uSky-templates-template span {
+ background: #d8d7d9;
+ display: inline-block;
+}
+.usky-grid-configuration .uSky-templates .uSky-templates-template .tb:hover {
+ border-width: 2px !important;
+}
+.usky-grid-configuration .uSky-templates-column {
+ display: block;
+ float: left;
+ margin-left: -1px;
+ border: 1px #ffffff solid !important;
+ background: #f3f3f5;
+}
+.usky-grid-configuration .uSky-templates-column.last {
+ margin-right: -1px;
+}
+.usky-grid-configuration .uSky-templates-column.add {
+ text-align: center;
+ font-size: 20px;
+ line-height: 70px;
+ color: #d8d7d9;
+ text-decoration: none;
+ background: #ffffff;
+}
+.usky-grid-configuration .mainTdpt {
+ height: initial;
+ border: none;
+}
+.usky-grid-configuration .uSky-templates-rows .uSky-templates-row {
+ margin: 0px 50px 20px 0px;
+ width: 60px;
+}
+.usky-grid-configuration .uSky-templates-rows .uSky-templates-row .tb {
+ border-width: 2px !important;
+ padding: 0px;
+ border-spacing: 2px;
+}
+.usky-grid-configuration .uSky-templates-rows .mainTdpt {
+ height: 10px !important;
+}
+.usky-grid-configuration a.uSky-templates-column {
+ height: 70px !important;
+}
+.umb-forms__pages {
+ margin-top: -30px;
+}
+.umb-forms__footer {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-bottom: 20px;
+}
+.umb-forms__page {
+ background: #e9e9eb;
+ padding: 20px 15px;
+ margin-top: 30px;
+ margin-bottom: 30px;
+ border-radius: 3px;
+}
+.umb-forms__page-number {
+ width: 23px;
+ height: 23px;
+ line-height: 23px;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: #ffffff;
+ border: 1px solid #bbbabf;
+ margin-right: 5px;
+}
+.umb-forms__page-header {
+ margin-bottom: 15px;
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ align-items: center;
+ font-size: 14px;
+ font-weight: bold;
+}
+.umb-forms__page-footer {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+}
+.umb-forms__page-footer .umb-forms-button {
+ opacity: .5;
+}
+.umb-forms__page-footer .umb-forms-button:hover {
+ opacity: 1;
+}
+input.umb-forms__page-name {
+ border: none;
+ color: #000000;
+ background-color: transparent;
+ margin: 0 0 0 3px;
+ padding: 0;
+}
+input.umb-forms__page-name::-webkit-input-placeholder {
+ color: #68676b;
+ font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+.umb-forms__pagination {
+ opacity: .5;
+}
+.umb-forms__actions {
+ flex: 0 0 40px;
+ text-align: center;
+ margin: 15px 0 0 15px;
+}
+.umb-forms__actions a,
+.umb-forms__actions span {
+ margin: 0 0 10px;
+ display: block;
+ font-size: 18px;
+ position: relative;
+ cursor: pointer;
+}
+.umb-forms__actions a:hover,
+.umb-forms__actions span:hover {
+ color: #413659;
+ text-decoration: none;
+}
+.umb-forms__actions.-page a {
+ position: relative;
+}
+.umb-forms__actions.-fieldset a {
+ color: #000000;
+}
+.umb-forms__page-actions {
+ color: #817f85;
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ margin-left: auto;
+ padding-left: 10px;
+}
+.umb-forms__page-actions a,
+.umb-forms__page-actions span {
+ position: relative;
+ color: #68676b;
+ font-size: 18px;
+ margin-right: 5px;
+ cursor: pointer;
+}
+.umb-forms__page-actions a:hover,
+.umb-forms__page-actions span:hover {
+ color: #413659;
+ text-decoration: none;
+}
+.umb-forms__page-actions.-fieldset a {
+ color: #000000;
+}
+.umb-forms__container {
+ background: #ffffff;
+ position: relative;
+}
+.umb-forms__fieldset {
+ margin-top: 20px;
+ margin-bottom: 20px;
+ min-height: 86px;
+ border: 1px solid transparent;
+ border-radius: 3px;
+ box-sizing: border-box;
+ background-color: #fff;
+ position: relative;
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.16);
+}
+.umb-forms__fieldset.-active {
+ border-color: #413659;
+}
+.umb-forms__fieldset-header {
+ display: flex;
+ align-items: center;
+ border-bottom: 1px solid #e9e9eb;
+ font-size: 14px;
+ padding: 10px;
+}
+.umb-forms__fieldset-info {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+.umb-forms__fieldset-name {
+ border: none;
+ background-color: transparent;
+ color: #000000;
+ font-weight: 700;
+ font-size: 13px;
+ padding: 0;
+}
+.umb-forms__fieldset-name:focus {
+ outline: none;
+}
+.umb-forms__fieldset-name::-webkit-input-placeholder {
+ font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #d9d9d9;
+}
+.umb-forms__fieldset-name::-moz-placeholder {
+ font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ color: #b3afbd;
+}
+.umb-forms__field {
+ display: flex;
+ flex-direction: column;
+ border-bottom: 1px solid #e9e9eb;
+}
+.umb-forms__page-placeholder,
+.umb-forms__fieldset-placeholder,
+.umb-forms__field-placeholder {
+ background: #e9e9eb;
+}
+.umb-forms__field-condition {
+ padding-top: 3px;
+ padding-right: 10px;
+ padding-bottom: 3px;
+ padding-left: 10px;
+ background-color: #f3f3f5;
+ font-size: 13px;
+ font-weight: bold;
+ width: 100%;
+ box-sizing: border-box;
+}
+.umb-forms__field-content {
+ padding-top: 15px;
+ padding-right: 10px;
+ padding-bottom: 15px;
+ padding-left: 10px;
+ display: flex;
+ flex-direction: row;
+ width: 100%;
+ box-sizing: border-box;
+ position: relative;
+}
+.umb-forms__field:last-child {
+ margin-bottom: 0;
+ border-bottom-width: 2px;
+}
+.umb-forms__field-footer {
+ padding: 10px;
+}
+.umb-forms__field.-collapsed {
+ display: flex;
+ align-items: center;
+}
+.umb-forms__field.-collapsed .umb-forms__field-content {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ align-items: center;
+}
+.umb-forms__field.-collapsed .umb-forms__field-name {
+ display: inline-block;
+}
+.umb-forms__field.-collapsed .umb-forms__field-description,
+.umb-forms__field.-collapsed .umb-forms__field-preview,
+.umb-forms__field.-collapsed .umb-forms_field-actions,
+.umb-forms__field.-collapsed .umb-forms__field-condition {
+ display: none;
+}
+.umb-forms__field.-collapsed .umb-forms__field-info,
+.umb-forms__field.-collapsed input,
+.umb-forms__field.-collapsed textarea,
+.umb-forms__field.-collapsed .uneditable-input {
+ width: 100%;
+}
+.umb-forms__field.-collapsed .umb-forms__field-mandatory {
+ transform: translate(-7px, -7px);
+}
+.umb-forms__field.-collapsed:last-child {
+ border-bottom: none;
+}
+.umb-forms__field-mandatory {
+ color: #f02e28;
+ position: absolute;
+ transform: translate(-4px, -4px);
+}
+.umb-forms__field-name,
+.umb-forms__field-description {
+ border: none;
+ background: transparent;
+ resize: none;
+ margin: 0;
+}
+.umb-forms__field-name {
+ font-size: 14px;
+ font-weight: bold;
+}
+.umb-forms__field-description {
+ display: block;
+ font-size: 12px;
+ line-height: 1.5;
+ color: #515054;
+ margin-bottom: 0;
+ width: 100%;
+ min-height: 25px;
+ box-sizing: border-box;
+ resize: none;
+ overflow: hidden;
+ border-color: transparent;
+ background: 0 0;
+}
+.umb-forms__field-info {
+ padding-right: 10px;
+ box-sizing: border-box;
+}
+.umb-forms__field-info.-inline {
+ display: flex;
+ flex-direction: row;
+}
+.umb-forms__field-info.-inline .umb-forms__field-mandatory {
+ margin-right: 3px;
+ margin-left: 0;
+}
+.umb-forms__field-wrapper {
+ flex: 1 1 auto;
+}
+.umb-forms__field-preview {
+ pointer-events: none;
+ flex: 1;
+ overflow: hidden;
+ position: relative;
+ padding: 25px 10px 20px;
+ background-color: #f3f3f5;
+}
+.umb-forms__containers {
+ display: flex;
+ background: #e9e9eb;
+}
+.umb-forms__container {
+ flex: 1 1 100%;
+ margin-left: 1px;
+ margin-right: 1px;
+ border-top: none;
+ display: flex;
+ flex-direction: column;
+}
+.umb-forms__container:first-child {
+ margin-left: 0;
+}
+.umb-forms__container:last-child {
+ margin-right: 0;
+}
+.umb-forms__container:only-child {
+ margin-right: 0;
+ margin-left: 0;
+}
+.umb-forms__fields {
+ flex: 1 1 auto;
+}
+.umb-forms__fields.-empty {
+ min-height: 100px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+}
+.umb-forms__fieldsets.-empty {
+ min-height: 150px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.umb-forms__fieldset-condition {
+ font-size: 12px;
+ color: #ffffff;
+ flex: 0 0 400px;
+ margin-left: 10px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
+.-element-column.umb-forms__field-preview input,
+.-element-column.umb-forms__field-preview textarea {
+ width: auto !important;
+}
+.-element-column .umb-forms__field-content {
+ flex-direction: column;
+}
+.-element-column .umb-forms__actions {
+ position: absolute;
+ top: 20px;
+ right: 10px;
+}
+.-element-column .umb-forms__field-preview {
+ padding-left: 10px;
+ padding-right: 10px;
+}
+.-element-column .umb-forms__field-description {
+ width: 100%;
+}
+.-element-column .-collapsed .umb-forms__field-content {
+ flex-direction: row;
+}
+.umb-forms__columns-template__form {
+ width: 100%;
+ height: 70px;
+ box-sizing: border-box;
+ padding: 2px;
+ border: 2px solid #e9e9eb;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ margin-bottom: 10px;
+}
+.umb-forms__columns-template__column {
+ flex: 1 1 100%;
+ background: #d8d7d9;
+ border: 2px solid #ffffff;
+ display: flex;
+}
+.umb-forms__columns-template__column:hover {
+ background: #413659;
+}
+.umb-forms__columns-template__column:only-child:hover {
+ background: #d8d7d9;
+}
+.umb-forms__columns-template__column:hover .umb-forms__columns-template__remove {
+ display: block;
+}
+.umb-forms__columns-template__remove {
+ display: none;
+ margin-left: auto;
+ color: #ffffff;
+ opacity: .7;
+ margin-right: 3px;
+}
+.umb-forms__columns-template__remove:hover {
+ opacity: 1;
+ color: #ffffff;
+ text-decoration: none;
+}
+@font-face {
+ font-family: 'icomoonforms';
+ src: url('../fonts/icomoon.eot?-6xypwb');
+ src: url('../fonts/icomoon.eot?#iefix-6xypwb') format('embedded-opentype'), url('../fonts/icomoon.woff?-6xypwb') format('woff'), url('../fonts/icomoon.ttf?-6xypwb') format('truetype'), url('../fonts/icomoon.svg?-6xypwb#icomoon') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+[class^="icon-forms"],
+[class*=" icon-forms"] {
+ font-family: 'icomoonforms';
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.icon-forms-table:before {
+ content: "\e600";
+}
+.icon-forms-google-drive:before {
+ content: "\e601";
+}
+.icon-forms-flickr:before {
+ content: "\e602";
+}
+.icon-forms-github:before {
+ content: "\e603";
+}
+.icon-forms-tumblr:before {
+ content: "\e604";
+}
+.icon-forms-stackoverflow:before {
+ content: "\e605";
+}
+.icon-forms-paypal:before {
+ content: "\e606";
+}
+.icon-forms-libreoffice:before {
+ content: "\e607";
+}
+.icon-forms-file-pdf:before {
+ content: "\e608";
+}
+.icon-forms-file-openoffice:before {
+ content: "\e609";
+}
+.icon-forms-file-word:before {
+ content: "\e60a";
+}
+.icon-forms-file-excel:before {
+ content: "\e60b";
+}
+.icon-forms-file-zip:before {
+ content: "\e60c";
+}
+.icon-forms-file-powerpoint:before {
+ content: "\e60d";
+}
+.icon-forms-file-xml:before {
+ content: "\e60e";
+}
+.icon-forms-file-css:before {
+ content: "\e60f";
+}
+.inactive {
+ color: #d8d7d9;
+}
+.umb-forms-workflow-illustration {
+ width: 70px;
+ height: 70px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 2px dashed #d8d7d9;
+ background: #ffffff;
+ font-size: 50px;
+ margin-left: auto;
+ margin-right: auto;
+ margin-bottom: 40px;
+ color: #d8d7d9;
+}
+.umb-forms-workflows {
+ margin-top: 20px;
+ position: relative;
+}
+.umb-forms-workflows__line {
+ width: 2px;
+ background-color: #e9e9eb;
+ position: absolute;
+ top: 15px;
+ bottom: 0;
+ left: 28px;
+}
+.umb-forms-workflows__sortable-wrapper {
+ min-height: 10px;
+}
+.umb-forms-workflow-start {
+ font-size: 16px;
+ font-weight: bold;
+ color: #d8d7d9;
+ margin-bottom: 20px;
+ margin-left: 73px;
+}
+.umb-forms-add-workflow {
+ font-weight: bold;
+ font-size: 14px;
+ color: #2e2246;
+}
+.umb-forms-workflow.-add-new:hover .umb-forms-add-workflow {
+ color: #2e2246;
+ text-decoration: none;
+}
+.umb-forms-workflow {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ margin-bottom: 15px;
+ padding: 5px 10px;
+ position: relative;
+ z-index: 1;
+ box-sizing: border-box;
+}
+.umb-forms-workflow:hover {
+ cursor: pointer;
+ background: #f3f3f5;
+}
+.umb-forms-workflow:hover .umb-forms-workflow__icon-wrapper {
+ border-color: #413659;
+}
+.umb-forms-workflow.-not-clickable:hover {
+ cursor: auto;
+ background: transparent;
+}
+.umb-forms-workflow.-not-clickable:hover .umb-forms-workflow__icon-wrapper {
+ border: 2px solid #e9e9eb;
+}
+.umb-forms-workflow.-add-new {
+ padding-bottom: 0;
+}
+.umb-forms-workflow.-add-new:hover {
+ background: none;
+}
+.umb-forms-workflow__icon-wrapper {
+ width: 36px;
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 2px solid #d8d7d9;
+ margin-right: 10px;
+ background: #ffffff;
+ border-radius: 3px;
+}
+.umb-forms-workflow__icon-wrapper.-round {
+ border-radius: 50%;
+}
+.umb-forms-workflow__icon-wrapper.-empty {
+ border-style: dashed;
+}
+.umb-forms-workflow__icon-wrapper.sortable-handle {
+ cursor: move;
+}
+.umb-forms-workflow__icon {
+ font-size: 22px;
+}
+.umb-forms-workflow__name-wrapper {
+ display: flex;
+ flex-direction: column;
+ flex: 1 1 auto;
+}
+.umb-forms-workflow__name {
+ font-weight: bold;
+ font-size: 14px;
+}
+.umb-forms-workflow__description {
+ font-size: 13px;
+ color: #817f85;
+}
+.umb-forms-workflow__action {
+ font-size: 16px;
+ margin-left: 5px;
+ margin-right: 5px;
+ position: relative;
+}
+.umb-forms-workflow__workflow-placeholder {
+ background: #f3f3f5;
+ display: block;
+ padding: 10px;
+ position: relative;
+ z-index: 1;
+}
+.umb-forms-workflows-divider {
+ display: block;
+ border: 1px dashed #e9e9eb;
+ margin-top: 40px;
+ margin-bottom: 40px;
+}
+.umb-forms-workflow-actions {
+ padding: 10px 15px;
+ margin-bottom: 30px;
+ display: flex;
+ align-items: center;
+ margin-top: 10px;
+ min-height: 86px;
+ border: 1px solid transparent;
+ border-radius: 3px;
+ box-sizing: border-box;
+ background-color: #fff;
+ position: relative;
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.16);
+}
+.umb-forms-workflow-preview {
+ line-height: 1.3;
+ display: inline-flex;
+ align-items: center;
+ font-size: 14px;
+ flex: 0 0 auto;
+ padding: 3px 0;
+}
+.umb-forms-workflow-preview__item {
+ padding: 5px 8px;
+ margin: 0 5px;
+ background-color: #f6f3fd;
+ border: 1px solid #413659;
+ border-radius: 3px;
+ text-align: center;
+ display: inline-block;
+}
+a.umb-forms-workflow-preview__item:hover {
+ border-color: #675e7a;
+ text-decoration: none;
+}
+.umb-forms-workflow-preview__item--inactive {
+ background-color: #f3f3f5;
+ border: 1px solid #bbbabf;
+}
+a.umb-forms-workflow-preview__item--inactive:hover {
+ border-color: #a2a1a6;
+}
+.umb-forms-workflow-flows {
+ display: flex;
+ flex-direction: column;
+ flex: 1 1 auto;
+}
+.umb-forms-workflow-flow {
+ flex: 1 1 auto;
+ max-width: 98%;
+ line-height: 3;
+ display: flex;
+ flex-wrap: wrap;
+ margin: 5px 0;
+}
+.umb-forms-workflow-settings {
+ font-weight: bold;
+ flex: 0 0 auto;
+ text-align: right;
+ font-size: 14px;
+}
+.umb-forms-workflow-preview__add {
+ display: inline-block;
+ margin-top: 30px;
+}
+.umb-forms__no-fields {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ text-align: center;
+}
+.umb-forms__no-fields-text {
+ font-size: 18px;
+ line-height: 1.5;
+ font-weight: bold;
+ display: block;
+ width: 100%;
+ margin-bottom: 5px;
+}
+.umb-forms__store-records-disabled {
+ margin-top: -30px;
+ /* Used to help remove top whitespace between the date filter */
+}
+.umb-forms-button {
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 14px;
+ font-weight: bold;
+ text-transform: capitalize;
+ height: 32px;
+ line-height: 32px;
+ max-width: 100%;
+ padding: 0 18px;
+ color: #515054;
+ background-color: #d8d7d9;
+ text-decoration: none !important;
+ user-select: none;
+ white-space: nowrap;
+ overflow: hidden;
+ border-radius: 3px;
+ border: 0 none;
+ transition: background-color 80ms ease, color 80ms ease;
+}
+.umb-forms-button:hover,
+.umb-forms-button:active {
+ color: #515054;
+ background-color: #bbbabf;
+ outline: none;
+ text-decoration: none;
+}
+.umb-forms-button:focus {
+ outline: none;
+}
+.umb-forms-button.-blue {
+ background: #2e8aea;
+ color: #ffffff;
+}
+.umb-forms-button.-blue:hover,
+.umb-forms-button.-blue:active {
+ background: #0064cd;
+ color: #ffffff;
+}
+.umb-forms-button.-simple {
+ background: transparent;
+ padding: 0;
+}
+.umb-forms-button.-simple:hover,
+.umb-forms-button.-simple:active {
+ color: #2e8aea;
+}
+.umb-forms-button.-disabled,
+.umb-forms-button.-disabled:hover,
+.umb-forms-button.-disabled:active {
+ background-color: #f3f3f5;
+ border: 1px solid #a2a1a6;
+ cursor: default;
+}
+.umb-forms__select {
+ position: relative;
+}
+.umb-forms__select select {
+ width: 100%;
+ min-width: 70px;
+ border: none;
+ margin-right: 5px;
+ font-size: 14px;
+ text-align: left;
+ line-height: 1.3;
+ display: inline-block;
+ background: #f6f3fd;
+ border: 1px solid #413659;
+ border-radius: 3px;
+ height: 30px;
+}
+.umb-forms__select select:hover,
+.umb-forms__select select:active {
+ border: 1px solid #675e7a;
+ text-decoration: none;
+ outline: none;
+}
+.umb-forms__condition-select {
+ display: inline-flex;
+ flex-direction: row;
+ align-items: center;
+ font-size: 14px;
+ font-weight: bold;
+ margin-bottom: 10px;
+}
+.umb-forms__condition-select span {
+ padding-right: 5px;
+}
+.umb-forms__condition-select .umb-forms__select {
+ margin-right: 5px;
+}
+.umb-forms-rule {
+ padding-top: 15px;
+ padding-bottom: 15px;
+ border-bottom: 1px solid #e9e9eb;
+}
+.umb-forms-rule:last-of-type {
+ margin-bottom: 20px;
+}
+.umb-forms-rule input[type="text"] {
+ display: block;
+ width: auto;
+ flex: 1 1 auto;
+}
+.umb-forms-rule__cond {
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ align-items: center;
+}
+.umb-forms-rule__cond a,
+.umb-forms-rule__cond a:hover,
+.umb-forms-rule__cond a:focus {
+ text-decoration: none;
+ margin-left: auto;
+ text-align: right;
+ flex: 0 0 4%;
+}
+.umb-forms-rule__cond [class*="icon-"] {
+ margin-left: 5px;
+ cursor: pointer;
+ opacity: .75;
+}
+.umb-forms-rule__cond [class*="icon-"]:hover {
+ opacity: 1;
+}
+.umb-forms-rule .umb-forms__select {
+ flex: 1 1 32%;
+ margin-right: 5px;
+}
+.umb-forms__conditions-rule {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ flex: 1 1 32%;
+}
+.umb-forms__conditions-rule a {
+ margin-left: 5px;
+ cursor: pointer;
+ text-decoration: none !important;
+ opacity: .5;
+}
+.umb-forms__conditions-rule a:hover {
+ opacity: 1;
+}
+.umb-forms-mappings {
+ display: flex;
+ flex-direction: column;
+}
+.umb-forms-mapping-header {
+ display: flex;
+ flex-direction: row;
+ font-weight: bold;
+}
+.umb-forms-mapping {
+ display: flex;
+ flex-direction: row;
+ margin-bottom: 5px;
+ align-items: center;
+}
+.umb-forms-mapping-field {
+ flex: 1 1 33%;
+ margin: 5px;
+}
+.umb-forms-mapping-field input,
+.umb-forms-mapping-field select {
+ margin-bottom: 0;
+}
+.umb-forms-mapping-field.-no-margin-left {
+ margin-left: 0;
+}
+.umb-forms-mapping-remove {
+ flex: 1 1 20px;
+ margin: 5px;
+}
+.umb-forms-mapping-remove.-no-margin-right {
+ margin-right: 0;
+}
+.umb-forms__save-as-node {
+ flex-wrap: wrap;
+ margin-top: 20px;
+}
+.umb-forms__save-as-node-group {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+ padding: 5px 0;
+}
+.umb-forms__save-as-node__head {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ width: 100%;
+}
+.umb-forms__save-as-node-field {
+ display: flex;
+ align-items: center;
+ flex: 0 0 37%;
+ margin: 3px;
+}
+.umb-forms__save-as-node-field:first-of-type {
+ flex: 0 0 20%;
+}
+.umb-forms__save-as-node .-full-width {
+ width: 100%;
+}
+.umb-forms-date-range-picker {
+ /* List */
+ /* Date range start */
+ /* Date range end */
+ /* Date range background */
+ /* Current date */
+ /* Date hover */
+ /* Dropdown icon */
+ /* Calendar switcher arrow */
+}
+.umb-forms-date-range-picker.daterange .dr-input.dr-active {
+ box-shadow: none;
+ color: #2e2246;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-list-item {
+ color: #303033;
+ font-weight: bold;
+ border-bottom-color: #e9e9eb;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-list-item .dr-item-aside {
+ font-weight: normal;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-list-item:hover {
+ background-color: #f3f3f5;
+}
+.umb-forms-date-range-picker.daterange .dr-input:hover {
+ border-color: #413659;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-days-of-week-list {
+ background-color: #f3f3f5;
+ color: #817f85;
+}
+.umb-forms-date-range-picker.daterange .dr-input .dr-dates .dr-date.dr-active,
+.umb-forms-date-range-picker.daterange .dr-input .dr-dates .dr-date:focus,
+.umb-forms-date-range-picker.daterange .dr-input .dr-dates .dr-date:hover {
+ color: #2e2246;
+}
+.umb-forms-date-range-picker.daterange .dr-input .dr-presets {
+ border-left-color: #bbbabf;
+}
+.umb-forms-date-range-picker.daterange .dr-input .dr-presets.dr-active,
+.umb-forms-date-range-picker.daterange .dr-input .dr-presets:hover {
+ border-color: #413659;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-start {
+ border-left-color: #2e2246;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-end {
+ border-right-color: #2e2246;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-end,
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-selected,
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-start {
+ background-color: #f3f3f5;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-current {
+ color: #000000 !important;
+ background-color: #b3afbd !important;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-day.dr-hover-before,
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-day.dr-hover-after {
+ border-left-color: #2e2246 !important;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-day.dr-hover:not(.dr-current),
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-day-list .dr-day.dr-maybe {
+ background-color: #f3f3f5 !important;
+}
+.umb-forms-date-range-picker.daterange .dr-input .dr-presets .dr-preset-bar {
+ background-color: #a2a1a6;
+}
+.umb-forms-date-range-picker.daterange .dr-input .dr-presets.dr-active .dr-preset-bar,
+.umb-forms-date-range-picker.daterange .dr-input .dr-presets:hover .dr-preset-bar {
+ background-color: #413659;
+}
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i:hover:after,
+.umb-forms-date-range-picker.daterange .dr-selections .dr-calendar .dr-range-switcher .dr-switcher i:hover:before {
+ background-color: #2e2246;
+}
+.umb-forms__validation-pattern {
+ margin-bottom: 5px !important;
+}
+.umb-form-picker .flex {
+ width: 60%;
+}
+.umb-form-picker-select ul.umb-actions {
+ margin-top: 10px;
+}
+.umb-form-picker-select ul.umb-actions li a {
+ display: flex;
+ padding: 8px 2px;
+ border-bottom: 1px solid #e6e6e6;
+}
+.umb-form-picker-select ul.umb-actions li a:hover {
+ background-color: #f3f3f5;
+ text-decoration: none;
+}
+.umb-form-picker-select ul.umb-actions li a .icon-umb-contour {
+ font-size: 20px;
+ display: inline-block;
+ margin-left: 4px;
+}
+.umb-form-picker-select ul.umb-actions li a .icon-check {
+ font-size: 22px;
+ display: inline-block;
+}
+.umb-forms-prevalues .umb-forms-prevalues__list {
+ margin: 4px 2px;
+}
+.umb-forms-prevalues .umb-forms-prevalues__list td {
+ padding: 2px 6px;
+}
+.umb-forms-prevalues .umb-forms-prevalues__add input {
+ margin-bottom: 0;
+}
+.umb-forms-prevalues .umb-forms-prevalues__actions span {
+ position: relative;
+ cursor: pointer;
+}
+.umb-forms-prevalues .umb-forms-prevalues__actions span .umb_confirm-action__overlay.-right {
+ top: -5px;
+ right: -55px;
+}
+.umb-forms-prevalues .umb-forms-prevalues__actions i {
+ cursor: pointer;
+ margin-left: 4px;
+}
+.umb-forms-file-upload .umb-forms-file-upload__allow-all {
+ margin: 10px 0;
+}
+.umb-forms-file-upload .grid-container {
+ grid-template-columns: 1fr 1fr 1fr 1fr;
+}
+.umb-forms-file-upload .umb-forms-file-upload__add input {
+ margin-bottom: 0;
+}
+.umb-forms-setting-type-range {
+ padding: 50px 0px 50px 0px;
+ margin: 0 20px 0 20px;
+}
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/js/umbraco.forms.js b/TestSite-V8.7.3/App_Plugins/UmbracoForms/js/umbraco.forms.js
new file mode 100644
index 0000000..c5d37bb
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/js/umbraco.forms.js
@@ -0,0 +1,5430 @@
+angular.module("umbraco").controller("UmbracoForms.RenderTypes.FileController",
+ function($scope){
+
+
+
+ var imageExts = ['jpg','jpeg','png','gif','bmp'];
+
+ $scope.files = $scope.field.replace('~', '').split(',');
+
+ $scope.isImage = function(filepath){
+ return imageExts.indexOf( $scope.getExtension(filepath) ) >= 0;
+ };
+
+ $scope.getExtension = function(filepath){
+ return filepath.substring(filepath.lastIndexOf(".")+1).toLowerCase();
+ };
+
+ $scope.getFileName = function(filepath){
+ return filepath.substring(filepath.lastIndexOf("/")+1);
+ };
+
+ $scope.getPreview = function(filepath){
+ return filepath.replace('~','') + "?width=400";
+ };
+
+ });
+
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.DocumentMapperController",
+ function ($scope, $routeParams,pickerResource) {
+
+ if (!$scope.setting.value) {
+
+ } else {
+ var value = JSON.parse($scope.setting.value);
+ $scope.doctype = value.doctype;
+ $scope.nameField = value.nameField;
+ $scope.nameStaticValue = value.nameStaticValue;
+
+ //Need to merge the fields (fetch everytime we load in case of renames or new properties added or removed)
+ pickerResource.updateMappedProperties($scope.doctype, value.properties).then(function (response) {
+ $scope.properties = response.data;
+ });
+ }
+
+ pickerResource.getAllDocumentTypesWithAlias().then(function (response) {
+ $scope.doctypes = response.data;
+ });
+
+ pickerResource.getAllFields($routeParams.id).then(function (response) {
+ $scope.fields = response.data;
+ });
+
+ $scope.setDocType = function() {
+
+ pickerResource.getAllProperties($scope.doctype).then(function (response) {
+ $scope.properties = response.data;
+ });
+ };
+
+ $scope.setValue = function() {
+
+ var val = {};
+ val.doctype = $scope.doctype;
+ val.nameField = $scope.nameField;
+ val.nameStaticValue = $scope.nameStaticValue;
+ val.properties = $scope.properties;
+
+ $scope.setting.value = JSON.stringify(val);
+ };
+ });
+
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.EmailTemplatePicker",
+ function ($scope, pickerResource, editorService) {
+
+ $scope.openTreePicker = function() {
+
+ var treePickerOverlay = {
+ treeAlias: "emailTemplates",
+ section:"forms",
+ entityType: "email-template",
+ multiPicker: false,
+ onlyInitialized: false,
+ select: function(node){
+ pickerResource.getVirtualPathForEmailTemplate(node.id).then(function (response) {
+ //Set the picked template file path as the setting value
+ $scope.setting.value = response.data.path;
+ });
+
+ editorService.close();
+ },
+ close: function (model) {
+ editorService.close();
+ }
+ };
+
+ editorService.treePicker(treePickerOverlay);
+
+ };
+
+ });
+
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.FieldMapperController",
+ function ($scope, $routeParams, pickerResource) {
+
+ function init() {
+
+ if (!$scope.setting.value) {
+ $scope.mappings = [];
+ } else {
+ $scope.mappings = JSON.parse($scope.setting.value);
+ }
+
+ var formId = $routeParams.id;
+
+ if (formId === -1 && $scope.model && $scope.model.fields) {
+
+ } else {
+
+ pickerResource.getAllFields($routeParams.id).then(function (response) {
+ $scope.fields = response.data;
+ });
+ }
+ }
+
+ $scope.addMapping = function () {
+ console.log('add');
+
+ $scope.mappings.push({
+ alias: "",
+ value: "",
+ staticValue: ""
+ });
+ };
+
+ $scope.deleteMapping = function (index) {
+ $scope.mappings.splice(index, 1);
+ $scope.setting.value = JSON.stringify($scope.mappings);
+ };
+
+ $scope.stringifyValue = function () {
+ $scope.setting.value = JSON.stringify($scope.mappings);
+ };
+
+ init();
+
+ });
+
+
+(function () {
+ "use strict";
+
+ function FileUploadSettingsController($scope, Upload, notificationsService) {
+
+ var vm = this;
+ vm.isUploading = false;
+ vm.filePercentage = 0;
+ vm.savedPath = $scope.setting.value;
+
+ vm.uploadFile = function(file){
+
+ // console.log('savedPath', vm.savedPath);
+
+ Upload.upload({
+ url: "backoffice/UmbracoForms/PreValueFile/PostAddFile",
+ fields: {
+ 'previousPath': vm.savedPath
+ },
+ file: file
+ })
+ .progress(function(evt) {
+ // set uploading status on file
+ vm.isUploading = true;
+
+ // calculate progress in percentage
+ var progressPercentage = parseInt(100.0 * evt.loaded / evt.total, 10);
+
+ // set percentage property on file
+ vm.filePercentage = progressPercentage;
+
+ // console.log('progress', progressPercentage);
+ })
+ .success(function(data, status, headers, config) {
+ // console.log('success data', data);
+
+ //Set the path for the PreValue setting & will get saved into the JSON
+ $scope.setting.value = data.FilePath;
+ vm.savedPath = data.FilePath;
+
+ //Reset
+ vm.isUploading = false;
+ vm.filePercentage = 0;
+ })
+ .error(function(evt, status, headers, config) {
+
+ //Loop over notifications from response from API to show them
+ if (angular.isArray(evt.notifications)) {
+ for (var i = 0; i < evt.notifications.length; i++) {
+ notificationsService.showNotification(evt.notifications[i]);
+ }
+ }
+
+ //Reset
+ vm.isUploading = false;
+ vm.filePercentage = 0;
+
+ });
+
+ };
+
+ };
+
+ angular.module("umbraco").controller("UmbracoForms.SettingTypes.FileUpload", FileUploadSettingsController);
+})();
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.File",
+ function ($scope, editorService) {
+
+ $scope.openMediaPicker = function () {
+
+ var mediaPicker = {
+ submit: function (model) {
+ var selectedImage = model.selection[0];
+ populateFile(selectedImage);
+
+ editorService.close();
+ },
+ close: function () {
+ editorService.close();
+ }
+ };
+
+ editorService.mediaPicker(mediaPicker);
+ };
+
+ $scope.clear = function () {
+ $scope.setting.value = undefined;
+ };
+
+ function populateFile(item) {
+ $scope.setting.value = item.image;
+ }
+ });
+
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.NumericFieldController",
+ function ($scope) {
+
+ var vm = this;
+
+ // The prevalues setting is a string array in order: Min, Max, Default Value.
+ vm.min = parseFloat($scope.setting.prevalues[0]);
+ vm.max = parseFloat($scope.setting.prevalues[1]);
+ var defaultValue = parseFloat($scope.setting.prevalues[2]);
+
+ // Set the provided default value.
+ if (!$scope.setting.value) {
+ $scope.setting.value = defaultValue;
+ }
+
+ // Ensure we have a number.
+ vm.value = parseFloat($scope.setting.value);
+
+ vm.change = function () {
+ // Convert it back to a string.
+ $scope.setting.value = vm.value.toString();
+ }
+
+});
+
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.Pickers.CheckboxController", function ($scope) {
+
+ var vm = this;
+
+ vm.toggle = toggle;
+ vm.checked = $scope.setting.value === 'True';
+
+
+ function toggle() {
+ vm.checked = !vm.checked;
+
+ if(vm.checked){
+ $scope.setting.value = 'True'
+ }else{
+ $scope.setting.value = 'False'
+ }
+ }
+});
+
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.Pickers.ConnectionStringController",
+ function ($scope, $routeParams, pickerResource) {
+ pickerResource.getAllConnectionStrings().then(function (response) {
+ $scope.strings = response.data;
+ });
+ });
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.Pickers.ContentController",
+ function ($scope, $routeParams, editorService, entityResource, iconHelper) {
+
+ if (!$scope.setting) {
+ $scope.setting = {};
+ }
+
+
+ var val = parseInt($scope.setting.value);
+
+
+ if (!isNaN(val) && angular.isNumber(val)) {
+ //node
+ $scope.showQuery = false;
+
+ entityResource.getById($scope.setting.value, "Document").then(function (item) {
+ item.icon = iconHelper.convertFromLegacyIcon(item.icon);
+ $scope.node = item;
+ });
+ }
+
+ $scope.openContentPicker = function () {
+
+ var contentPicker = {
+ submit: function(model) {
+ var selectedNode = model.selection[0];
+ populate(selectedNode);
+ editorService.close();
+ },
+ close: function() {
+ editorService.close();
+ }
+ };
+ editorService.contentPicker(contentPicker);
+ };
+
+
+ $scope.clear = function () {
+ $scope.id = undefined;
+ $scope.node = undefined;
+ $scope.setting.value = undefined;
+ };
+
+ function populate(item) {
+ $scope.clear();
+ item.icon = iconHelper.convertFromLegacyIcon(item.icon);
+ $scope.node = item;
+ $scope.id = item.id;
+ $scope.setting.value = item.id;
+ }
+
+});
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.Pickers.ContentWithXpathController",
+ function ($scope, $routeParams, editorService, entityResource, iconHelper, utilityService) {
+
+ var umbracoVersion = Umbraco.Sys.ServerVariables.application.version;
+
+ $scope.queryIsVisible = false;
+ $scope.helpIsVisible = false;
+ $scope.query = "";
+
+
+ if (!$scope.setting) {
+ $scope.setting = {};
+ }
+
+ function init() {
+
+ if(angular.isNumber($scope.setting.value)){
+
+ entityResource.getById($scope.setting.value, "Document").then(function (item) {
+ item.icon = iconHelper.convertFromLegacyIcon(item.icon);
+ $scope.node = item;
+ });
+
+ } else if($scope.setting.value) {
+
+ $scope.queryIsVisible = true;
+ $scope.query = $scope.setting.value;
+
+ }
+
+ }
+
+ $scope.openContentPicker = function () {
+
+ var contentPicker = {
+ submit: function(model) {
+ populate(model.selection[0]);
+ editorService.close();
+ },
+ close: function() {
+ editorService.close();
+ }
+ };
+ editorService.contentPicker(contentPicker);
+
+ };
+
+ $scope.showQuery = function() {
+ $scope.queryIsVisible = true;
+ };
+
+ $scope.toggleHelp = function() {
+ $scope.helpIsVisible = !$scope.helpIsVisible;
+ };
+
+ $scope.setXpath = function() {
+ $scope.setting.value = $scope.query;
+ };
+
+ $scope.clear = function () {
+ $scope.id = undefined;
+ $scope.node = undefined;
+ $scope.setting.value = undefined;
+ $scope.query = undefined;
+ $scope.queryIsVisible = false;
+ };
+
+ function populate(item) {
+ $scope.clear();
+ item.icon = iconHelper.convertFromLegacyIcon(item.icon);
+ $scope.node = item;
+ $scope.id = item.id;
+ $scope.setting.value = item.id;
+ }
+
+ init();
+
+});
+
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.Pickers.DataTypeController",
+ function ($scope, $routeParams, pickerResource) {
+ pickerResource.getAllDataTypes().then(function (response) {
+ $scope.datatypes = response.data;
+ });
+ });
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.Pickers.DocumentTypeController",
+ function ($scope, $routeParams, pickerResource) {
+ pickerResource.getAllDocumentTypesWithAlias().then(function (response) {
+ $scope.doctypes = response.data;
+ });
+ });
+angular.module("umbraco").controller("UmbracoForms.SettingTypes.RangeController",
+ function ($scope) {
+
+ var vm = this;
+
+ // The prevalues setting is a string array in order: Min, Max, Step, Default.
+ var min = parseFloat($scope.setting.prevalues[0]);
+ var max = parseFloat($scope.setting.prevalues[1]);
+ var step = parseFloat($scope.setting.prevalues[2]);
+ var defaultValue = parseFloat($scope.setting.prevalues[3]);
+ var stepDecimalPlaces = getDecimalPlaces(step);
+
+ // Set the provided default value.
+ if (!$scope.setting.value) {
+ $scope.setting.value = defaultValue;
+ }
+
+ // Ensure we have a number.
+ vm.value = parseFloat($scope.setting.value);
+
+ vm.sliderOptions = {
+ "start": [vm.Value],
+ "step": step,
+ "tooltips": [true],
+ "format": {
+ to: function (value) {
+ return value.toFixed(stepDecimalPlaces);
+ },
+ from: function (value) {
+ return Number(value);
+ }
+ },
+ "range": {
+ "min": min,
+ "max": max,
+ },
+ "pips": {
+ "mode": "steps",
+ "density": 100,
+ "format": {
+ to: function (value) {
+ return value.toFixed(stepDecimalPlaces);
+ },
+ from: function (value) {
+ return Number(value);
+ }
+ },
+ }
+ };
+
+ function getDecimalPlaces(value) {
+ // Hat-tip: https://stackoverflow.com/a/17369245/489433
+ if (Math.floor(value) === value) {
+ return 0;
+ }
+
+ return value.toString().split(".")[1].length || 0;
+ }
+
+ vm.change = function (values) {
+ // Convert it back to a string anytime the range slider value changed.
+ // We're only supporting a single value, so as value provided is an array, we just take the first value.
+ $scope.setting.value = values[0].toString();
+ }
+
+ });
+
+angular.module("umbraco")
+ .controller("UmbracoForms.Dashboards.FormsController",
+ function ($scope, $location, $cookies, formResource, licensingResource, updatesResource, notificationsService, userService, securityResource, recordResource) {
+
+ var vm = this;
+
+ vm.overlay = {
+ show: false,
+ title: "Congratulations",
+ description: "You've just installed Umbraco Forms - Let's create your first form"
+ };
+
+ var packageInstall = $cookies.get("umbPackageInstallId");
+
+ if (packageInstall) {
+ vm.overlay.show = true;
+ $cookies.put("umbPackageInstallId", "");
+ }
+
+ //Default for canManageForms is false
+ //Need a record in security to ensure user has access to edit/create forms
+ vm.userCanManageForms = false;
+
+ //Get Current User - To Check if the user Type is Admin
+ userService.getCurrentUser().then(function (response) {
+ vm.currentUser = response;
+ vm.isAdminUser = response.userGroups.includes("admin");
+
+ securityResource.getByUserId(vm.currentUser.id).then(function (response) {
+ vm.userCanManageForms = response.data.userSecurity.manageForms;
+ });
+ });
+
+ //if not initial install, but still do not have forms - display a message
+ if (!vm.overlay.show) {
+
+ //Check if we have any forms created yet - by chekcing number of items back from JSON response
+ formResource.getOverView().then(function (response) {
+ if (response.data.length === 0) {
+ vm.overlay.show = true;
+ vm.overlay.title = "Create a form";
+ vm.overlay.description = "You do not have any forms setup yet, how about creating one now?";
+ }
+ });
+ }
+
+ vm.getLicenses = function (config) {
+
+ vm.loginError = false;
+ vm.hasLicenses = undefined;
+ vm.isLoading = true;
+
+ licensingResource.getAvailableLicenses(config).then(function (response) {
+ var licenses = response.data;
+ var currentDomain = window.location.hostname;
+
+ vm.hasLicenses = licenses.length > 0;
+ _.each(licenses, function (lic) {
+ if (lic.bindings && lic.bindings.indexOf(currentDomain) >= 0) {
+ lic.currentDomainMatch = true;
+ }
+ });
+
+ vm.configuredLicenses = _.sortBy(_.filter(licenses, function (license) { return license.configured; }), 'currentDomainMatch');
+ vm.openLicenses = _.filter(licenses, function (license) { return license.configured === false; });
+ vm.isLoading = false;
+
+ }, function (err) {
+ vm.loginError = true;
+ vm.hasLicenses = undefined;
+ vm.isLoading = false;
+ });
+
+ };
+
+
+ vm.configure = function (config) {
+ vm.isLoading = true;
+ licensingResource.configureLicense(config).then(function (response) {
+ vm.configuredLicenses.length = 0;
+ vm.openLicenses.length = 0;
+ vm.loadStatus();
+ notificationsService.success("License configured", "Umbraco forms have been configured to be used on this website");
+ });
+ };
+
+
+ vm.loadStatus = function () {
+ licensingResource.getLicenseStatus().then(function (response) {
+ vm.status = response.data;
+ vm.isLoading = false;
+ });
+
+ updatesResource.getUpdateStatus().then(function (response) {
+ vm.version = response.data;
+ });
+
+ updatesResource.getVersion().then(function (response) {
+ vm.currentVersion = response.data;
+ });
+
+ updatesResource.getSavePlainTextPasswordsConfiguration().then(function (response) {
+ vm.savePlainTextPasswords = response.data.toString() === "true";
+ });
+
+
+ };
+
+ //TODO: Can this die/go away?!
+ vm.upgrade = function () {
+ //Let's tripple check the user is of the userType Admin
+ if (!$scope.isAdminUser) {
+ //The user is not an admin & should have not hit this method but if they hack the UI they could potnetially see the UI perhaps?
+ notificationsService.error("Insufficient Permissions", "Only Admin users have the ability to upgrade Umbraco Forms");
+ return;
+ }
+
+ vm.installing = true;
+ updatesResource.installLatest($scope.version.remoteVersion).then(function (response) {
+ window.location.reload();
+ }, function (reason) {
+ //Most likely the 403 Unauthorised back from server side
+ //The error is caught already & shows a notification so need to do it here
+ //But stop the loading bar from spining forever
+ vm.installing = false;
+ });
+ };
+
+
+ vm.create = function () {
+
+ //Let's tripple check the user is of the userType Admin
+ if (!vm.userCanManageForms) {
+ //The user is not an admin & should have not hit this method but if they hack the UI they could potnetially see the UI perhaps?
+ notificationsService.error("Insufficient Permissions", "You do not have permissions to create & manage forms");
+ return;
+ }
+
+ $location.url("forms/form/edit/-1?template=&create=true");
+ };
+
+
+ vm.configuration = { domain: window.location.hostname };
+ vm.loadStatus();
+
+
+ /////////////////////
+
+ vm.initialFormsLimit = 4;
+ vm.formsLimit = 4; //Show top 4 by default
+
+ vm.showMore = function () {
+ var incrementLimitBy = 8;
+ vm.formsLimit = vm.formsLimit + incrementLimitBy;
+ getRecordCounts();
+ };
+
+ function getRecordCounts() {
+ _.each(vm.forms, function (form, index) {
+
+ // Only get record counts for forms that are a) visible and b) already populated.
+ if (index >= vm.formsLimit || form.gotEntries) {
+ return;
+ }
+
+ var filter = { form: form.id };
+
+ recordResource.getRecordsCount(filter).then(function (response) {
+ form.entries = response.data.count;
+ form.gotEntries = true;
+ });
+ });
+ }
+
+ // Get all forms and populate visible ones with recorcd counts.
+ formResource.getOverView().then(function (response) {
+ vm.forms = response.data;
+ getRecordCounts();
+ });
+
+ });
+
+angular.module("umbraco")
+.controller("UmbracoForms.Editors.DataSource.DeleteController",
+ function ($scope, dataSourceResource, navigationService, treeService) {
+ $scope.delete = function (id) {
+ dataSourceResource.deleteByGuid(id).then(function () {
+
+ treeService.removeNode($scope.currentNode);
+ navigationService.hideNavigation();
+
+ });
+
+ };
+ $scope.cancelDelete = function () {
+ navigationService.hideNavigation();
+ };
+ });
+angular.module("umbraco").controller("UmbracoForms.Editors.DataSource.EditController", function ($scope, $routeParams, dataSourceResource, editorState, notificationsService, editorService, navigationService, formHelper, userService, securityResource) {
+
+ //On load/init of 'editing' a prevalue source then
+ //Let's check & get the current user's form security
+ var currentUserId = null;
+
+ userService.getCurrentUser().then(function (response) {
+ currentUserId = response.id;
+
+ //Now we can make a call to form securityResource
+ securityResource.getByUserId(currentUserId).then(function (response) {
+ $scope.security = response.data;
+
+ //Check if we have access to current form OR manage forms has been disabled
+ if (!$scope.security.userSecurity.manageDataSources) {
+
+ //Show error notification
+ notificationsService.error("Access Denied", "You do not have access to edit Datasources");
+
+ //Resync tree so that it's removed & hides
+ navigationService.syncTree({ tree: "datasource", path: ['-1'], forceReload: true, activate: false }).then(function (response) {
+
+ //Response object contains node object & activate bool
+ //Can then reload the root node -1 for this tree 'Forms Folder'
+ navigationService.reloadNode(response.node);
+ });
+
+ //Don't need to wire anything else up
+ return;
+ }
+ });
+ });
+
+ if ($routeParams.create) {
+ //we are creating so get an empty data type item
+ dataSourceResource.getScaffold().then(function (response) {
+ $scope.loaded = true;
+ $scope.dataSource = response.data;
+
+ dataSourceResource.getAllDataSourceTypesWithSettings()
+ .then(function (resp) {
+ $scope.types = resp.data;
+
+ });
+
+ //set a shared state
+ editorState.set($scope.form);
+ });
+ }
+ else {
+ //we are editing so get the content item from the server
+ dataSourceResource.getByGuid($routeParams.id)
+ .then(function (response) {
+
+ $scope.dataSource = response.data;
+
+ dataSourceResource.getAllDataSourceTypesWithSettings()
+ .then(function (resp) {
+ $scope.types = resp.data;
+ setTypeAndSettings();
+
+ $scope.loaded = true;
+ });
+
+
+
+ //set a shared state
+ editorState.set($scope.dataSource);
+ });
+ }
+
+ $scope.setType = function () {
+ setTypeAndSettings();
+ };
+
+ $scope.save = function () {
+ if (formHelper.submitForm({ scope: $scope })) {
+
+ //set settings
+ $scope.dataSource.settings = {};
+ if($scope.dataSource.$type){
+ angular.forEach($scope.dataSource.$type.settings, function (setting) {
+ var key = setting.alias;
+ var value = setting.value;
+ $scope.dataSource.settings[key] = value;
+
+ });
+ }
+
+ //validate settings
+ dataSourceResource.validateSettings($scope.dataSource)
+ .then(function (response) {
+
+ $scope.errors = response.data;
+
+ if ($scope.errors.length > 0) {
+ $scope.dataSource.valid = false;
+ angular.forEach($scope.errors, function (error) {
+
+ notificationsService.error("Datasource failed to save", error.Message);
+
+ });
+ } else {
+ //save
+ dataSourceResource.save($scope.dataSource)
+ .then(function (response) {
+
+ $scope.dataSource = response.data;
+ //set a shared state
+ editorState.set($scope.dataSource);
+ setTypeAndSettings();
+ navigationService.syncTree({ tree: "datasource", path: [String($scope.dataSource.id)], forceReload: true });
+ notificationsService.success("Datasource saved", "");
+ $scope.dataSource.valid = true;
+ $scope.dataSourceForm.$dirty = false;
+ }, function (err) {
+ notificationsService.error("Datasource failed to save", "");
+ });
+ }
+
+
+ }, function (err) {
+ notificationsService.error("Datasource failed to save", "Please check if your settings are valid");
+ });
+ }
+ };
+
+ $scope.showWizard = function() {
+ var dataSourcesSettings = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Datasource/dialogs/wizard.html",
+ dataSourceId: $scope.dataSource.id,
+ size: 'medium'
+ };
+
+ editorService.open(dataSourcesSettings);
+ };
+
+ var setTypeAndSettings = function () {
+ $scope.dataSource.$type = _.where($scope.types, { id: $scope.dataSource.formDataSourceTypeId })[0];
+
+ //set settings
+ angular.forEach($scope.dataSource.settings, function (setting) {
+ for (var key in $scope.dataSource.settings) {
+ if ($scope.dataSource.settings.hasOwnProperty(key)) {
+ if (_.where($scope.dataSource.$type.settings, { alias: key }).length > 0) {
+ _.where($scope.dataSource.$type.settings, { alias: key })[0].value = $scope.dataSource.settings[key];
+ }
+
+ }
+ }
+ });
+ };
+
+
+
+ });
+angular.module("umbraco")
+.controller("UmbracoForms.Editors.DataSource.WizardController",
+ function ($scope, $routeParams, dataSourceWizardResource, navigationService, notificationsService, editorService) {
+
+ $scope.currentStep = 1;
+ dataSourceWizardResource.getScaffold($scope.model.dataSourceId).then(function (response) {
+
+ $scope.wizard = response.data;
+
+ $scope.hasPrimaryKeys = $scope.wizard.mappings.length != _.where($scope.wizard.mappings, { prevalueKeyField: null }).length;
+
+ dataSourceWizardResource.getAllFieldTypes()
+ .then(function (resp) {
+ $scope.fieldtypes = resp.data;
+ $scope.ready = true;
+ });
+ });
+
+
+ $scope.createForm = function() {
+
+ dataSourceWizardResource.createForm($scope.wizard)
+ .then(function (resp) {
+ editorService.closeAll();
+ notificationsService.success("Form created", "");
+ });
+ };
+
+
+ $scope.cancel = function() {
+ editorService.closeAll();
+ };
+
+ $scope.gotoStep = function (step) {
+ $scope.currentStep = step;
+ }
+
+ $scope.gotoThirdStep = function() {
+ if ($scope.hasPrimaryKeys) {
+ $scope.currentStep = 3;
+ } else {
+ $scope.currentStep = 4;
+ }
+ }
+ $scope.goBackToThirdStep = function() {
+ if ($scope.hasPrimaryKeys) {
+ $scope.currentStep = 3;
+ } else {
+ $scope.currentStep = 2;
+ }
+ }
+ });
+angular.module("umbraco").controller("UmbracoForms.Editors.Form.CopyController", function ($scope, formResource, navigationService) {
+
+ $scope.copiedForm = {
+ name: '',
+ copyWorkflows: false
+ };
+
+ //Copy Function run from button on click
+ $scope.copyForm = function (formId) {
+
+ //Perform copy in formResource
+ formResource.copy(formId, $scope.copiedForm.name, $scope.copiedForm.copyWorkflows).then(function (response) {
+
+ var newFormId = response.data.id;
+
+ //Reload the tree (but do NOT mark the new item in the tree as selected/active)
+ navigationService.syncTree({ tree: "form", path: ["-1", String(newFormId)], forceReload: true, activate: false });
+
+ //Once 200 OK then reload tree & hide copy dialog navigation
+ navigationService.hideNavigation();
+ });
+ };
+
+ //Cancel button - closes dialog
+ $scope.cancelCopy = function () {
+ navigationService.hideNavigation();
+ }
+});
+
+angular.module("umbraco").controller("UmbracoForms.Editors.Form.CreateController", function ($scope, $location, formResource, navigationService) {
+ formResource.getAllTemplates().then(function (response) {
+ $scope.formTemplates = response.data;
+ });
+
+ function navigateToCreateForm(templateAlias) {
+ $location
+ .path("/forms/form/edit/" + $scope.currentNode.id)
+ .search("create", "true")
+ .search("template", templateAlias);
+ navigationService.hideNavigation();
+ }
+
+ $scope.createEmptyForm = function () {
+ navigateToCreateForm("");
+ };
+
+ $scope.createTemplateForm = function (templateAlias) {
+ navigateToCreateForm(templateAlias);
+ };
+
+ $scope.hideDialog = function () {
+ navigationService.hideDialog(true);
+ };
+});
+
+(function () {
+ "use strict";
+
+ function Controller($scope, formResource, navigationService, notificationsService, treeService) {
+
+ var vm = this;
+ vm.buttonState = "init";
+
+ vm.deleteForm = deleteForm;
+ vm.cancelDelete = cancelDelete;
+
+ function cancelDelete () {
+ navigationService.hideNavigation();
+ };
+
+ function deleteForm(id) {
+
+ vm.buttonState = "busy";
+ formResource.deleteByGuid(id).then(function() {
+ vm.buttonState = "success";
+ treeService.removeNode($scope.currentNode);
+ navigationService.hideNavigation();
+
+ notificationsService.success("Successfully deleted the form");
+ }, function(err) {
+ vm.buttonState = "error";
+ notificationsService.error("Form failed to delete", err.data.Message);
+ });
+
+ }
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.Editors.Form.DeleteController", Controller);
+
+})();
+angular.module("umbraco").controller("UmbracoForms.Editors.Form.EditController",
+
+ function ($scope, $routeParams, formResource, editorState, editorService, formService, notificationsService, contentEditingHelper, formHelper, navigationService, userService, securityResource, localizationService, workflowResource) {
+
+
+ //On load/init of 'editing' a form then
+ //Let's check & get the current user's form security
+ var currentUserId = null;
+ var currentFormSecurity = null;
+
+ $scope.page = {
+ loading: true
+ };
+ $scope.page.contentApps = [];
+
+ //By default set to have access (in case we do not find the current user's per individual form security item)
+ $scope.hasAccessToCurrentForm = true;
+
+ $scope.displayEditor = true;
+
+ $scope.init = function () {
+ createAndLocalizeApps();
+ };
+
+ function createAndLocalizeApps() {
+ localizationService.localize("general_design").then(function (val) {
+
+ $scope.page.contentApps.push(
+ {
+ "name": val,
+ "alias": "design",
+ "icon": "icon-document-dashed-line",
+ "view": "/App_Plugins/UmbracoForms/Backoffice/Form/views/design/design.html",
+ "active": true
+ }
+ );
+ });
+
+ localizationService.localize("general_settings").then(function (val) {
+
+ $scope.page.contentApps.push(
+ {
+ "name": val,
+ "alias": "settings",
+ "icon": "icon-settings",
+ "view": "/App_Plugins/UmbracoForms/Backoffice/Form/views/settings/settings.html",
+ "active": false
+ }
+ );
+ });
+ }
+
+ userService.getCurrentUser().then(function (response) {
+ currentUserId = response.id;
+
+ //Now we can make a call to form securityResource
+ securityResource.getByUserId(currentUserId).then(function (response) {
+ $scope.security = response.data;
+
+ //Use _underscore.js to find a single item in the JSON array formsSecurity
+ //where the FORM guid matches the one we are currently editing (if underscore does not find an item it returns an empty array)
+ //As _.findWhere not in Umb .1.6 using _.where() that lists multiple matches - checking that we have only item in the array (ie one match)
+ currentFormSecurity = _.where(response.data.formsSecurity, { Form: $routeParams.id });
+
+ if (currentFormSecurity.length === 1) {
+ //Check & set if we have access to the form
+ //if we have no entry in the JSON array by default its set to true (so won't prevent)
+ $scope.hasAccessToCurrentForm = currentFormSecurity[0].HasAccess;
+ }
+
+ //Check if we have access to current form OR manage forms has been disabled
+ if (!$scope.hasAccessToCurrentForm || !$scope.security.userSecurity.manageForms) {
+
+ //Show error notification
+ notificationsService.error("Access Denied", "You do not have access to edit this form");
+
+
+ //Resync tree so that it's removed & hides
+ navigationService.syncTree({ tree: "form", path: ['-1'], forceReload: true, activate: false }).then(function (response) {
+
+ //Response object contains node object & activate bool
+ //Can then reload the root node -1 for this tree 'Forms Folder'
+ navigationService.reloadNode(response.node);
+ });
+
+ //Don't need to wire anything else up
+ return;
+ }
+ });
+ });
+
+
+ if ($routeParams.create) {
+
+ //we are creating so get an empty data type item
+ //formResource.getScaffold($routeParams.template)
+ formResource.getScaffoldWithWorkflows($routeParams.template)
+ .then(function (response) {
+ $scope.form = response.data;
+
+ //set a shared state
+ editorState.set($scope.form);
+
+ $scope.page.loading = false;
+ });
+
+ } else {
+
+ $scope.workflowsUrl = "#/forms/form/workflows/" + $routeParams.id;
+ $scope.entriesUrl = "#/forms/form/entries/" + $routeParams.id;
+
+
+ //we are editing so get the content item from the server
+ formResource.getWithWorkflowsByGuid($routeParams.id)
+ .then(function (response) {
+
+ //As we are editing an item we can highlight it in the tree
+ navigationService.syncTree({ tree: "form", path: [String($routeParams.id)], forceReload: false });
+
+ $scope.form = response.data;
+ $scope.saved = true;
+
+ // this should be removed in next major version
+ angular.forEach($scope.form.pages, function (page) {
+ angular.forEach(page.fieldSets, function (fieldSet) {
+ angular.forEach(fieldSet.containers, function (container) {
+ angular.forEach(container.fields, function (field) {
+ field.removePrevalueEditor = true;
+ });
+ });
+ });
+ });
+
+ //set a shared state
+ editorState.set($scope.form);
+
+ $scope.page.loading = false;
+ }, function (reason) {
+ //Includes ExceptionMessage, StackTrace etc from the WebAPI
+ var jsonErrorResponse = reason.data;
+
+ //Show notification message, a sticky Error message
+ notificationsService.add({ headline: "Unable to load form", message: jsonErrorResponse.ExceptionMessage, type: 'error', sticky: true });
+
+ //Hide the entire form UI
+ $scope.displayEditor = false;
+ });
+
+
+ }
+
+ $scope.editForm = function (form, section) {
+ editorService.open(
+ {
+ template: "/app_plugins/UmbracoForms/Backoffice/Form/dialogs/formsettings.html",
+ form: form,
+ section: section,
+ page: $scope.currentPage
+ });
+ };
+
+ $scope.save = function () {
+ if (formHelper.submitForm({ scope: $scope })) {
+
+ $scope.page.saveButtonState = "busy";
+
+ //make sure we set correct widths on all containers
+ formService.syncContainerWidths($scope.form);
+
+ formResource.saveWithWorkflows($scope.form).then(function (response) {
+ formHelper.resetForm({ scope: $scope });
+
+ contentEditingHelper.handleSuccessfulSave({
+ scope: $scope,
+ savedContent: response.data
+ });
+
+ $scope.ready = true;
+
+ //set a shared state
+ editorState.set($scope.form);
+
+ $scope.page.saveButtonState = "success";
+ navigationService.syncTree({ tree: "form", path: [String($scope.form.id)], forceReload: true });
+ notificationsService.success("Form saved", "");
+
+ }, function (err) {
+
+ formHelper.handleError(err);
+
+ $scope.page.saveButtonState = "error";
+
+ });
+ }
+
+ };
+
+
+ });
+
+angular.module("umbraco").controller("UmbracoForms.Editors.Form.EntriesController", function ($scope, $routeParams, recordResource, formResource, editorService, userService, securityResource, notificationsService, navigationService, overlayService) {
+
+ // On load/init of 'editing' a form then
+ // Let's check & get the current user's form security
+ var currentUserId = null;
+ var currentFormSecurity = null;
+
+ var vm = this;
+ vm.pagination = {
+ pageNumber: 1,
+ totalPages: 1
+ };
+ vm.allIsChecked = false;
+ vm.selectedEntry = {};
+ vm.showEntryDetails = false;
+ vm.userLocale = "";
+
+ vm.nextPage = nextPage;
+ vm.prevPage = prevPage;
+ vm.goToPageNumber = goToPageNumber;
+ vm.viewEntryDetails = viewEntryDetails;
+ vm.closeEntryDetails = closeEntryDetails;
+ vm.nextEntryDetails = nextEntryDetails;
+ vm.prevEntryDetails = prevEntryDetails;
+ vm.datePickerChange = datePickerChange;
+ vm.toggleRecordState = toggleRecordState;
+ vm.canEditSensitiveData = false;
+
+
+ vm.keyboardShortcutsOverview = [
+
+ {
+ "name": "Entry details",
+ "shortcuts": [
+ {
+ "description": "Next entry",
+ "keys": [
+ {
+ "key": "→"
+ }
+ ]
+ },
+ {
+ "description": "Previous entry",
+ "keys": [
+ {
+ "key": "←"
+ }
+ ]
+ },
+ {
+ "description": "Close details",
+ "keys": [
+ {
+ "key": "esc"
+ }
+ ]
+ }
+ ]
+ }
+
+ ];
+
+ // By default set to have access (in case we do not find the current user's per individual form security item)
+ $scope.hasAccessToCurrentForm = true;
+
+ userService.getCurrentUser().then(function (response) {
+ currentUserId = response.id;
+ vm.userLocale = response.locale;
+
+ // Set the API controller response on the Angular ViewModel
+ vm.canEditSensitiveData = response.userGroups.indexOf("sensitiveData") !== -1;
+
+ // Now we can make a call to form securityResource
+ securityResource.getByUserId(currentUserId).then(function (response) {
+ $scope.security = response.data;
+
+ // Use _underscore.js to find a single item in the JSON array formsSecurity
+ // where the FORM guid matches the one we are currently editing (if underscore does not find an item it returns undefinied)
+ currentFormSecurity = _.where(response.data.formsSecurity, { Form: $routeParams.id });
+
+ if (currentFormSecurity.length === 1) {
+ // Check & set if we have access to the form
+ // if we have no entry in the JSON array by default its set to true (so won't prevent)
+ $scope.hasAccessToCurrentForm = currentFormSecurity[0].HasAccess;
+ }
+
+ // Check if we have access to current form OR manage forms has been disabled
+ if (!$scope.hasAccessToCurrentForm || !$scope.security.userSecurity.manageForms) {
+
+ // Show error notification
+ notificationsService.error("Access Denied", "You do not have access to view this form's entries");
+
+ // Resync tree so that it's removed & hides
+ navigationService.syncTree({ tree: "form", path: ['-1'], forceReload: true, activate: false }).then(function (response) {
+
+ // Response object contains node object & activate bool
+ // Can then reload the root node -1 for this tree 'Forms Folder'
+ navigationService.reloadNode(response.node);
+ });
+
+ // Don't need to wire anything else up
+ return;
+ }
+ });
+ });
+
+
+ formResource.getByGuid($routeParams.id)
+ .then(function (response) {
+ $scope.form = response.data;
+ $scope.loaded = true;
+
+ // As we are editing an item we can highlight it in the tree
+ navigationService.syncTree({ tree: "form", path: [String($routeParams.id), String($routeParams.id) + "_entries"], forceReload: false });
+
+ // Populate the available recordset actions (we need to do this after retrieving the form, so
+ // we can filter out those not appropriate for forms that are automatically approved).
+ recordResource.getRecordSetActions().then(function (response) {
+ $scope.recordSetActions = response.data.filter(function (action) {
+ return $scope.form.manualApproval || action.isAvailableForApprovedRecords
+ });
+ });
+
+ });
+
+ $scope.states = [
+ {
+ "name": "Approved",
+ "isChecked": true
+ },
+ {
+ "name": "Submitted",
+ "isChecked": true
+ }
+ ];
+
+ $scope.filter = {
+ startIndex: 1, // Page Number
+ length: 20, // No per page
+ form: $routeParams.id,
+ sortBy: "created",
+ sortOrder: "descending",
+ states: ["Approved", "Submitted"],
+ localTimeOffset: new Date().getTimezoneOffset()
+ };
+
+ $scope.records = [];
+
+ // Default value
+ $scope.loading = false;
+
+ $scope.toggleRecordStateSelection = function (recordState) {
+ var idx = $scope.filter.states.indexOf(recordState);
+
+ // is currently selected
+ if (idx > -1) {
+ $scope.filter.states.splice(idx, 1);
+ }
+
+ // is newly selected
+ else {
+ $scope.filter.states.push(recordState);
+ }
+ };
+
+ $scope.hiddenFields = [2];
+ $scope.toggleSelection = function toggleSelection(field) {
+ var idx = $scope.hiddenFields.indexOf(field);
+
+ // is currently selected
+ if (idx > -1) {
+ $scope.hiddenFields.splice(idx, 1);
+ } else {
+ $scope.hiddenFields.push(field);
+ }
+ };
+
+
+ $scope.edit = function (schema) {
+ editorService.open(
+ {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/dialogs/entriessettings.html",
+ schema: schema,
+ toggle: $scope.toggleSelection,
+ hiddenFields: $scope.hiddenFields,
+ filter: $scope.filter,
+ size: 'medium'
+ });
+ };
+
+ // $scope.pagination = [];
+
+
+ function nextPage(pageNumber) {
+ $scope.filter.startIndex++;
+ $scope.loadRecords($scope.filter);
+ }
+
+ function prevPage(pageNumber) {
+ $scope.filter.startIndex--;
+ $scope.loadRecords($scope.filter);
+ }
+
+ function goToPageNumber(pageNumber) {
+ // do magic here
+ $scope.filter.startIndex = pageNumber;
+ $scope.loadRecords($scope.filter);
+ }
+
+ function viewEntryDetails(schema, entry, event) {
+
+ vm.selectedEntry = {};
+
+ var entryIndex = $scope.records.results.indexOf(entry);
+ // get the count of the entry across the pagination: entries pr page * page index + entry index
+ var entryCount = $scope.filter.length * ($scope.filter.startIndex - 1) + (entryIndex + 1);
+
+ vm.selectedEntry = entry;
+ vm.selectedEntry.index = entryIndex;
+ vm.selectedEntry.entryCount = entryCount;
+ vm.selectedEntry.details = [];
+
+ if (schema && entry) {
+ for (var index = 0; index < schema.length; index++) {
+ var schemaItem = schema[index];
+
+ // Select the value from the entry.fields array
+ var valueItem = entry.fields[index];
+
+ // Create new object to push into details above (so our angular view is much neater)
+ var itemToPush = {
+ name: schemaItem.name,
+ value: valueItem,
+ viewName: schemaItem.view,
+ view: '/app_plugins/umbracoforms/Backoffice/common/rendertypes/' + schemaItem.view + '.html',
+ containsSensitiveData: schemaItem.containsSensitiveData
+ };
+
+ var excludeItems = ["member", "state", "created", "updated"];
+ var found = excludeItems.indexOf(schemaItem.id);
+
+ if (excludeItems.indexOf(schemaItem.id) === -1) {
+ vm.selectedEntry.details.push(itemToPush);
+ }
+
+ }
+ }
+
+ vm.showEntryDetails = true;
+
+ if (event) {
+ event.stopPropagation();
+ }
+ }
+
+ function closeEntryDetails() {
+ vm.selectedEntry = {};
+ vm.showEntryDetails = false;
+ }
+
+ function nextEntryDetails() {
+
+ // get the current index and plus 1 to get the next item in the array
+ var nextEntryIndex = vm.selectedEntry.index + 1;
+ var entriesCount = $scope.records.results.length;
+ var currentPage = $scope.filter.startIndex;
+ var totalNumberOfPages = $scope.records.totalNumberOfPages;
+
+ if (nextEntryIndex < entriesCount) {
+
+ var entry = $scope.records.results[nextEntryIndex];
+ viewEntryDetails($scope.records.schema, entry);
+
+ } else if (totalNumberOfPages > 1 && currentPage < totalNumberOfPages) {
+
+ $scope.filter.startIndex++;
+ vm.pagination.pageNumber++;
+
+ recordResource.getRecords($scope.filter).then(function (response) {
+ $scope.records = response.data;
+ $scope.allIsChecked = ($scope.selectedRows.length >= $scope.records.results.length);
+ vm.pagination.totalPages = response.data.totalNumberOfPages;
+
+ limitRecordFields($scope.records);
+
+ // get the first item from the new collection
+ var entry = $scope.records.results[0];
+ viewEntryDetails($scope.records.schema, entry);
+
+ });
+
+ }
+
+ }
+
+ function prevEntryDetails() {
+
+
+ var prevEntryIndex = vm.selectedEntry.index - 1;
+ var totalNumberOfPages = $scope.records.totalNumberOfPages;
+ var currentPage = $scope.filter.startIndex;
+
+ if (vm.selectedEntry.index > 0) {
+
+ var entry = $scope.records.results[prevEntryIndex];
+ viewEntryDetails($scope.records.schema, entry);
+
+ } else if (totalNumberOfPages > 1 && currentPage !== 1) {
+
+ $scope.filter.startIndex--;
+ vm.pagination.pageNumber--;
+
+ recordResource.getRecords($scope.filter).then(function (response) {
+ $scope.records = response.data;
+ $scope.allIsChecked = ($scope.selectedRows.length >= $scope.records.results.length);
+ vm.pagination.totalPages = response.data.totalNumberOfPages;
+
+ limitRecordFields($scope.records);
+
+ // get the last item from the new collection
+ var lastEntryIndex = $scope.records.results.length - 1;
+ var entry = $scope.records.results[lastEntryIndex];
+ viewEntryDetails($scope.records.schema, entry);
+
+ });
+
+ }
+ }
+
+ function datePickerChange(dateRange) {
+ $scope.filter.startDate = dateRange.startDate;
+ $scope.filter.endDate = dateRange.endDate;
+ $scope.filterChanged();
+ }
+
+ function toggleRecordState(recordState) {
+ if (recordState.isChecked) {
+ $scope.filter.states.push(recordState.name);
+ } else {
+ var index = $scope.filter.states.indexOf(recordState.name);
+ if (index !== -1) {
+ $scope.filter.states.splice(index, 1);
+ }
+ }
+ $scope.filterChanged();
+ }
+
+ $scope.next = function () {
+ $scope.filter.startIndex++;
+ };
+
+ $scope.prev = function () {
+ $scope.filter.startIndex--;
+ };
+
+ $scope.goToPage = function (index) {
+ $scope.filter.startIndex = index;
+ };
+
+
+ $scope.search = _.debounce(function (resetIndex) {
+
+ // Set loading to true
+ $scope.loading = true;
+
+ $scope.reset(resetIndex);
+
+ $scope.$apply(function () {
+ recordResource.getRecords($scope.filter).then(function (response) {
+ // Got results back - set loading to false]
+ $scope.loading = false;
+
+ $scope.records = response.data;
+ vm.pagination.totalPages = response.data.totalNumberOfPages;
+
+ limitRecordFields($scope.records);
+
+ });
+ });
+
+
+ }, 300);
+
+
+ $scope.filterChanged = function () {
+ var resetIndex = true;
+ $scope.search(resetIndex);
+ };
+
+ $scope.loadRecords = function (filter, append) {
+
+ // Set loading to true
+ $scope.loading = true;
+
+ recordResource.getRecords(filter).then(function (response) {
+ // Got response from server
+ $scope.loading = false;
+
+ if (append) {
+ $scope.records = $scope.records.results.concat(response.data.results);
+ } else {
+ $scope.records = response.data;
+ }
+
+ $scope.allIsChecked = ($scope.selectedRows.length >= $scope.records.results.length);
+
+ limitRecordFields($scope.records);
+
+ vm.pagination.totalPages = response.data.totalNumberOfPages;
+
+ });
+ };
+
+ $scope.loadRecords($scope.filter);
+
+ function limitRecordFields(records) {
+ // function to limit how many fields are
+ // shown in the entries table
+
+ var falseFromIndex = 2;
+ var falseToIndex = records.schema.length - 4;
+ var trueFalseArray = [];
+
+ // make array of true/false
+ angular.forEach(records.schema, function (schema, index) {
+ if (index <= falseFromIndex || index >= falseToIndex) {
+ trueFalseArray.push(true);
+ } else {
+ trueFalseArray.push(false);
+ }
+ });
+
+ // set array for schema
+ records.showSchemaArray = trueFalseArray;
+
+ // set array for row fields
+ angular.forEach(records.results, function (result) {
+ result.showRecordsArray = trueFalseArray;
+ });
+ }
+
+ $scope.reset = function (resetIndex) {
+ $scope.selectedRows.length = 0;
+ $scope.allIsChecked = false;
+
+ if (resetIndex) {
+ $scope.filter.startIndex = 1;
+ }
+
+ };
+
+ $scope.clearSelection = function () {
+ $scope.selectedRows.length = 0;
+ vm.allIsChecked = false;
+
+ for (var i = 0; i < $scope.records.results.length; i++) {
+ var row = $scope.records.results[i];
+ row.selected = false;
+ }
+ };
+
+ $scope.more = function () {
+ $scope.filter.startIndex++;
+ $scope.loadRecords($scope.filter, true);
+ };
+
+ $scope.selectedRows = [];
+
+ $scope.toggleRow = function (row) {
+ row.selected = !row.selected;
+ if (row.selected) {
+ $scope.selectedRows.push(row.id);
+ $scope.allIsChecked = ($scope.selectedRows.length >= $scope.records.results.length);
+ } else {
+ var i = $scope.selectedRows.indexOf(row.id);
+ $scope.selectedRows.splice(i, 1);
+ $scope.allIsChecked = false;
+ }
+ };
+
+ $scope.toggleRowLegacy = function (row) {
+ if (row.selected) {
+ $scope.selectedRows.push(row.id);
+ $scope.allIsChecked = ($scope.selectedRows.length >= $scope.records.results.length);
+ } else {
+ var i = $scope.selectedRows.indexOf(row.id);
+ $scope.selectedRows.splice(i, 1);
+ $scope.allIsChecked = false;
+ }
+ };
+
+ $scope.allIsChecked = false;
+ $scope.toggleAllLegacy = function ($event) {
+ var checkbox = $event.target;
+ $scope.selectedRows.length = 0;
+
+ for (var i = 0; i < $scope.records.results.length; i++) {
+ var entity = $scope.records.results[i];
+ entity.selected = checkbox.checked;
+
+ if (checkbox.checked) {
+ $scope.selectedRows.push(entity.id);
+ }
+ }
+ };
+
+ $scope.toggleAll = function () {
+
+ var newValue = !$scope.allIsChecked;
+
+ for (var i = 0; i < $scope.records.results.length; i++) {
+ var entity = $scope.records.results[i];
+
+ if (entity.selected !== newValue) {
+ $scope.toggleRow(entity);
+ }
+
+ }
+
+ };
+
+ $scope.executeRecordSetAction = function (action) {
+
+ // Get the data we need in order to send to the API Endpoint
+ var model = {
+ formId: $scope.form.id,
+ recordKeys: $scope.selectedRows,
+ actionId: action.id
+ };
+
+ var performAction = function () {
+
+ recordResource.executeRecordSetAction(model).then(function (response) {
+ $scope.reset(true);
+ $scope.loadRecords($scope.filter, false);
+ notificationsService.success("Excuted Action", "Successfully executed action " + action.name);
+ }, function (err) {
+ // Error Function - so get an error response from API
+ notificationsService.error("Excuted Action", "Failed to execute action " + action.name + " due to error: " + err);
+ });
+ };
+
+ // Check if the action we are running requires a confirmation and that we have a message to be displayed.
+ if (action.needsConfirm && action.confirmMessage.length > 0) {
+
+ var overlay = {
+ view: "confirm",
+ title: "Confirmation",
+ content: action.confirmMessage,
+ closeButtonLabel: "No",
+ submitButtonLabel: "Yes",
+ submitButtonStyle: "danger",
+ close: function () {
+ overlayService.close();
+ },
+ submit: function () {
+ performAction();
+ overlayService.close();
+ }
+ };
+ overlayService.open(overlay);
+ }
+ else {
+ // No confirmation required, so execute immediately.
+ performAction();
+ }
+ };
+});
+
+angular.module("umbraco").controller("UmbracoForms.Editors.Form.EntriesSettingsController",
+ function($scope, $log, $timeout, exportResource, utilityService, editorService){
+
+ //The Form ID is found in the filter object we pass into the dialog
+ var formId = $scope.model.filter.form;
+
+ exportResource.getExportTypes(formId).then(function(response){
+ $scope.exportTypes = response.data;
+ });
+
+ $scope.close = function(){
+ editorService.closeAll();
+ };
+
+ $scope.export = function(type, filter){
+ filter.exportType = type.id;
+
+ //Check if we need to do server time offset to the date we are displaying
+ var serverTimeNeedsOffsetting = utilityService.serverTimeNeedsOffsetting();
+
+ if(serverTimeNeedsOffsetting) {
+ // Use the localOffset to correct the server times with the client browser's offset
+ filter.localTimeOffset = new Date().getTimezoneOffset();
+ }
+
+ exportResource.generateExport(filter).then(function(response){
+
+ var url = exportResource.getExportUrl(response.data.formId, response.data.fileName);
+
+ var iframe = document.createElement('iframe');
+ iframe.id = "hiddenDownloadframe";
+ iframe.style.display = 'none';
+ document.body.appendChild(iframe);
+ iframe.src= url;
+
+ //remove all traces
+ $timeout(function(){
+ document.body.removeChild(iframe);
+ }, 1000);
+
+ });
+ };
+
+ });
+
+/**
+ * @ngdoc controller
+ * @name UmbracoForms.Overlays.FieldsetSettingsOverlay
+ * @function
+ *
+ * @description
+ * The controller for the Fieldset Settings dialog
+ */
+
+(function () {
+ "use strict";
+
+ function FieldsetSettingsOverlay($scope, formService, editorService) {
+
+ var vm = this;
+
+ vm.actionTypes = [];
+ vm.logicTypes = [];
+ vm.operators = [];
+
+ vm.deleteConditionRule = deleteConditionRule;
+ vm.addConditionRule = addConditionRule;
+ vm.conditionFieldSelected = conditionFieldSelected;
+ vm.canAddColumn = canAddColumn;
+ vm.addColumn = addColumn;
+ vm.removeColumn = removeColumn;
+ vm.toggleConditions = toggleConditions;
+ vm.close = close;
+ vm.submit = submit;
+
+ var oldFieldset = "";
+ var oldContainers = "";
+
+ function init() {
+ vm.actionTypes = formService.getActionTypes();
+ vm.logicTypes = formService.getLogicTypes();
+ vm.operators = formService.getOperators();
+
+ if (!$scope.model.fieldset.condition) {
+ $scope.model.fieldset.condition = {};
+ $scope.model.fieldset.condition.actionType = vm.actionTypes[0].value;
+ $scope.model.fieldset.condition.logicType = vm.logicTypes[0].value;
+ }
+
+ oldFieldset = angular.copy($scope.model.fieldset);
+ oldContainers = angular.copy($scope.model.fieldset.containers);
+ }
+
+ function deleteConditionRule(rules, rule) {
+ formService.deleteConditionRule(rules, rule);
+ }
+
+ function toggleConditions() {
+ $scope.model.fieldset.condition.enabled = !$scope.model.fieldset.condition.enabled;
+ }
+
+ function addConditionRule(condition) {
+ formService.addEmptyConditionRule(condition);
+ // set default operator
+ var lastIndex = condition.rules.length - 1;
+ condition.rules[lastIndex].operator = vm.operators[0].value;
+ }
+
+ function conditionFieldSelected(selectedField, rule) {
+ formService.populateConditionRulePrevalues(selectedField, rule, $scope.model.fields);
+ }
+
+ function canAddColumn() {
+ var index = $scope.model.fieldset.containers.length;
+ return index < parseInt(Umbraco.Sys.ServerVariables.umbracoPlugins.forms.maxNumberOfColumnsInFormGroup);
+ }
+
+ function addColumn() {
+ if (!canAddColumn()) {
+ return;
+ }
+ var index = $scope.model.fieldset.containers.length;
+ formService.addContainer($scope.model.fieldset, index);
+ }
+
+ function removeColumn(container) {
+ formService.deleteContainer($scope.model.fieldset, container);
+ }
+
+ function close(model) {
+
+ $scope.model.fieldset.containers = oldContainers;
+ $scope.model.fieldset = oldFieldset;
+
+ editorService.close();
+ };
+
+ function submit() {
+ editorService.close();
+ };
+
+ init();
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.Overlays.FieldsetSettingsOverlay", FieldsetSettingsOverlay);
+
+})();
+
+/**
+ * @ngdoc controller
+ * @name UmbracoForms.Overlays.FieldSettingsOverlay
+ * @function
+ *
+ * @description
+ * The controller for the Field Settings dialog
+ */
+
+(function () {
+ "use strict";
+
+ function FieldSettingsOverlay($scope, localizationService, formService, userService, editorService, formHelper) {
+
+ var vm = this;
+
+ vm.showValidationPattern = false;
+ vm.focusOnPatternField = false;
+ vm.focusOnMandatoryField = false;
+ vm.canEditSensitiveData = false; //Default to false - until we check with the server for this user to see if they have rights to edit/set this property
+ vm.loading = true; //We need to do a serverside call lookup at init/active to check is user has access to sensitive data
+ vm.selectedValidationType = {};
+ vm.actionTypes = [];
+ vm.logicTypes = [];
+ vm.operators = [];
+ vm.mandatoryToggleText = "Field is mandatory";
+
+
+ var localizeValidation = localizationService.localizeMany(
+ [
+ "validation_validateAsEmail",
+ "validation_validateAsNumber",
+ "validation_validateAsUrl",
+ "validation_enterCustomValidation",
+ "validation_fieldIsMandatory"]
+ ).then(function (labels) {
+ vm.validationTypes = [{
+ "name": labels[0],
+ "key": "email",
+ "pattern": "^[a-zA-Z0-9_\.\+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-\.]+$",
+ "enableEditing": true
+ }, {
+ "name": labels[1],
+ "key": "number",
+ "pattern": "^[0-9]*$",
+ "enableEditing": true
+ }, {
+ "name": labels[2],
+ "key": "url",
+ "pattern": "https?\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}",
+ "enableEditing": true
+ }, {
+ "name": labels[3],
+ "key": "custom",
+ "pattern": "",
+ "enableEditing": true
+ }];
+
+ vm.mandatoryToggleText = labels[4];
+ });
+
+ vm.changeValidationType = changeValidationType;
+ vm.changeValidationPattern = changeValidationPattern;
+ vm.openFieldTypePicker = openFieldTypePicker;
+ vm.deleteConditionRule = deleteConditionRule;
+ vm.addConditionRule = addConditionRule;
+ vm.getPrevalues = getPrevalues;
+ vm.conditionFieldSelected = conditionFieldSelected;
+ vm.submitOnEnter = submitOnEnter;
+ vm.submit = submit;
+ vm.close = close;
+ vm.toggleConditions = toggleConditions;
+ vm.toggleMandatory = toggleMandatory;
+ vm.toggleSensitiveData = toggleSensitiveData;
+ vm.toggleAllowMultipleFileUploads = toggleAllowMultipleFileUploads;
+ vm.matchValidationType = matchValidationType;
+
+
+ //Creating duplicate of the fields array on the model
+ //As the select for the conditions needs to ensure it does not include itself
+
+ //Need to use angular.copy() otherwise when we remove item in fieldConditions its data-binding back down to the original model.fields
+ vm.fieldConditions = angular.copy($scope.model.fields);
+
+ //Trying not to use _underscore.js
+ //Loop over array until we find the item where the ID matches & remove object from the array
+ for (var i = 0; i < vm.fieldConditions.length; i++) {
+ if (vm.fieldConditions[i].id === $scope.model.field.id) {
+ vm.fieldConditions.splice(i, 1);
+ break;
+ }
+ }
+
+
+
+ function activate() {
+ vm.actionTypes = formService.getActionTypes();
+ vm.logicTypes = formService.getLogicTypes();
+ vm.operators = formService.getOperators();
+
+
+ //Verify that the current user is allowed to view & change the property 'containsSensitiveData'
+ userService.getCurrentUser().then(function (user) {
+
+ //Set the API controller response on the Angular ViewModel
+ vm.canEditSensitiveData = user.userGroups.indexOf("sensitiveData") !== -1;
+
+ //Got a response back from promise - so lets load up the UI
+ vm.loading = false;
+ });
+
+ if (!$scope.model.field.condition) {
+ $scope.model.field.condition = {};
+ $scope.model.field.condition.actionType = vm.actionTypes[0].value;
+ $scope.model.field.condition.logicType = vm.logicTypes[0].value;
+ }
+
+ matchValidationType();
+
+ // If the prevalue source Id hasn't been defined, ensure angularjs doesn't add an initial empty
+ // select list option by initialising to the first empty value (the 'Choose...' prompt.)
+ // See: https://stackoverflow.com/a/12654812/489433
+ if (!$scope.model.field.prevalueSourceId) {
+ $scope.model.field.prevalueSourceId = '00000000-0000-0000-0000-000000000000';
+ }
+ }
+
+ function changeValidationPattern() {
+ matchValidationType();
+ }
+
+ function openFieldTypePicker(field) {
+
+ vm.focusOnMandatoryField = false;
+
+ var fieldTypePicker = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/fieldtypepicker/field-type-picker.html",
+ title: "Choose answer type",
+ hideSubmitButton: true,
+ size: "medium",
+ submit: function (model) {
+
+ formService.loadFieldTypeSettings(field, model.fieldType);
+
+ // this should be removed in next major version
+ field.removePrevalueEditor = true;
+
+ editorService.close();
+ },
+ close: function (model) {
+ editorService.close();
+ }
+ };
+ editorService.open(fieldTypePicker);
+ }
+
+ function matchValidationType() {
+
+ if ($scope.model.field.regex !== null && $scope.model.field.regex !== "" && $scope.model.field.regex !== undefined) {
+
+ return localizeValidation.then(function () {
+ var match = false;
+ // find and show if a match from the list has been chosen
+ angular.forEach(vm.validationTypes, function (validationType, index) {
+ if ($scope.model.field.regex === validationType.pattern) {
+ vm.selectedValidationType = validationType;
+ vm.showValidationPattern = true;
+ match = true;
+ }
+ });
+ if (!match) {
+ // if there is no match - choose the custom validation option.
+ angular.forEach(vm.validationTypes, function (validationType) {
+ if (validationType.key === "custom") {
+ vm.selectedValidationType = validationType;
+ vm.showValidationPattern = true;
+ }
+ });
+ }
+ });
+ }
+
+ }
+
+ function toggleConditions() {
+ $scope.model.field.condition.enabled = !$scope.model.field.condition.enabled;
+ }
+ function toggleSensitiveData() {
+ $scope.model.field.containsSensitiveData = !$scope.model.field.containsSensitiveData;
+ }
+ function toggleMandatory() {
+ $scope.model.field.mandatory = !$scope.model.field.mandatory;
+ }
+ function toggleAllowMultipleFileUploads() {
+ $scope.model.field.allowMultipleFileUploads = !$scope.model.field.allowMultipleFileUploads;
+ }
+ function changeValidationType(selectedValidationType) {
+
+ if (selectedValidationType) {
+ $scope.model.field.regex = selectedValidationType.pattern;
+ vm.showValidationPattern = true;
+
+ // set focus on textarea
+ if (selectedValidationType.key === "custom") {
+ vm.focusOnPatternField = true;
+ }
+
+ } else {
+ $scope.model.field.regex = "";
+ vm.showValidationPattern = false;
+ }
+
+ }
+
+ function conditionFieldSelected(selectedField, rule) {
+ formService.populateConditionRulePrevalues(selectedField, rule, $scope.model.fields);
+ }
+
+ function deleteConditionRule(rules, rule) {
+ formService.deleteConditionRule(rules, rule);
+ }
+
+ function addConditionRule(condition) {
+ formService.addEmptyConditionRule(condition);
+ // set default operator
+ var lastIndex = condition.rules.length - 1;
+ condition.rules[lastIndex].operator = vm.operators[0].value;
+ }
+
+ function getPrevalues(field) {
+ formService.loadFieldTypePrevalues(field);
+ }
+
+ function submitOnEnter(event) {
+ if (event && event.keyCode === 13) {
+ submit();
+ }
+ }
+
+ function submit() {
+ if ($scope.model.submit) {
+ if (formHelper.submitForm({ scope: $scope })) {
+ $scope.model.submit($scope.model);
+ }
+ }
+ }
+
+ function close() {
+ if ($scope.model.close) {
+ $scope.model.close();
+ }
+ }
+
+ activate();
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.Overlays.FieldSettingsOverlay", FieldSettingsOverlay);
+
+})();
+
+(function() {
+ "use strict";
+
+ function FieldTypePickerOverlayController($scope, formResource, formService) {
+
+ var vm = this;
+
+ vm.fieldTypes = [];
+ vm.searchTerm = "";
+
+ vm.pickFieldType = pickFieldType;
+ vm.filterItems = filterItems;
+ vm.showDetailsOverlay = showDetailsOverlay;
+ vm.hideDetailsOverlay = hideDetailsOverlay;
+ vm.close = close;
+
+ function init() {
+
+ // get workflows with settings
+ formResource.getAllFieldTypesWithSettings()
+ .then(function (response) {
+ vm.fieldTypes = response.data;
+ });
+ }
+
+
+ function pickFieldType(selectedFieldType) {
+ $scope.model.fieldType = selectedFieldType;
+ $scope.model.submit($scope.model);
+ }
+
+ function filterItems() {
+ // clear item details
+ $scope.model.itemDetails = null;
+ }
+
+ function showDetailsOverlay(workflowType) {
+
+ var workflowDetails = {};
+ workflowDetails.icon = workflowType.icon;
+ workflowDetails.title = workflowType.name;
+ workflowDetails.description = workflowType.description;
+
+ $scope.model.itemDetails = workflowDetails;
+
+ }
+
+ function hideDetailsOverlay() {
+ $scope.model.itemDetails = null;
+ }
+
+ function close() {
+ if ($scope.model.close) {
+ $scope.model.close();
+ }
+ }
+
+ init();
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.Overlays.FieldTypePickerOverlayController", FieldTypePickerOverlayController);
+})();
+
+(function () {
+ "use strict";
+
+ function FormPickerOverlayController($scope, $http, formPickerResource, notificationsService) {
+
+ var vm = this;
+
+ vm.loading = false;
+ vm.forms = [];
+ vm.error = null;
+
+ vm.pickForm = pickForm;
+
+ function onInit() {
+
+ vm.loading = true;
+
+ // set default title
+ if(!$scope.model.title) {
+ $scope.model.title = "Select a form";
+ }
+
+ // we don't need the submit button for a multi picker because we submit on select for the single picker
+ if(!$scope.model.multiPicker) {
+ $scope.model.hideSubmitButton = true;
+ }
+
+ // make sure we have an array to push to
+ if(!$scope.model.selectedForms) {
+ $scope.model.selectedForms = [];
+ }
+
+ // get the available forms
+ formPickerResource.getFormsForPicker($scope.model.allowedForms).then(function (response) {
+ vm.forms = response;
+ vm.loading = false;
+ }, function (err) {
+ //Error callback from - getting all Forms
+ //Unsure what exception/error we would encounter
+ //Would be just an empty collection if we cant find/get any
+ vm.error = "An Error has occured while loading!";
+ vm.loading = false;
+ });
+ }
+
+ function pickForm(form) {
+
+ if(form.selected) {
+
+ // if form is already selected we deselect and remove it from the picked forms array
+ form.selected = false;
+
+ angular.forEach($scope.model.selectedForms, function(selectedForm, index){
+ if(selectedForm.id === form.id) {
+ $scope.model.selectedForms.splice(index, 1);
+ }
+ });
+
+ } else {
+
+ // set selected flag so we can show checkmark icon
+ form.selected = true;
+
+ // store selected form in an array
+ $scope.model.selectedForms.push(form);
+
+ // if it's not a multipicker - submit the overlay
+ if(!$scope.model.multiPicker) {
+ $scope.model.submit($scope.model);
+ }
+
+ }
+
+ }
+
+ onInit();
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.FormPickerOverlayController", FormPickerOverlayController);
+
+})();
+
+(function () {
+ "use strict";
+
+ function ThemePickerOverlayController($scope, themePickerResource) {
+
+ var vm = this;
+
+ vm.loading = false;
+ vm.themes = [];
+ vm.error = null;
+
+ vm.pickTheme = pickTheme;
+
+ function onInit() {
+
+ vm.loading = true;
+
+ // set default title
+ if(!$scope.model.title) {
+ $scope.model.title = "Select a theme";
+ }
+
+ // we don't need the submit button for a multi picker because we submit on select for the single picker
+ if(!$scope.model.multiPicker) {
+ $scope.model.hideSubmitButton = true;
+ }
+
+ // make sure we have an array to push to
+ if(!$scope.model.selectedThemes) {
+ $scope.model.selectedThemes = [];
+ }
+
+ // get the available forms
+ themePickerResource.getThemes().then(function (response) {
+ vm.themes = response;
+ vm.loading = false;
+ }, function (err) {
+ //Error callback from - getting all Forms
+ //Unsure what exception/error we would encounter
+ //Would be just an empty collection if we cant find/get any
+ vm.error = "An Error has occured while loading!";
+ vm.loading = false;
+ });
+ }
+
+ function pickTheme(theme) {
+
+ if(theme.selected) {
+
+ // if form is already selected we deselect and remove it from the picked forms array
+ theme.selected = false;
+
+ angular.forEach($scope.model.selectedThemes, function(selectedTheme, index){
+ if(selectedTheme.name === theme.name) {
+ $scope.model.selectedThemes.splice(index, 1);
+ }
+ });
+
+ } else {
+
+ // set selected flag so we can show checkmark icon
+ theme.selected = true;
+
+ // store selected form in an array
+ $scope.model.selectedThemes.push(theme);
+
+ // if it's not a multipicker - submit the overlay
+ if(!$scope.model.multiPicker) {
+ $scope.model.submit($scope.model);
+ }
+
+ }
+
+ }
+
+ onInit();
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.ThemePickerOverlayController", ThemePickerOverlayController);
+
+})();
+
+(function () {
+ "use strict";
+
+ function WorkflowSettingsOverlayController($scope, workflowResource, editorService) {
+
+ var vm = this;
+
+ vm.workflowTypes = [];
+ vm.focusWorkflowName = true;
+
+ var prepareDataForEdit = function () {
+ // Transform includeSensitiveData field from an integer derived from an enum to a boolean,
+ // for user selection via a check-box.
+ $scope.model.workflow.includeSensitiveData = $scope.model.workflow.includeSensitiveData == 1 ? true : false;
+ };
+
+ if ($scope.model.workflow) {
+ prepareDataForEdit();
+ }
+
+ if ($scope.model.workflowType && $scope.model.workflowType.id) {
+ workflowResource.getScaffoldWorkflowType($scope.model.workflowType.id).then(function (response) {
+ $scope.model.workflow = response.data;
+ prepareDataForEdit();
+ });
+ }
+
+ vm.toggleActive = function () {
+ $scope.model.workflow.active = !$scope.model.workflow.active;
+ }
+
+ vm.toggleIncludeSensitiveData = function () {
+ $scope.model.workflow.includeSensitiveData = !$scope.model.workflow.includeSensitiveData;
+ }
+
+ vm.close = function () {
+ editorService.close();
+ };
+
+ vm.submit = function () {
+ $scope.model.submit($scope.model);
+ };
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.Overlays.WorkflowSettingsOverlayController", WorkflowSettingsOverlayController);
+})();
+
+(function () {
+ "use strict";
+
+ function WorkflowsOverviewOverlayController($scope, workflowResource, notificationsService, editorService) {
+
+ var vm = this;
+ // massive hack to fix submit when pressing enter
+ vm.focusOverlay = true;
+
+ vm.openWorkflowsTypesOverlay = openWorkflowsTypesOverlay;
+ vm.editWorkflow = editWorkflow;
+ vm.removeWorkflow = removeWorkflow;
+ vm.editSubmitMessageWorkflow = editSubmitMessageWorkflow;
+
+ if(!$scope.model.formWorkflows.onSubmit){
+ $scope.model.formWorkflows.onSubmit = [];
+ }
+ if(!$scope.model.formWorkflows.onApprove){
+ $scope.model.formWorkflows.onApprove = [];
+ }
+
+ vm.workflowsSortableOptions = {
+ distance: 10,
+ tolerance: "pointer",
+ connectWith: ".umb-forms-workflows__sortable-wrapper",
+ opacity: 0.7,
+ scroll: true,
+ cursor: "move",
+ zIndex: 6000,
+ handle: ".sortable-handle",
+ items: ".sortable",
+ placeholder: "umb-forms-workflow__workflow-placeholder",
+ start: function (e, ui) {
+ ui.placeholder.height(ui.item.height());
+ },
+ stop: function (event, ui) {
+ updateSortOrder($scope.model.formWorkflows.onSubmit);
+ updateSortOrder($scope.model.formWorkflows.onApprove);
+ }
+ };
+
+ function updateSortOrder(array) {
+ var sortOrder = 0;
+ for (var i = 0; i < array.length; i++) {
+ var arrayItem = array[i];
+ if (arrayItem.isDeleted === false) {
+ arrayItem.sortOrder = sortOrder;
+ sortOrder++;
+ }
+ }
+ }
+
+ function openWorkflowsTypesOverlay(workflowTypeArray) {
+ // set overlay settings and open overlay
+ var workflowsTypesOverlay = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-types.html",
+ title: "Choose workflow",
+ fields: $scope.model.fields,
+ size: "medium",
+ submit: function (model) {
+
+ // set sortOrder
+ workflowTypeArray.push(model.workflow);
+ updateSortOrder(workflowTypeArray);
+
+ editorService.close();
+ },
+ close: function () {
+ editorService.close();
+ }
+ };
+
+ editorService.open(workflowsTypesOverlay);
+ }
+
+ function editWorkflow(workflow) {
+ var workflowSettingsOverlay = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-settings.html",
+ title: workflow.name,
+ workflow: workflow,
+ fields: $scope.model.fields,
+ size: "medium",
+ submit: function (model) {
+
+ //Validate settings
+ workflowResource.validateWorkflowSettings(model.workflow).then(function (response) {
+ if (response.data.length > 0) {
+ angular.forEach(response.data, function (error) {
+ notificationsService.error("Workflow failed to save", error.Message);
+ });
+ } else {
+ editorService.close();
+ }
+
+ });
+ }
+ };
+
+ editorService.open(workflowSettingsOverlay);
+ }
+
+ function editSubmitMessageWorkflow() {
+
+ var submitMessageWorkflowOverlay = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/workflows/submit-message-workflow-settings.html",
+ title: "Message on submit",
+ messageOnSubmit: $scope.model.messageOnSubmit,
+ goToPageOnSubmit: $scope.model.goToPageOnSubmit,
+ size: "medium",
+ submit: function (model) {
+
+ $scope.model.messageOnSubmit = model.messageOnSubmit;
+ $scope.model.goToPageOnSubmit = model.goToPageOnSubmit;
+ editorService.close();
+ },
+ close: function () {
+ editorService.close();
+ }
+ };
+
+ editorService.open(submitMessageWorkflowOverlay);
+ }
+
+ function removeWorkflow(workflow, event, workflowTypeArray) {
+ workflow.isDeleted = true;
+ updateSortOrder(workflowTypeArray);
+ event.stopPropagation();
+ }
+
+ vm.close = function () {
+ $scope.model.close();
+ }
+
+ vm.submit = function () {
+ $scope.model.submit($scope.model);
+ }
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.Overlays.WorkflowsOverviewOverlayController", WorkflowsOverviewOverlayController);
+})();
+
+(function() {
+ "use strict";
+
+ function WorkflowTypesOverlayController($scope, workflowResource, notificationsService, editorService) {
+
+ var vm = this;
+
+ vm.workflowTypes = [];
+ vm.searchTerm = "";
+
+ vm.pickWorkflowType = pickWorkflowType;
+ vm.filterItems = filterItems;
+ vm.showDetailsOverlay = showDetailsOverlay;
+ vm.hideDetailsOverlay = hideDetailsOverlay;
+
+ function init() {
+
+ // get workflows with settings
+ workflowResource.getAllWorkflowTypesWithSettings()
+ .then(function(response) {
+ vm.workflowTypes = response.data;
+ setDefaultWorkflowIcon(vm.workflowTypes);
+ });
+
+ }
+
+ function setDefaultWorkflowIcon(workflowTypes) {
+
+ for(var i = 0; i < workflowTypes.length; i++) {
+ var workflowType = workflowTypes[i];
+ if(!workflowType.icon) {
+ workflowType.icon = "icon-mindmap";
+ }
+ }
+ }
+
+ function pickWorkflowType(selectedWorkflowType) {
+
+ // set overlay settings + open overlay
+ var workflowSettingsOverlay = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-settings.html",
+ title: selectedWorkflowType.name,
+ workflow: $scope.model.workflow,
+ workflowType: selectedWorkflowType,
+ fields: $scope.model.fields,
+ size: "medium",
+ submit: function(model) {
+ workflowResource.validateWorkflowSettings(model.workflow).then(function(response){
+ if (response.data.length > 0) {
+ angular.forEach(response.data, function (error) {
+ notificationsService.error("Workflow failed to save", error.Message);
+ });
+ } else {
+
+ //Need to add the properties to the $scope from this submitted model
+ $scope.model.workflow = model.workflow;
+
+ // submit overlay and return the model
+ $scope.model.submit($scope.model);
+
+ // close the infinite editor
+ editorService.close();
+ }
+
+ });
+ }
+ };
+
+ editorService.open(workflowSettingsOverlay);
+ }
+
+ function filterItems() {
+ // clear item details
+ $scope.model.itemDetails = null;
+ }
+
+ function showDetailsOverlay(workflowType) {
+
+ var workflowDetails = {};
+ workflowDetails.icon = workflowType.icon;
+ workflowDetails.title = workflowType.name;
+ workflowDetails.description = workflowType.description;
+
+ $scope.model.itemDetails = workflowDetails;
+
+ }
+
+ function hideDetailsOverlay() {
+ $scope.model.itemDetails = null;
+ }
+
+ vm.close = function() {
+ $scope.model.close();
+ }
+
+ init();
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.Overlays.WorkflowTypesOverlayController", WorkflowTypesOverlayController);
+})();
+
+/**
+ * @ngdoc controller
+ * @name UmbracoForms.Editors.Form.FormDesignController
+ * @function
+ *
+ * @description
+ * The controller for the Umbraco Forns type editor
+ */
+(function () {
+ "use strict";
+
+ function formDesignController($scope, formResource, userService, securityResource) {
+
+ var vm = this;
+ var currentUser = {};
+
+ vm.currentPage = {};
+ vm.security = {};
+
+ //Get PreValues for the current form we are editing/designing
+ formResource.getPrevalueSources().then(function (resp) {
+ vm.prevaluesources = resp.data;
+
+ formResource.getAllFieldTypesWithSettings().then(function (resp) {
+ vm.fieldtypes = resp.data;
+ vm.ready = true;
+ });
+ });
+
+ userService.getCurrentUser().then(function (response) {
+ currentUser = response;
+
+ //Now we can make a call to form securityResource
+ securityResource.getByUserId(currentUser.id).then(function (response) {
+ vm.security = response.data;
+ });
+
+ });
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.Editors.Form.FormDesignController", formDesignController);
+})();
+
+(function () {
+ "use strict";
+
+ function FormSecurityEditController($scope, $routeParams, securityResource, notificationsService, navigationService) {
+
+ var vm = this;
+
+ vm.page = { name: "Form Security" };
+ vm.security = {};
+ vm.save = save;
+ vm.loading = true;
+
+ function init() {
+
+ // Ensure the current item we are editing is highlighted in the tree.
+ // Note: doesn't work for the admin user (as this leads to a path of -1 which is also used for the tree's root node).
+ navigationService.syncTree({ tree: "formsecurity", path: [String($routeParams.id)], forceReload: true });
+
+ securityResource.getByUserId($routeParams.id).then(function (resp) {
+ vm.security = resp.data;
+ vm.loading = false;
+ });
+ }
+
+ vm.toggleManageForms = function () {
+ vm.security.userSecurity.manageForms = !vm.security.userSecurity.manageForms;
+ }
+
+ vm.toggleManageWorkflows = function () {
+ vm.security.userSecurity.manageWorkflows = !vm.security.userSecurity.manageWorkflows;
+ }
+
+ vm.toggleManageDataSources = function () {
+ vm.security.userSecurity.manageDataSources = !vm.security.userSecurity.manageDataSources;
+ }
+
+ vm.togglePreValueSources = function () {
+ vm.security.userSecurity.managePreValueSources = !vm.security.userSecurity.managePreValueSources;
+ }
+
+ vm.toggleFormAccess = function (form) {
+ form.HasAccess = !form.HasAccess;
+ }
+
+ function save() {
+
+ // Add a property to the object to save the Umbraco User ID taken from the routeParam.
+ vm.security.userSecurity.user = $routeParams.id;
+
+ securityResource.save(vm.security).then(function (response) {
+ vm.security = response.data;
+ notificationsService.success("User form security saved", "");
+
+ // SecurityForm is the name of the
+ // Set it back to Pristine after we save, so when we browse away we don't get the 'discard changes' notification
+ $scope.securityForm.$setPristine();
+
+ }, function (err) {
+ notificationsService.error("User form security failed to save", "");
+ });
+ }
+
+ init();
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.Editors.Security.EditController", FormSecurityEditController);
+
+})();
+
+
+angular.module("umbraco")
+ .controller("Umbraco.Forms.GridEditors.FormPickerController",
+ function ($scope, $timeout, editorService, macroResource, macroService, $routeParams) {
+
+ $scope.title = "Click to insert form";
+ $scope.macroAlias = "renderUmbracoForm";
+
+ $scope.setFormMacro = function(){
+
+ var dialogData = {
+ richTextEditor: true,
+ macroData: $scope.control.value || {
+ macroAlias: $scope.macroAlias
+ }
+ };
+
+ var macroPicker = {
+ dialogData: dialogData,
+ submit: function(model) {
+ var macroObject = macroService.collectValueData(model.selectedMacro, model.macroParams, dialogData.renderingEngine);
+
+ $scope.control.value = {
+ macroAlias: macroObject.macroAlias,
+ macroParamsDictionary: macroObject.macroParamsDictionary
+ };
+
+ $scope.setPreview($scope.control.value );
+ editorService.close();
+ },
+ close: function() {
+ editorService.close();
+ }
+ };
+ editorService.macroPicker(macroPicker);
+ };
+
+ $scope.setPreview = function(macro){
+ var contentId = $routeParams.id;
+
+ macroResource.getMacroResultAsHtmlForEditor(macro.macroAlias, contentId, macro.macroParamsDictionary)
+ .then(function (htmlResult) {
+ $scope.title = macro.macroAlias;
+ if(htmlResult.trim().length > 0 && htmlResult.indexOf("Macro:") < 0){
+ $scope.preview = htmlResult;
+ }
+ });
+
+ };
+
+ $timeout(function(){
+ if($scope.control.$initializing){
+ $scope.setFormMacro();
+ }else if($scope.control.value){
+ $scope.setPreview($scope.control.value);
+ }
+ }, 200);
+ });
+
+angular.module("umbraco")
+.controller("UmbracoForms.Editors.PreValueSource.DeleteController",
+ function ($scope, preValueSourceResource, navigationService, treeService) {
+ $scope.delete = function (id) {
+ preValueSourceResource.deleteByGuid(id).then(function () {
+
+ treeService.removeNode($scope.currentNode);
+ navigationService.hideNavigation();
+
+ });
+
+ };
+ $scope.cancelDelete = function () {
+ navigationService.hideNavigation();
+ };
+ });
+angular.module("umbraco").controller("UmbracoForms.Editors.PreValueSource.EditController", function ($scope, $routeParams, preValueSourceResource, editorState, notificationsService, navigationService, formHelper, userService, securityResource) {
+
+ //On load/init of 'editing' a prevalue source then
+ //Let's check & get the current user's form security
+ var currentUserId = null;
+
+ userService.getCurrentUser().then(function (response) {
+ currentUserId = response.id;
+
+ //Now we can make a call to form securityResource
+ securityResource.getByUserId(currentUserId).then(function (response) {
+ $scope.security = response.data;
+
+ //Check if we have access to current form OR manage forms has been disabled
+ if (!$scope.security.userSecurity.managePreValueSources) {
+
+ //Show error notification
+ notificationsService.error("Access Denied", "You do not have access to edit Prevalue sources");
+
+ //Resync tree so that it's removed & hides
+ navigationService.syncTree({ tree: "prevaluesource", path: ['-1'], forceReload: true, activate: false }).then(function (response) {
+
+ //Response object contains node object & activate bool
+ //Can then reload the root node -1 for this tree 'Forms Folder'
+ navigationService.reloadNode(response.node);
+ });
+
+ //Don't need to wire anything else up
+ return;
+ }
+ });
+ });
+
+ if ($routeParams.create) {
+ //we are creating so get an empty data type item
+ preValueSourceResource.getScaffold()
+ .then(function (response) {
+ $scope.loaded = true;
+ $scope.preValueSource = response.data;
+
+ preValueSourceResource.getAllPreValueSourceTypesWithSettings()
+ .then(function (resp) {
+ $scope.types = resp.data;
+
+ });
+
+ //set a shared state
+ editorState.set($scope.form);
+ });
+ } else {
+
+ //we are editing so get the content item from the server
+ preValueSourceResource.getByGuid($routeParams.id)
+ .then(function (response) {
+
+ $scope.preValueSource = response.data;
+
+ preValueSourceResource.getAllPreValueSourceTypesWithSettings()
+ .then(function (resp) {
+ $scope.types = resp.data;
+ setTypeAndSettings();
+ getPrevalues();
+ $scope.loaded = true;
+ });
+
+ //As we are editing an item we can highlight it in the tree
+ navigationService.syncTree({ tree: "prevaluesource", path: [String($routeParams.id)], forceReload: false });
+
+ //set a shared state
+ editorState.set($scope.preValueSource);
+ });
+ }
+
+ $scope.setType = function () {
+ $scope.prevalues = null;
+ setTypeAndSettings();
+ };
+
+ $scope.save = function () {
+
+ if (formHelper.submitForm({ scope: $scope })) {
+ //set settings
+ $scope.preValueSource.settings = {};
+ if ($scope.preValueSource.$type) {
+ angular.forEach($scope.preValueSource.$type.settings, function (setting) {
+ var key = setting.alias;
+ var value = setting.value;
+ $scope.preValueSource.settings[key] = value;
+
+ });
+ }
+
+ //validate settings
+ preValueSourceResource.validateSettings($scope.preValueSource)
+ .then(function (response) {
+
+ $scope.errors = response.data;
+
+ if ($scope.errors.length > 0) {
+ angular.forEach($scope.errors, function (error) {
+
+ notificationsService.error("Prevaluesource failed to save", error.Message);
+ });
+ } else {
+ //save
+ preValueSourceResource.save($scope.preValueSource)
+ .then(function (response) {
+
+ $scope.preValueSource = response.data;
+ //set a shared state
+ editorState.set($scope.preValueSource);
+ setTypeAndSettings();
+ getPrevalues();
+ $scope.preValueSourceForm.$dirty = false;
+ navigationService.syncTree({
+ tree: "prevaluesource",
+ path: [String($scope.preValueSource.id)],
+ forceReload: true
+ });
+ notificationsService.success("Prevaluesource saved", "");
+ }, function (err) {
+ notificationsService.error("Prevaluesource failed to save", "");
+ });
+ }
+
+ }, function (err) {
+ notificationsService.error("Prevaluesource failed to save", "Please check if your settings are valid");
+ });
+ }
+ };
+
+ var setTypeAndSettings = function() {
+ $scope.preValueSource.$type = _.where($scope.types, { id: $scope.preValueSource.fieldPreValueSourceTypeId })[0];
+
+ //set settings
+ angular.forEach($scope.preValueSource.settings, function (setting) {
+ for (var key in $scope.preValueSource.settings) {
+ if ($scope.preValueSource.settings.hasOwnProperty(key)) {
+ if (_.where($scope.preValueSource.$type.settings, { alias: key }).length > 0) {
+ _.where($scope.preValueSource.$type.settings, { alias: key })[0].value = $scope.preValueSource.settings[key];
+ }
+
+ }
+ }
+ });
+ };
+
+ var getPrevalues = function() {
+
+ preValueSourceResource.getPreValues($scope.preValueSource)
+ .then(function (response) {
+ $scope.prevalues = response.data;
+ });
+ };
+
+ });
+(function () {
+ "use strict";
+
+ function FormPickerController($scope, $location, formPickerResource, userService, securityResource) {
+
+ var vm = this;
+ var allowedForms = null;
+ var formSecurity = null;
+
+ vm.loading = true;
+ vm.selectedForm = null;
+ vm.error = null;
+
+ vm.openFormPicker = openFormPicker;
+ vm.remove = remove;
+
+ vm.openFormDesigner = openFormDesigner;
+ vm.openFormEntries = openFormEntries;
+
+ function onInit() {
+
+ if ($scope.model.config && $scope.model.config.allowedForms) {
+ allowedForms = $scope.model.config.allowedForms;
+ }
+
+ userService.getCurrentUser().then(function (response) {
+ var currentUserId = response.id;
+ securityResource.getByUserId(currentUserId).then(function (response) {
+ formSecurity = response.data.formsSecurity;
+
+ //Only do this is we have a value saved
+ if ($scope.model.value) {
+
+ formPickerResource.getPickedForm($scope.model.value).then(function (response) {
+ setSelectedForm(response);
+ }, function (err) {
+ //The 500 err will get caught by UmbRequestHelper & show the stacktrace in YSOD dialog if in debug or generic red error to see logs
+
+ //Got an error from the HTTP API call
+ //Most likely cause is the picked/saved form no longer exists & has been deleted
+ //Need to bubble this up in the UI next to prop editor to make it super obvious
+
+ //Using Angular Copy - otherwise the data binding will be updated
+ //So the error message wont make sense, if the user then updates/picks a new form as the model.value will update too
+ var currentValue = angular.copy($scope.model.value);
+
+ //Put something in the prop editor UI - some kind of red div or text
+ vm.error = "The saved/picked form with id '" + currentValue + "' no longer exists. Pick another form below or clear out the old saved form";
+ });
+
+ }
+ });
+ });
+ }
+
+ function openFormPicker() {
+ if (!vm.formPickerOverlay) {
+ vm.formPickerOverlay = {
+ view: "../App_Plugins/UmbracoForms/Backoffice/Form/overlays/formpicker/formpicker.html",
+ allowedForms: allowedForms,
+ show: true,
+ submit: function (model) {
+
+ // save form for UI and save on property model
+ if (model.selectedForms && model.selectedForms.length > 0) {
+ setSelectedForm(model.selectedForms[0]);
+ $scope.model.value = model.selectedForms[0].id;
+ }
+
+ vm.formPickerOverlay.show = false;
+ vm.formPickerOverlay = null;
+
+ },
+ close: function (oldModel) {
+ vm.formPickerOverlay.show = false;
+ vm.formPickerOverlay = null;
+ }
+ }
+ }
+ }
+
+ function setSelectedForm(form) {
+ vm.selectedForm = form;
+ vm.selectedForm.icon = "icon-umb-contour";
+
+ // Set properties indicating if the current user has access to the selected form.
+ if (formSecurity) {
+ var formSecurityForForm = formSecurity.filter(function (fs) {
+ return fs.Form == vm.selectedForm.id;
+ });
+ if (formSecurityForForm.length > 0) {
+ vm.selectedForm.canEditForm = formSecurityForForm[0].HasAccess;
+ vm.selectedForm.canViewEntries = formSecurityForForm[0].HasAccess;
+ }
+ }
+ }
+
+ function openFormDesigner() {
+ $location.url("forms/form/edit/" + vm.selectedForm.id);
+ }
+
+ function openFormEntries() {
+ $location.url("forms/form/entries/" + vm.selectedForm.id);
+ }
+
+ function remove() {
+ vm.selectedForm = null;
+ $scope.model.value = null;
+ }
+
+ onInit();
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.FormPickerController", FormPickerController);
+})();
+
+(function () {
+ "use strict";
+
+ function FormPickerPrevaluesController($scope, $http, formPickerResource, notificationsService) {
+
+ var vm = this;
+
+ vm.openFormPicker = openFormPicker;
+ vm.remove = remove;
+
+ function onInit() {
+
+ if(!$scope.model.value) {
+ $scope.model.value = [];
+ }
+
+ if(!vm.forms) {
+ vm.forms = [];
+ }
+
+ if($scope.model.value && $scope.model.value.length > 0) {
+ formPickerResource.getPickedForms($scope.model.value).then(function(response){
+ vm.forms = response;
+ });
+
+ }
+
+ }
+
+ function openFormPicker() {
+ if (!vm.formPickerOverlay) {
+ vm.formPickerOverlay = {
+ view: "../App_Plugins/UmbracoForms/Backoffice/Form/overlays/formpicker/formpicker.html",
+ multiPicker: true,
+ show: true,
+ submit: function (model) {
+
+ if(model.selectedForms && model.selectedForms.length > 0) {
+ selectForms(model.selectedForms);
+ }
+
+ vm.formPickerOverlay.show = false;
+ vm.formPickerOverlay = null;
+
+ },
+ close: function (oldModel) {
+ vm.formPickerOverlay.show = false;
+ vm.formPickerOverlay = null;
+ }
+ }
+ }
+ }
+
+ function selectForms(selectedForms) {
+ angular.forEach(selectedForms, function (selectedForm) {
+ // make sure the form isn't already picked
+ if($scope.model.value.indexOf(selectedForm.id) === -1) {
+ // store form object on view model
+ vm.forms.push(selectedForm);
+ // store id for value
+ $scope.model.value.push(selectedForm.id);
+ }
+ });
+ }
+
+ function remove(selectedForm) {
+
+ //remove from view model
+ angular.forEach($scope.model.value, function(formId, index){
+ if(formId === selectedForm.id) {
+ $scope.model.value.splice(index, 1);
+ }
+ })
+
+ // remove from model.value
+ angular.forEach(vm.forms, function(form, index){
+ if(form.id === selectedForm.id) {
+ vm.forms.splice(index, 1);
+ }
+ });
+
+ }
+
+ onInit();
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.FormPickerPrevaluesController", FormPickerPrevaluesController);
+})();
+
+(function () {
+ "use strict";
+
+ function ThemePickerController($scope, themePickerResource) {
+
+ var vm = this;
+
+ vm.loading = true;
+ vm.selectedTheme = null;
+ vm.error = null;
+
+ vm.openThemePicker = openThemePicker;
+ vm.remove = remove;
+
+ function onInit() {
+
+ //Only do this is we have a value saved
+ if ($scope.model.value) {
+
+ vm.selectedTheme = {};
+ vm.selectedTheme.name = $scope.model.value;
+ vm.selectedTheme.icon = "icon-brush";
+ }
+ }
+
+ function openThemePicker() {
+ if (!vm.themePickerOverlay) {
+ vm.themePickerOverlay = {
+ view: "../App_Plugins/UmbracoForms/Backoffice/Form/overlays/themepicker/themepicker.html",
+ show: true,
+ submit: function (model) {
+
+ vm.selectedTheme = model.selectedThemes[0];
+ vm.selectedTheme.icon = "icon-brush";
+ $scope.model.value = model.selectedThemes[0].name;
+
+ vm.themePickerOverlay.show = false;
+ vm.themePickerOverlay = null;
+
+ },
+ close: function (oldModel) {
+ vm.themePickerOverlay.show = false;
+ vm.formthemePickerOverlayPickerOverlay = null;
+ }
+ }
+ }
+ }
+
+ function remove() {
+ vm.selectedTheme = null;
+ $scope.model.value = null;
+ }
+
+ onInit();
+
+ }
+
+ angular.module("umbraco").controller("UmbracoForms.ThemePickerController", ThemePickerController);
+})();
+
+function dataSourceResource($http) {
+
+ var apiRoot = "backoffice/UmbracoForms/DataSource/";
+
+ return {
+
+ getScaffold: function (template) {
+ return $http.get(apiRoot + "GetScaffold");
+ },
+
+ getByGuid: function (id) {
+ return $http.get(apiRoot + "GetByGuid?guid=" + id);
+ },
+ deleteByGuid: function (id) {
+ return $http.delete(apiRoot + "DeleteByGuid?guid=" + id);
+ },
+ save: function (preValueSource) {
+ return $http.post(apiRoot + "PostSave", preValueSource);
+ },
+
+ validateSettings: function (preValueSource) {
+ return $http.post(apiRoot + "ValidateSettings", preValueSource);
+ },
+
+ getAllDataSourceTypesWithSettings: function () {
+ return $http.get(apiRoot + "GetAllDataSourceTypesWithSettings");
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('dataSourceResource', dataSourceResource);
+function dataSourceWizardResource($http) {
+
+ var apiRoot = "backoffice/UmbracoForms/DataSourceWizard/";
+
+ return {
+
+ getScaffold: function (id) {
+ return $http.get(apiRoot + "GetScaffold?guid=" + id);
+ },
+
+ getAllFieldTypes: function () {
+ return $http.get(apiRoot + "GetAllFieldTypes");
+ },
+
+ createForm: function (wizard) {
+ return $http.post(apiRoot + "CreateForm", wizard);
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('dataSourceWizardResource', dataSourceWizardResource);
+/**
+ * @ngdoc service
+ * @name umbraco.resources.dashboardResource
+ * @description Handles loading the dashboard manifest
+ **/
+function exportResource($http) {
+ //the factory object returned
+ var apiRoot = "backoffice/UmbracoForms/Export/";
+
+ return {
+
+ getExportTypes: function (formId) {
+ return $http.get(apiRoot + "GetExportTypes?formId=" + formId);
+ },
+
+ generateExport: function (config) {
+ return $http.post(apiRoot + "PostGenerateExport", config);
+ },
+
+ getExportUrl: function (formId, fileName) {
+ return apiRoot + "GetExport?formId=" + formId + "&fileName=" + fileName;
+ },
+
+ getExport: function (token) {
+ return $http.get(apiRoot + "GetExport?token=" + token);
+ }
+
+ };
+}
+
+angular.module('umbraco.resources').factory('exportResource', exportResource);
+
+function fieldResource($http) {
+
+ var apiRoot = "backoffice/UmbracoForms/Field/";
+
+ return {
+ validateSettings: function (field) {
+ return $http.post(apiRoot + "ValidateSettings", field);
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('fieldResource', fieldResource);
+/**
+ * @ngdoc service
+ * @name umbraco.resources.dashboardResource
+ * @description Handles loading the dashboard manifest
+ **/
+function formResource($http) {
+ //the factory object returned
+ var apiRoot = "backoffice/UmbracoForms/Form/";
+
+ return {
+
+ getScaffold: function (template) {
+ return $http.get(apiRoot + "GetScaffold?template=" + template);
+ },
+
+ getScaffoldWithWorkflows: function (template) {
+ return $http.get(apiRoot + "GetScaffoldWithWorkflows?template=" + template);
+ },
+
+ getAllTemplates: function () {
+ return $http.get(apiRoot + "GetFormTemplates");
+ },
+
+ getOverView : function(){
+ return $http.get(apiRoot + 'GetOverView');
+ },
+
+ getByGuid: function (id) {
+ return $http.get(apiRoot + "GetByGuid?guid=" + id);
+ },
+
+ getWithWorkflowsByGuid: function (id) {
+ return $http.get(apiRoot + "GetWithWorkflowsByGuid?guid=" + id);
+ },
+
+ deleteByGuid: function (id) {
+ return $http.delete(apiRoot + "DeleteByGuid?guid=" + id);
+ },
+
+ save: function (form) {
+ return $http.post(apiRoot + "PostSave", form);
+ },
+
+ saveWithWorkflows: function (formWithWorkflows) {
+ return $http.post(apiRoot + "SaveForm", formWithWorkflows);
+ },
+
+ getAllFieldTypes: function() {
+ return $http.get(apiRoot + "GetAllFieldTypes");
+ },
+
+ getAllFieldTypesWithSettings: function () {
+ return $http.get(apiRoot + "GetAllFieldTypesWithSettings");
+ },
+ getPrevalueSources: function() {
+ return $http.get(apiRoot + "GetPrevalueSources");
+ },
+
+ copy: function(id, newFormName, copyWorkflows) {
+ return $http.post(apiRoot + "CopyForm", { guid: id, newName: newFormName, copyWorkflows: copyWorkflows });
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('formResource', formResource);
+
+/**
+ * @ngdoc service
+ * @name umbraco.resources.formPickerResource
+ * @description Used for picking Umbraco Forms with the Form Picker Property Editor
+ **/
+function formPickerResource($http, umbRequestHelper) {
+ //the factory object returned
+
+ //TODO: Use the same way way in core to register URLs in Global Umbraco.Sys.ServerVariables
+ var apiRoot = "backoffice/UmbracoForms/FormPicker/";
+
+ return {
+
+ getFormsForPicker : function(formGuids){
+ return umbRequestHelper.resourcePromise(
+ $http.post(apiRoot + 'GetFormsForPicker', formGuids),
+ "Failed to retrieve Forms to pick"
+ );
+ },
+
+ getPickedForm: function (id) {
+ return umbRequestHelper.resourcePromise(
+ $http.get(apiRoot + "GetPickedForm?formGuid=" + id),
+ "The picked/saved form with id '" + id + "' does not exist"
+ );
+ },
+
+ getPickedForms: function (formGuids) {
+ return umbRequestHelper.resourcePromise(
+ $http.post(apiRoot + "GetPickedForms", formGuids),
+ "The picked/saved form with id '" + formGuids + "' does not exist"
+ );
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('formPickerResource', formPickerResource);
+
+/**
+ * @ngdoc service
+ * @name umbraco.resources.dashboardResource
+ * @description Handles loading the dashboard manifest
+ **/
+function licensingResource($http) {
+ //the factory object returned
+ var apiRoot = "backoffice/UmbracoForms/Licensing/";
+
+ return {
+
+ getLicenseStatus: function () {
+ return $http.get(apiRoot + "GetLicenseStatus");
+ },
+
+ getAvailableLicenses: function (config) {
+ return $http.post(apiRoot + "PostRetriveAvailableLicenses", config);
+ },
+
+ configureLicense: function (config) {
+ return $http.post(apiRoot + "PostConfigureLicense", config);
+ }
+
+ };
+}
+
+angular.module('umbraco.resources').factory('licensingResource', licensingResource);
+
+function pickerResource($http) {
+
+ var apiRoot = "backoffice/UmbracoForms/Picker/";
+
+ return {
+ getAllConnectionStrings: function () {
+ return $http.get(apiRoot + "GetAllConnectionStrings");
+ },
+ getAllDataTypes: function () {
+ return $http.get(apiRoot + "GetAllDataTypes");
+ },
+ getAllDocumentTypes: function () {
+ return $http.get(apiRoot + "GetAllDocumentTypes");
+ },
+ getAllDocumentTypesWithAlias: function () {
+ return $http.get(apiRoot + "GetAllDocumentTypesWithAlias");
+ },
+ getAllMediaTypes: function () {
+ return $http.get(apiRoot + "GetAllMediaTypes");
+ },
+ getAllFields: function (formGuid) {
+ return $http.get(apiRoot + "GetAllFields?formGuid="+formGuid);
+ },
+ getAllProperties: function (doctypeAlias) {
+ return $http.get(apiRoot + "GetAllProperties?doctypeAlias=" + doctypeAlias);
+ },
+ updateMappedProperties: function(doctypeAlias, currentSavedProperties){
+
+ var dataToPost = {
+ "doctypeAlias": doctypeAlias,
+ "currentProperties": currentSavedProperties
+ };
+
+ return $http.post(apiRoot + "PostUpdateMappedProperties", dataToPost);
+ },
+ getVirtualPathForEmailTemplate: function(encodedPath){
+ return $http.get(apiRoot + "GetVirtualPathForEmailTemplate?encodedPath=" + encodedPath);
+ }
+
+ };
+}
+
+angular.module('umbraco.resources').factory('pickerResource', pickerResource);
+function preValueSourceResource($http) {
+
+ var apiRoot = "backoffice/UmbracoForms/PreValueSource/";
+
+ return {
+
+ getScaffold: function (template) {
+ return $http.get(apiRoot + "GetScaffold");
+ },
+
+ getByGuid: function (id) {
+ return $http.get(apiRoot + "GetByGuid?guid=" + id);
+ },
+ deleteByGuid: function (id) {
+ return $http.delete(apiRoot + "DeleteByGuid?guid=" + id);
+ },
+ save: function (preValueSource) {
+ return $http.post(apiRoot + "PostSave", preValueSource);
+ },
+
+ validateSettings: function (preValueSource) {
+ return $http.post(apiRoot + "ValidateSettings", preValueSource);
+ },
+
+ getPreValues: function (preValueSource) {
+ return $http.post(apiRoot + "GetPreValues", preValueSource);
+ },
+
+ getPreValuesByGuid: function (preValueSourceId) {
+ return $http.get(apiRoot + "GetPreValuesByGuid?preValueSourceId=" + preValueSourceId);
+ },
+
+ getAllPreValueSourceTypesWithSettings: function () {
+ return $http.get(apiRoot + "GetAllPreValueSourceTypesWithSettings");
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('preValueSourceResource', preValueSourceResource);
+/**
+ * @ngdoc service
+ * @name umbraco.resources.dashboardResource
+ * @description Handles loading the dashboard manifest
+ **/
+function recordResource($http) {
+ //the factory object returned
+ var apiRoot = "backoffice/UmbracoForms/Record/";
+
+ return {
+
+ getRecords: function (filter) {
+ return $http.post(apiRoot + "PostRetriveRecords", filter);
+ },
+
+ getRecordsCount: function (filter) {
+ return $http.post(apiRoot + "PostRetriveRecordsCount", filter);
+ },
+
+ getRecordSetActions: function () {
+ return $http.get(apiRoot + "GetRecordSetActions");
+ },
+
+ executeRecordSetAction : function(model){
+ return $http.post(apiRoot + "PostExecuteRecordSetAction", model);
+ }
+
+ };
+}
+
+angular.module('umbraco.resources').factory('recordResource', recordResource);
+
+function securityResource($http) {
+
+ var apiRoot = "backoffice/UmbracoForms/FormSecurity/";
+
+ return {
+ getByUserId: function (userId) {
+ return $http.get(apiRoot + "GetByUserId?userId=" + userId);
+ },
+
+ save: function (userSecurity) {
+ return $http.post(apiRoot + "PostSave", userSecurity);
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('securityResource', securityResource);
+/**
+ * @ngdoc service
+ * @name umbraco.resources.themePickerResource
+ * @description Used for picking Umbraco Forms with the Form Picker Property Editor
+ **/
+function themePickerResource($http, umbRequestHelper) {
+ //the factory object returned
+
+ //TODO: Use the same way way in core to register URLs in Global Umbraco.Sys.ServerVariables
+ var apiRoot = "backoffice/UmbracoForms/ThemePicker/";
+
+ return {
+
+ getThemes : function(){
+ return umbRequestHelper.resourcePromise(
+ $http.get(apiRoot + 'GetThemes'),
+ "Failed to retrieve Form Themes to pick"
+ );
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('themePickerResource', themePickerResource);
+
+/**
+ * @ngdoc service
+ * @name umbraco.resources.dashboardResource
+ * @description Handles loading the dashboard manifest
+ **/
+function updatesResource($http) {
+ //the factory object returned
+ var apiRoot = "backoffice/UmbracoForms/Updates/";
+
+ return {
+ getUpdateStatus: function () {
+ return $http.get(apiRoot + "GetUpdateStatus");
+ },
+
+ installLatest: function (version) {
+ return $http.get(apiRoot + "InstallLatest?version=" + version);
+ },
+
+ getVersion: function() {
+ return $http.get(apiRoot + "GetVersion");
+ },
+
+ getSavePlainTextPasswordsConfiguration: function() {
+ return $http.get(apiRoot + "GetSavePlainTextPasswordsConfiguration");
+ }
+ };
+}
+
+angular.module('umbraco.resources').factory('updatesResource', updatesResource);
+
+function workflowResource($http) {
+
+ var apiRoot = "backoffice/UmbracoForms/Workflow/";
+
+ return {
+
+ getScaffold: function (template) {
+ return $http.get(apiRoot + "GetScaffold");
+ },
+
+ getByGuid: function (id) {
+ return $http.get(apiRoot + "GetByGuid?guid=" + id);
+ },
+ deleteByGuid: function (id) {
+ return $http.delete(apiRoot + "DeleteByGuid?guid=" + id);
+ },
+ save: function (preValueSource) {
+ return $http.post(apiRoot + "PostSave", preValueSource);
+ },
+
+ validateSettings: function (preValueSource) {
+ return $http.post(apiRoot + "ValidateSettings", preValueSource);
+ },
+
+ getAllWorkflowTypesWithSettings: function () {
+ return $http.get(apiRoot + "GetAllWorkflowTypesWithSettings");
+ },
+ getAllWorkflows: function (formGuid) {
+ return $http.get(apiRoot + "GetAllWorkflows?formGuid=" + formGuid);
+ },
+ updateSortOrder: function (state, workflowIds) {
+ var data = {};
+ data.state = state;
+ data.guids = workflowIds;
+
+ return $http.post(apiRoot + "UpdateSortOrder", data);
+ },
+
+ getScaffoldWorkflowType: function(workflowTypeId){
+ return $http.get(apiRoot + "GetScaffoldWorkflowType?workflowTypeId="+ workflowTypeId);
+ },
+
+ validateWorkflowSettings: function(workflowViewModel){
+ return $http.post(apiRoot + "ValidateWorkflowSettings", workflowViewModel);
+ }
+
+ };
+}
+
+angular.module('umbraco.resources').factory('workflowResource', workflowResource);
+angular.module("umbraco.directives")
+ .directive('umbFormsAutoFocus', function($timeout) {
+
+ return function(scope, element, attr){
+
+ var update = function() {
+
+ //if it uses its default naming
+ if(element.val().indexOf(" field") >= 0){
+ element.focus();
+ }
+
+ };
+
+ $timeout(function() {
+ update();
+ });
+
+
+ scope.$watch(attr.umbFormsFocusOn, function (_focusVal) {
+ $timeout(function () {
+ if (_focusVal) {
+ element.focus();
+ element.select();
+ update();
+ }
+ });
+ });
+ };
+});
+
+angular.module("umbraco.directives")
+ .directive('umbFormsAutoSize', function($timeout) {
+
+ return function(scope, element, attr){
+ var domEl = element[0];
+ var update = function(force) {
+
+ if(force === true){
+ element.height(0);
+ }
+
+ if(domEl.scrollHeight !== domEl.clientHeight){
+ element.height(domEl.scrollHeight);
+ }
+ };
+
+
+ element.bind('keyup keydown keypress change', update);
+ element.bind('blur', function(){ update(true); });
+
+ $timeout(function() {
+ update();
+ });
+ };
+});
+
+angular.module("umbraco.directives")
+ .directive('umbFormsContentPicker', function (entityResource, iconHelper, editorService) {
+ return {
+ restrict: 'E',
+ replace: true,
+ templateUrl: '/App_Plugins/UmbracoForms/directives/umb-forms-content-picker.html',
+ require: "ngModel",
+ link: function (scope, element, attr, ctrl) {
+
+ ctrl.$render = function() {
+ var val = parseInt(ctrl.$viewValue);
+
+ if (!isNaN(val) && angular.isNumber(val) && val > 0) {
+
+ entityResource.getById(val, "Document").then(function(item) {
+ item.icon = iconHelper.convertFromLegacyIcon(item.icon);
+ scope.node = item;
+ });
+ }
+ };
+
+ scope.openContentPicker = function () {
+ var contentPickerOverlay = {
+ submit: function(model) {
+ populate(model.selection[0]);
+ editorService.close();
+ },
+ close: function(){
+ editorService.close();
+ }
+ };
+
+ editorService.contentPicker(contentPickerOverlay);
+ };
+
+ scope.clear = function () {
+ scope.id = undefined;
+ scope.node = undefined;
+ updateModel(0);
+ };
+
+ function populate(item) {
+ scope.clear();
+ item.icon = iconHelper.convertFromLegacyIcon(item.icon);
+ scope.node = item;
+ scope.id = item.id;
+ updateModel(item.id);
+ }
+
+ function updateModel(id) {
+ ctrl.$setViewValue(id);
+
+ }
+ }
+ };
+});
+
+angular.module("umbraco.directives").directive('umbFormsDateRangePicker', function (assetsService, userService) {
+ return {
+ restrict: 'A',
+ scope: {
+ userLocale: "@",
+ onChange: "="
+ },
+ template: '
',
+ link: function (scope, element) {
+
+ assetsService.load([
+ "/App_Plugins/UmbracoForms/Assets/moment/min/moment-with-locales.min.js",
+ "/App_Plugins/UmbracoForms/Assets/BaremetricsCalendar/public/js/calendar.js"
+ ])
+ .then(function () {
+
+ //Set the moment locale to the current user's locale
+ //Used for display, we still grab the date as YYYY-MM-DD to send to API endpoint
+ moment.locale(scope.userLocale);
+
+ var dd = new Calendar({
+ element: $(".daterange--double"),
+ earliest_date: 'January 1, 2000',
+ latest_date: moment(),
+ start_date: moment().subtract(29, 'days'),
+ end_date: moment(),
+ same_day_range: true,
+ callback: function () {
+
+ //Date update/changed
+
+ //Parse the dates from this component to Moment dates
+ var start = moment(this.start_date);
+ var end = moment(this.end_date);
+ var dateFilter = {};
+
+ dateFilter.startDate = start.format('YYYY-MM-DD');
+ dateFilter.endDate = end.format('YYYY-MM-DD');
+
+ if(scope.onChange) {
+ scope.onChange(dateFilter);
+ }
+
+ }
+ });
+
+ });
+
+ //Load CSS as dependancy
+ //load the seperate css for the editor to avoid it blocking our js loading
+ assetsService.loadCss("/App_Plugins/UmbracoForms/Assets/BaremetricsCalendar/public/css/application.css");
+
+ }
+ };
+});
+
+angular.module("umbraco.directives")
+ .directive('ufDelayedMouseleave', function ($timeout, $parse) {
+ return {
+ restrict: 'A',
+ link: function (scope, element, attrs, ctrl) {
+ var active = false;
+ var fn = $parse(attrs.ufDelayedMouseleave);
+ element.on("mouseleave", function(event) {
+ var callback = function() {
+ fn(scope, {$event:event});
+ };
+
+ active = false;
+ $timeout(function(){
+ if(active === false){
+ scope.$apply(callback);
+ }
+ }, 650);
+ });
+
+ element.on("mouseenter", function(event, args){
+ active = true;
+ });
+ }
+ };
+ });
+
+angular.module("umbraco.directives")
+ .directive('umbFormsDesignerNew', function (formService, fieldResource, workflowResource, notificationsService, editorService) {
+ return {
+ scope: {
+ form: "=",
+ fieldtypes: "=",
+ prevaluesources: "=",
+ security: "="
+ },
+ transclude: true,
+ restrict: 'E',
+ replace: true,
+ templateUrl: '/App_Plugins/UmbracoForms/directives/umb-forms-designer-new.html',
+ link: function (scope, element, attrs, ctrl) {
+
+
+ scope.sortingMode = false;
+ scope.sortingButtonKey = "general_reorder";
+ scope.state = "";
+
+
+ // *********************************************
+ // Sorting management functions
+ // *********************************************
+
+
+ scope.setActive = function (fieldSet) {
+
+ angular.forEach(scope.form.pages, function (page) {
+ angular.forEach(page.fieldSets, function (fieldset) {
+
+ if (fieldset.state === "active") {
+ fieldset.state = "InActive";
+ }
+
+ });
+ });
+
+ fieldSet.state = "active";
+ };
+
+ scope.sortablePages = {
+ distance: 10,
+ tolerance: "pointer",
+ opacity: 0.7,
+ scroll: true,
+ cursor: "move",
+ placeholder: "umb-forms__page-placeholder",
+ zIndex: 6000,
+ handle: ".sortable-handle",
+ items: ".sortable",
+ start: function (e, ui) {
+ ui.placeholder.height(ui.item.height());
+ }
+ };
+
+ scope.sortableFieldsets = {
+ distance: 10,
+ tolerance: "pointer",
+ connectWith: ".umb-forms__fieldsets",
+ opacity: 0.7,
+ scroll: true,
+ cursor: "move",
+ placeholder: "umb-forms__fieldset-placeholder",
+ zIndex: 6000,
+ handle: ".sortable-handle",
+ items: ".sortable",
+ start: function (e, ui) {
+ ui.placeholder.height(ui.item.height());
+ },
+ over: function (e, ui) {
+ scope.$apply(function () {
+ $(e.target).scope().page.dropOnEmpty = true;
+ });
+ },
+ out: function (e, ui) {
+ scope.$apply(function () {
+ $(e.target).scope().page.dropOnEmpty = false;
+ });
+ }
+ };
+
+ scope.sortableFields = {
+ distance: 10,
+ tolerance: "pointer",
+ connectWith: ".umb-forms__fields",
+ opacity: 0.7,
+ scroll: true,
+ cursor: "move",
+ placeholder: "umb-forms__field-placeholder",
+ zIndex: 6000,
+ handle: ".sortable-handle",
+ items: ".sortable",
+ start: function (e, ui) {
+ ui.placeholder.height(ui.item.height());
+ },
+ over: function (e, ui) {
+ scope.$apply(function () {
+ $(e.target).scope().container.dropOnEmpty = true;
+ });
+ },
+ out: function (e, ui) {
+ scope.$apply(function () {
+ $(e.target).scope().container.dropOnEmpty = false;
+ });
+ }
+ };
+
+ scope.toggleSortingMode = function () {
+ scope.sortingMode = !scope.sortingMode;
+
+ if (scope.sortingMode) {
+ scope.sortingButtonKey = "general_reorderDone";
+ } else {
+ scope.sortingButtonKey = "general_reorder";
+ }
+
+ };
+
+ // *********************************************
+ // Form management functions
+ // *********************************************
+ scope.initForm = function (form, fieldtypes) {
+ formService.initForm(form, fieldtypes);
+ };
+
+ // *********************************************
+ // Copy prompt
+ // *********************************************
+ scope.toggleCopyPrompt = function (object) {
+ object.copyPrompt = !object.copyPrompt;
+ };
+
+ scope.hideCopyPrompt = function (object) {
+ object.copyPrompt = false;
+ };
+
+ // *********************************************
+ // Delete prompt
+ // *********************************************
+ scope.toggleDeletePrompt = function (object) {
+ object.deletePrompt = !object.deletePrompt;
+ };
+
+ scope.hideDeletePrompt = function (object) {
+ object.deletePrompt = false;
+ };
+
+ // *********************************************
+ // Page management functions
+ // *********************************************
+
+ scope.addPage = function (form) {
+ formService.addPage(form);
+ };
+
+ scope.removePage = function (pages, index) {
+ pages.splice(index, 1);
+ };
+
+ scope.formHasFields = function (form) {
+ var hasFields = false;
+
+ angular.forEach(scope.form.pages, function (page) {
+ angular.forEach(page.fieldSets, function (fieldset) {
+ angular.forEach(fieldset.containers, function (container) {
+ if (container.fields.length > 0) {
+ hasFields = true;
+ }
+ });
+ });
+ });
+
+ return hasFields;
+ };
+
+ scope.pageHasFields = function (page) {
+
+ var hasFields = false;
+
+ angular.forEach(page.fieldSets, function (fieldset) {
+ angular.forEach(fieldset.containers, function (container) {
+ if (container.fields.length > 0) {
+ hasFields = true;
+ }
+ });
+ });
+
+ return hasFields;
+
+ };
+
+ // *********************************************
+ // Fieldset management functions
+ // *********************************************
+
+
+ scope.addFieldset = function (page) {
+ // always add it last
+ var _index = page.fieldSets.length;
+ formService.addFieldset(page, _index);
+ };
+
+ scope.copyFieldset = function (page, fieldset) {
+ fieldset.copyPrompt = false;
+ formService.copyFieldset(page, fieldset, getExistingFieldAliases());
+ };
+
+ scope.removeFieldset = function (page, fieldset) {
+ formService.deleteFieldset(page, fieldset);
+ };
+
+ scope.editFieldset = function (fieldset) {
+ populateFields();
+
+ var fieldsetSettingsOverlay = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/fieldsetsettings/fieldset-settings.html",
+ title: "Edit group",
+ fieldset: fieldset,
+ fields: scope.fields,
+ size: "medium"
+ };
+
+ editorService.open(fieldsetSettingsOverlay);
+ };
+
+
+ // *********************************************
+ // Field management functions
+ // *********************************************
+
+ var addOrUpdateField = function(model, field) {
+ field.settings = {};
+
+ for (var i = 0; i < model.field.$fieldType.settings.length; i++) {
+ var setting = model.field.$fieldType.settings[i];
+ var key = setting.alias;
+ var value = setting.value;
+ field.settings[key] = value;
+ }
+
+ fieldResource.validateSettings(field).then(function (response) {
+ if (response.data.length > 0) {
+ angular.forEach(response.data, function (error) {
+ notificationsService.error("Field failed to save", error.Message);
+ });
+ } else {
+ editorService.close();
+ }
+ });
+ };
+
+ scope.addField = function (fieldset, container) {
+
+ populateFields();
+
+ var emptyField = formService.addEmptyField(container);
+
+ var fieldSettingsEditor = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/fieldsettings/field-settings.html",
+ title: "Add question",
+ field: emptyField,
+ fields: scope.fields,
+ size: "medium",
+ prevalueSources: scope.prevaluesources,
+ submit: function (model) {
+ addOrUpdateField(model, emptyField);
+ },
+ close: function () {
+ formService.deleteField(fieldset, container, emptyField);
+ editorService.close();
+ }
+ };
+ editorService.open(fieldSettingsEditor);
+ };
+
+ scope.openFieldSettings = function (field) {
+
+ populateFields();
+
+ scope.setFieldType(field);
+
+ var fieldSettingsOverlay = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/fieldsettings/field-settings.html",
+ title: "Edit question",
+ field: field,
+ fields: scope.fields,
+ size: "medium",
+ prevalueSources: scope.prevaluesources,
+ submit: function (model) {
+ addOrUpdateField(model, field);
+ },
+ close: function () {
+ editorService.close();
+ }
+ };
+
+ editorService.open(fieldSettingsOverlay);
+ };
+
+ scope.removeField = function (fieldset, container, field) {
+ formService.deleteField(fieldset, container, field);
+ };
+
+ scope.copyField = function (container, field) {
+ field.copyPrompt = false;
+ formService.copyField(container, field, getExistingFieldAliases());
+ };
+
+ scope.setFieldType = function (field) {
+
+ //set settings
+ angular.forEach(field.settings, function (setting) {
+ for (var key in field.settings) {
+ if (field.settings.hasOwnProperty(key)) {
+ if (_.where(field.$fieldType.settings, { alias: key }).length > 0) {
+ _.where(field.$fieldType.settings, { alias: key })[0].value = field.settings[key];
+ }
+ }
+ }
+ });
+
+ };
+
+ // *********************************************
+ // Field conditions
+ // *********************************************
+
+ scope.getFieldNameFromGuid = function (selectedFieldId) {
+ populateFields();
+ for (var i = 0; i < scope.fields.length; i++) {
+ var field = scope.fields[i];
+ if (field.id === selectedFieldId) {
+ return field.caption;
+ }
+ }
+ };
+
+ // *********************************************
+ // Button functions
+ // *********************************************
+
+ scope.editWorkflows = function () {
+
+ if (scope.security && scope.security.userSecurity.manageWorkflows) {
+
+ populateFields();
+
+ var oldFormWorkflows = angular.copy(scope.form.formWorkflows);
+ var oldMessageOnSubmit = angular.copy(scope.form.messageOnSubmit);
+ var oldGoToPageOnSubmit = angular.copy(scope.form.goToPageOnSubmit);
+
+ var workflowOverlay = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflows-overview.html",
+ title: "Workflows",
+ formWorkflows: scope.form.formWorkflows,
+ messageOnSubmit: scope.form.messageOnSubmit,
+ goToPageOnSubmit: scope.form.goToPageOnSubmit,
+ submitLabel: scope.form.submitLabel,
+ manualApproval: scope.form.manualApproval,
+ fields: scope.fields,
+ size: "medium",
+ submit: function (model) {
+ scope.form.formWorkflows = model.formWorkflows;
+ scope.form.messageOnSubmit = model.messageOnSubmit;
+ scope.form.goToPageOnSubmit = model.goToPageOnSubmit;
+
+ editorService.close();
+ },
+ close: function () {
+ // reset the model
+ scope.form.formWorkflows = oldFormWorkflows;
+ scope.form.messageOnSubmit = oldMessageOnSubmit;
+ scope.form.goToPageOnSubmit = oldGoToPageOnSubmit;
+
+ editorService.close();
+ }
+ };
+
+ editorService.open(workflowOverlay);
+ }
+ };
+
+ scope.editWorkflowSettings = function (workflow) {
+
+ if (scope.security && scope.security.userSecurity.manageWorkflows) {
+
+
+ populateFields();
+
+ var workflowSettingsOverlay = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/workflows/workflow-settings.html",
+ workflow: workflow,
+ fields: scope.fields,
+ title: workflow.name,
+ size: "medium",
+ submit: function (model) {
+
+ // Validate settings
+ workflowResource.validateWorkflowSettings(model.workflow).then(function (response) {
+ if (response.data.length > 0) {
+ angular.forEach(response.data, function (error) {
+ notificationsService.error("Workflow failed to save", error.Message);
+ });
+ } else {
+ editorService.close();
+ }
+ });
+ }
+ };
+
+ editorService.open(workflowSettingsOverlay);
+ }
+ };
+
+ scope.editSubmitMessageWorkflow = function () {
+
+ var submitMessageWorkflowOverlay = {
+ view: "/app_plugins/UmbracoForms/Backoffice/Form/overlays/workflows/submit-message-workflow-settings.html",
+ title: "Message on submit",
+ messageOnSubmit: scope.form.messageOnSubmit,
+ goToPageOnSubmit: scope.form.goToPageOnSubmit,
+ size: "medium",
+ submit: function (model) {
+ scope.form.messageOnSubmit = model.messageOnSubmit;
+ scope.form.goToPageOnSubmit = model.goToPageOnSubmit;
+
+ editorService.close();
+ },
+ close: function(){
+ editorService.close();
+ }
+
+ };
+
+ editorService.open(submitMessageWorkflowOverlay);
+ };
+
+ // *********************************************
+ // Internal functions
+ // *********************************************
+ var populateFields = function () {
+ scope.fields = [];
+ angular.forEach(scope.form.pages, function (page) {
+ angular.forEach(page.fieldSets, function (fieldset) {
+ angular.forEach(fieldset.containers, function (container) {
+ angular.forEach(container.fields, function (field) {
+ scope.fields.push(field);
+ });
+ });
+ });
+ });
+ };
+
+ var getExistingFieldAliases = function () {
+ var aliases = [];
+ angular.forEach(scope.form.pages, function (page) {
+ angular.forEach(page.fieldSets, function (fieldset) {
+ angular.forEach(fieldset.containers, function (container) {
+ angular.forEach(container.fields, function (field) {
+ aliases.push(field.alias);
+ });
+ });
+ });
+ });
+ return aliases;
+ };
+
+ scope.initForm(scope.form, scope.fieldtypes);
+ }
+ };
+ });
+
+(function () {
+ 'use strict';
+
+ function FormsEntryDetail() {
+
+ function link(scope, el, attr, ctrl) {
+
+
+ //console.log("from directive", scope.entry);
+
+ }
+
+ var directive = {
+ restrict: 'E',
+ replace: true,
+ templateUrl: '/App_Plugins/UmbracoForms/directives/umb-forms-entry-detail.html',
+ scope: {
+ entry: '=',
+ sensitiveDataAccess: '='
+ },
+ link: link
+ };
+
+ return directive;
+ }
+
+ angular.module('umbraco.directives').directive('umbFormsEntryDetail', FormsEntryDetail);
+
+})();
+
+angular.module("umbraco.directives")
+ .directive('umbFormsFileUploadEditor', function (notificationsService, overlayService) {
+ return {
+ restrict: 'E',
+ replace: true,
+ templateUrl: '/App_Plugins/UmbracoForms/directives/umb-forms-file-upload-editor.html',
+ require: "ngModel",
+ link: function (scope, element, attr, ctrl) {
+ scope.allowedFileTypes = [
+ { Type: '', Name: 'Allow all files', Checked: false },
+ { Type: 'pdf', Name: 'PDF', Checked: false },
+ { Type: 'docx', Name: "DOCX", Checked: false },
+ { Type: 'xlsx', Name: "XLSX", Checked: false },
+ { Type: 'txt', Name: "TXT", Checked: false },
+ { Type: 'png', Name: "PNG", Checked: false },
+ { Type: 'jpg', Name: "JPG", Checked: false },
+ { Type: 'gif', Name: "GIF", Checked: false }
+ ];
+ ctrl.$render = function () {
+ if (Object.prototype.toString.call(ctrl.$viewValue) === '[object Array]') {
+ ctrl.$viewValue.forEach(function (allowedFileType) {
+ if (allowedFileType.Checked === undefined || allowedFileType.Checked === null) {
+ allowedFileType.Checked = undefined;
+ }
+ else if (typeof (allowedFileType.Checked) === "string" && allowedFileType.Checked.toLowerCase() === 'false') {
+ allowedFileType.Checked = false;
+ }
+ else if (typeof (allowedFileType.Checked) === "string" && allowedFileType.Checked.toLowerCase() === 'true') {
+ allowedFileType.Checked = true;
+ }
+ });
+ scope.allowedFileTypes = ctrl.$viewValue;
+ }
+ updateModel();
+ };
+ function updateModel() {
+ ctrl.$setViewValue(scope.allowedFileTypes);
+ }
+ scope.deleteAllowedFileType = function (idx) {
+ var performDelete = function () {
+ scope.allowedFileTypes.splice(idx, 1);
+ updateModel();
+ };
+ var overlay = {
+ view: "confirm",
+ title: "Confirmation",
+ content: "Are you sure you want to delete this?",
+ closeButtonLabel: "No",
+ submitButtonLabel: "Yes",
+ submitButtonStyle: "danger",
+ close: function () {
+ overlayService.close();
+ },
+ submit: function () {
+ performDelete();
+ overlayService.close();
+ }
+ };
+ overlayService.open(overlay);
+ };
+ scope.addAllowedFileType = function () {
+ if (!scope.newAllowedFileType) {
+ return;
+ }
+ scope.newAllowedFileType = scope.newAllowedFileType.replace(/[^a-zA-Z0-9]/g, "");
+ if (scope.newAllowedFileType.length === 0) {
+ return;
+ }
+ var indexOfExisting = scope.allowedFileTypes.findIndex(function (p) { return p.Name.toUpperCase() === scope.newAllowedFileType.toUpperCase(); });
+ //Check that our array does not already contain the same item
+ if (indexOfExisting < 0) {
+ scope.allowedFileTypes.push({ Type: scope.newAllowedFileType, Name: scope.newAllowedFileType.toUpperCase(), Checked: undefined });
+ scope.newAllowedFileType = '';
+ // Disable the "allow all" checkbox
+ scope.allowedFileTypes.forEach(function (allowedFileType) {
+ if (allowedFileType.Type === '') {
+ allowedFileType.Checked = false;
+ }
+ });
+ updateModel();
+ } else {
+ //Notify user they are trying to add a prevalue that already exists
+ notificationsService.error("File Type Error", "Unable to add File Type as this is a duplicate");
+ }
+ };
+ scope.switchAllowedPredefined = function (allowedFileType, updateProvidedFileType) {
+ // When updating from the "allow all files" toggle, we need to set the new "checked" value.
+ // From the check-boxes, it's done for us.
+ if (updateProvidedFileType) {
+ allowedFileType.Checked = !allowedFileType.Checked;
+ }
+ if (allowedFileType !== undefined) {
+ // When allowing all, disable all other checkboxes
+ if (allowedFileType.Type === '' && allowedFileType.Checked === true) {
+ scope.allowedFileTypes.forEach(function (allowedFileType) {
+ if (allowedFileType.Type !== '' && allowedFileType.Checked !== undefined) {
+ allowedFileType.Checked = false;
+ }
+ });
+ }
+ // When allowing a specific type and if All is enabled, disable all
+ if (allowedFileType.Type !== '' && allowedFileType.Checked === true && allowedFileType.Checked !== undefined) {
+ scope.allowedFileTypes.forEach(function (allowedFileType) {
+ if (allowedFileType.Type === '') {
+ allowedFileType.Checked = false;
+ }
+ });
+ }
+ updateModel();
+ }
+ };
+ }
+ };
+ });
+
+angular.module("umbraco.directives")
+ .directive('umbFormsInlinePrevalueEditor', function (notificationsService) {
+ return {
+ restrict: 'E',
+ replace: true,
+ templateUrl: '/App_Plugins/UmbracoForms/directives/umb-forms-inline-prevalue-editor.html',
+ require: "ngModel",
+ link: function (scope, element, attr, ctrl) {
+ scope.prevalues = [];
+
+ ctrl.$render = function () {
+ if (Object.prototype.toString.call(ctrl.$viewValue) === '[object Array]') {
+ scope.prevalues = ctrl.$viewValue;
+ }
+ };
+
+ function updateModel() {
+ ctrl.$setViewValue(scope.prevalues);
+ }
+
+ function addPrevalue() {
+
+ //Check that our array does not already contain the same item
+ if (scope.prevalues.indexOf(scope.newPrevalue) < 0) {
+ scope.prevalues.push(scope.newPrevalue);
+ scope.newPrevalue = '';
+ updateModel();
+ } else {
+ //Notify user they are trying to add a prevalue that already exists
+ notificationsService.error("PreValue Error", "Unable to add PreValue as this is a duplicate");
+ }
+ }
+
+ scope.addPrevalue = function () {
+ addPrevalue();
+ };
+
+ }
+ };
+ });
+angular.module("umbraco.directives")
+ .directive('umbFormsPrevalueEditor', function (notificationsService) {
+ return {
+ restrict: 'E',
+ replace: true,
+ templateUrl: '/App_Plugins/UmbracoForms/directives/umb-forms-prevalue-editor.html',
+ require: "ngModel",
+ link: function (scope, element, attr, ctrl) {
+
+ scope.prevalues = [];
+ scope.editIndex = -1;
+ scope.deleteIndex = -1;
+
+ ctrl.$render = function () {
+ if (Object.prototype.toString.call(ctrl.$viewValue) === '[object Array]') {
+ scope.prevalues = ctrl.$viewValue;
+ }
+ };
+
+ function updateModel() {
+ ctrl.$setViewValue(scope.prevalues);
+ }
+
+ scope.editPrevalue = function (idx) {
+ scope.editIndex = idx;
+ scope.newPrevalue = scope.prevalues[idx];
+ };
+
+ scope.deletePrevalue = function (idx) {
+ scope.prevalues.splice(idx, 1);
+ updateModel();
+ };
+
+ scope.addPrevalue = function () {
+
+ // Check that our array does not already contain the same item (and if editing, make sure not to check against self).
+ var otherPrevalues = scope.prevalues.slice();
+ if (scope.isEditing()) {
+ otherPrevalues.splice(scope.editIndex, 1);
+ }
+
+ if (otherPrevalues.indexOf(scope.newPrevalue) < 0) {
+ if (scope.isEditing()) {
+ scope.prevalues[scope.editIndex] = scope.newPrevalue;
+ } else {
+ scope.prevalues.push(scope.newPrevalue);
+ }
+
+ scope.newPrevalue = '';
+ scope.editIndex = -1;
+ updateModel();
+ } else {
+ // Notify user they are trying to add a prevalue that already exists.
+ notificationsService.error("PreValue Error", "Unable to " + (scope.isEditing() ? "edit" : "add" ) + " value as it would create a duplicate.");
+ }
+ };
+
+ scope.cancelEditing = function () {
+ scope.newPrevalue = '';
+ scope.editIndex = -1;
+ };
+
+ scope.isEditing = function () {
+ return scope.editIndex >= 0;
+ };
+
+ scope.showDeletePrompt = function (idx) {
+ scope.deleteIndex = idx;
+ };
+
+ scope.isDeleting = function (idx) {
+ return scope.deleteIndex === idx;
+ };
+
+ scope.hideDeletePrompt = function () {
+ scope.deleteIndex = -1;
+ };
+
+ }
+ };
+ });
+
+(function () {
+ 'use strict';
+
+ function FormsRenderType() {
+
+ var directive = {
+ restrict: 'E',
+ replace: true,
+ templateUrl: '/App_Plugins/UmbracoForms/directives/umb-forms-render-type.html',
+ scope: {
+ view: '=',
+ field: '=',
+ sensitive: '=',
+ hasAccess: '=',
+ name: '='
+ }
+ };
+
+ return directive;
+ }
+
+ angular.module('umbraco.directives').directive('umbFormsRenderType', FormsRenderType);
+
+})();
+
+function formService(preValueSourceResource) {
+
+ var generateGUID = function () {
+ var d = new Date().getTime();
+
+ var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+ var r = (d + Math.random() * 16) % 16 | 0;
+ d = Math.floor(d / 16);
+ return (c === 'x' ? r : (r & 0x7 | 0x8)).toString(16);
+ });
+
+ return uuid;
+ };
+
+ var generateCopiedAlias = function (alias, existingFieldAliases) {
+
+ var result;
+
+ // Check if the string already ends with a number, if so increment.
+ var matches = alias.match(/\d+$/);
+ if (matches) {
+ var prefix = alias.substring(0, alias.length - matches[0].length);
+ var existingNumberSuffix = parseInt(matches[0], 10);
+ var newNumberSuffix = existingNumberSuffix + 1;
+ result = prefix + newNumberSuffix;
+ } else {
+ // Otherwise just suffix with '2'
+ result = alias + '2';
+ }
+
+ // Check it's not an existing alias.
+ var clashesWithExistingAlias = false;
+ for (var i = 0; i < existingFieldAliases.length; i++) {
+ if (existingFieldAliases[i] === result) {
+ clashesWithExistingAlias = true;
+ break;
+ }
+ }
+
+ // If it matches an existing alias, recursively call to generate another. Otherwise return the new, unique alias.
+ return clashesWithExistingAlias ? generateCopiedAlias(result, existingFieldAliases) : result;
+ };
+
+ var service = {
+ fieldTypes: [],
+ actionTypes: [
+ {
+ name: "Show",
+ value: "Show"
+ },
+ {
+ name: "Hide",
+ value: "Hide"
+ }
+ ],
+ logicTypes: [
+ {
+ name: "all",
+ value: "All"
+ },
+ {
+ name: "any",
+ value: "Any"
+ }
+ ],
+ operators: [
+ {
+ name: "is",
+ value: "Is"
+ },
+ {
+ name: "is not",
+ value: "IsNot"
+ },
+ {
+ name: "is greater than",
+ value: "GreaterThen"
+ },
+ {
+ name: "is less than",
+ value: "LessThen"
+ },
+ {
+ name: "contains",
+ value: "Contains"
+ },
+ {
+ name: "starts with",
+ value: "StartsWith"
+ },
+ {
+ name: "ends with",
+ value: "EndsWith"
+ }
+ ],
+
+ getActionTypes: function () {
+ return service.actionTypes;
+ },
+
+ getLogicTypes: function () {
+ return service.logicTypes;
+ },
+
+ getOperators: function () {
+ return service.operators;
+ },
+
+ initForm: function (form, fieldtypes) {
+ service.fieldTypes = fieldtypes;
+
+ if (!form.pages || form.pages.length === 0) {
+ service.addPage(form);
+ } else {
+
+ _.each(service.getAllFields(form), function (field) {
+
+ if (!field.$fieldType) {
+ service.setFieldType(field, field.fieldTypeId);
+ }
+
+ });
+ }
+ },
+
+ addPage: function (form, index) {
+ var p = { caption: "", fieldSets: [] };
+ service.addFieldset(p);
+
+ if (form.pages.length > index) {
+ form.pages.splice(index, 0, p);
+ } else {
+ form.pages.push(p);
+ }
+ },
+
+ addFieldset: function (page, index) {
+ var fs = { caption: "", containers: [], id: generateGUID() };
+ service.addContainer(fs);
+
+ if (page.fieldSets.length > index) {
+ page.fieldSets.splice(index, 0, fs);
+ } else {
+ page.fieldSets.push(fs);
+ }
+ },
+
+ copyFieldset: function (page, fieldset, existingFieldAliases) {
+ var index = page.fieldSets.indexOf(fieldset);
+ if (index >= 0) {
+ service.copyFieldsetAtIndex(page, fieldset, index, existingFieldAliases);
+ }
+ },
+
+ copyFieldsetAtIndex: function (page, fieldset, index, existingFieldAliases) {
+ var copiedFieldset = JSON.parse(JSON.stringify(fieldset)); // Need to do a full clone here to ensure that the container and field collections are new objects.
+ copiedFieldset.id = generateGUID();
+
+ for (var i = 0; i < copiedFieldset.containers.length; i++) {
+ for (var j = 0; j < copiedFieldset.containers[i].fields.length; j++) {
+ var copiedField = copiedFieldset.containers[i].fields[j];
+ copiedField.id = generateGUID();
+ copiedField.alias = generateCopiedAlias(copiedField.alias, existingFieldAliases);
+ existingFieldAliases.push(copiedField.alias); // Make sure to add the generated alias to the list of existing ones, so it's used in further duplicate checks.
+ }
+ }
+
+ page.fieldSets.splice(index + 1, 0, copiedFieldset);
+ },
+
+ deleteFieldset: function (page, fieldset) {
+ if (page.fieldSets.length > 1) {
+ var index = page.fieldSets.indexOf(fieldset);
+ page.fieldSets.splice(index, 1);
+ } else {
+ fieldset.containers.length = 0;
+ service.addContainer(fieldset);
+ }
+ },
+
+ deleteFieldsetAtIndex: function (page, index) {
+ if (page.fieldSets.length > 1) {
+ page.fieldSets.splice(index, 1);
+ } else {
+ fieldset.containers.length = 0;
+ service.addContainer(fieldset);
+ }
+ },
+
+ splitFieldset: function (page, fieldset, container, splitAtIndex) {
+
+ var newfieldset = { caption: "", containers: [{ caption: "", fields: [] }] };
+ var insertAt = page.fieldSets.indexOf(fieldset);
+
+ page.fieldSets.splice(insertAt + 1, 0, newfieldset);
+
+ var oldFields = container.fields.slice(0, splitAtIndex + 1);
+ var newFields = container.fields.slice(splitAtIndex + 1);
+
+ newfieldset.containers[0].fields = newFields;
+ container.fields = oldFields;
+ },
+
+ addContainer: function (fieldset, index) {
+ var c = { caption: "", fields: [] };
+
+ if (fieldset.containers.length > index) {
+ fieldset.containers.splice(index, 0, c);
+ } else {
+ fieldset.containers.push(c);
+ }
+ },
+
+ splitContainer: function (fieldset, container, splitAtIndex) {
+
+ var newContainer = { caption: "", fields: [] };
+ var insertAt = fieldset.containers.indexOf(container);
+
+ fieldset.containers.splice(insertAt - 1, 0, newContainer);
+ var newFields = container.fields.slice(0, splitAtIndex + 1);
+ var oldFields = container.fields.slice(splitAtIndex + 1);
+
+ newContainer.fields = newFields;
+ container.fields = oldFields;
+ },
+
+ deleteContainer: function (fieldset, container) {
+ //only delete the container if there are multiple ones on this fieldseet
+ //otherwise keep it and just clear its contents
+ if (fieldset.containers.length > 1) {
+ var index = fieldset.containers.indexOf(container);
+ if (index >= 0) {
+ service.deleteContainerAtIndex(fieldset, index);
+ }
+ } else {
+ container.fields.length = 0;
+ }
+ },
+
+ deleteContainerAtIndex: function (fieldset, index) {
+
+ if (fieldset.containers.length > 1) {
+ fieldset.containers.splice(index, 1);
+ } else {
+ fieldset.containers.length = 0;
+ }
+ },
+
+
+ syncContainerWidths: function (form) {
+ _.each(form.pages, function (page) {
+ _.each(page.fieldSets, function (fieldset) {
+ var containers = fieldset.containers.length;
+ var avrg = Math.floor(12 / containers);
+ _.each(fieldset.containers, function (container) {
+ container.width = avrg;
+ });
+ });
+ });
+ },
+
+ addField: function (container, fieldtype, index) {
+ var newField = {
+ caption: "",
+ id: generateGUID(),
+ settings: {},
+ preValues: [],
+ $focus: true
+ };
+
+ service.loadFieldTypeSettings(newField, fieldtype);
+
+ if (container.fields.length > index) {
+ container.fields.splice(index, 0, newField);
+ } else {
+ container.fields.push(newField);
+ }
+
+ },
+
+ addEmptyField: function (container) {
+
+ var newField = {
+ caption: "",
+ alias: "",
+ id: generateGUID(),
+ settings: {},
+ preValues: [],
+ $focus: true
+ };
+
+ container.fields.push(newField);
+
+ return newField;
+
+ },
+
+ getAllFields: function (form) {
+ var fields = [];
+ if (form.pages) {
+ _.each(form.pages, function (page) {
+ if (page.fieldSets) {
+ _.each(page.fieldSets, function (fieldset) {
+ if (fieldset.containers) {
+ _.each(fieldset.containers, function (container) {
+ if (container.fields) {
+ _.each(container.fields, function (field) {
+ fields.push(field);
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ }
+
+ return fields;
+ },
+
+ copyField: function (container, field, existingFieldAliases) {
+ var index = container.fields.indexOf(field);
+ if (index >= 0) {
+ service.copyFieldAtIndex(container, field, index, existingFieldAliases);
+ }
+ },
+
+ copyFieldAtIndex: function (container, field, index, existingFieldAliases) {
+ var copiedField = Object.assign({}, field);
+ copiedField.id = generateGUID();
+ copiedField.alias = generateCopiedAlias(field.alias, existingFieldAliases);
+ container.fields.splice(index + 1, 0, copiedField);
+ },
+
+ deleteField: function (fieldset, container, field) {
+ var index = container.fields.indexOf(field);
+ if (index >= 0) {
+ service.deleteFieldAtIndex(fieldset, container, index);
+ }
+ },
+
+ deleteFieldAtIndex: function (fieldset, container, index) {
+ container.fields.splice(index, 1);
+ if (container.fields.length === 0) {
+ service.deleteContainer(fieldset, container);
+ }
+ },
+
+ setFieldType: function (field, fieldTypeId) {
+ //get field type
+ field.fieldTypeId = fieldTypeId;
+
+ var fldt = _.find(service.fieldTypes, function (ft) { return ft.id === field.fieldTypeId; });
+ field.$fieldType = fldt;
+
+ service.loadFieldTypeSettings(field, field.$fieldType);
+
+
+ service.loadFieldTypePrevalues(field);
+
+ },
+
+ loadFieldTypePrevalues: function (field) {
+
+ if (field.prevalueSourceId !== null && field.prevalueSourceId !== "00000000-0000-0000-0000-000000000000") {
+
+ preValueSourceResource.getPreValuesByGuid(field.prevalueSourceId)
+ .then(function (response) {
+ field.$preValues = response.data;
+
+ });
+ } else {
+ field.$preValues = null;
+ }
+
+ },
+
+ loadFieldTypeSettings: function (field, fieldtype) {
+
+ var stng = angular.copy(fieldtype.settings);
+
+ if (field.fieldTypeId !== fieldtype.id) {
+ field.settings = {};
+ }
+
+ field.fieldTypeId = fieldtype.id;
+ field.$fieldType = fieldtype;
+
+ if (fieldtype.settings) {
+ _.each(fieldtype.settings, function (setting) {
+ if (!field.settings[setting.alias]) {
+ field.settings[setting.alias] = "";
+ }
+ });
+ }
+ },
+
+
+ deleteConditionRule: function (rules, rule) {
+ var index = rules.indexOf(rule);
+ rules.splice(index, 1);
+ },
+
+ addConditionRule: function (condition) {
+ if (!condition.rules) {
+ condition.rules = [];
+ }
+
+ condition.rules.push({
+ field: condition.$newrule.field,
+ operator: condition.$newrule.operator,
+ value: condition.$newrule.value
+ });
+ },
+
+ addEmptyConditionRule: function (condition) {
+ if (!condition.rules) {
+ condition.rules = [];
+ }
+
+ condition.rules.push({
+ field: "",
+ operator: "",
+ value: ""
+ });
+ },
+
+ populateConditionRulePrevalues: function (selectedField, rule, fields) {
+
+ for (var i = 0; i < fields.length; i++) {
+ var field = fields[i];
+
+ if (field.id === selectedField) {
+
+ // prevalues and be stored in both $preValues and preValues
+ if (field.$preValues && field.$preValues.length > 0) {
+
+ rule.$preValues = field.$preValues;
+
+ } else if (field.preValues && field.preValues.length > 0) {
+
+ var rulePreValuesObjectArray = [];
+
+ // make prevalues to object array
+ for (var preValueIndex = 0; preValueIndex < field.preValues.length; preValueIndex++) {
+
+ var preValue = field.preValues[preValueIndex];
+ var preValueObject = {
+ value: preValue
+ };
+
+ rulePreValuesObjectArray.push(preValueObject);
+ }
+
+ rule.$preValues = rulePreValuesObjectArray;
+
+ } else {
+ rule.$preValues = null;
+ }
+
+ }
+ }
+
+ }
+
+ };
+
+ return service;
+}
+angular.module('umbraco.services').factory('formService', formService);
+
+/**
+ * Compares two software version numbers (e.g. "1.7.1" or "1.2b").
+ *
+ *
+ * @param {string} v1 The first version to be compared.
+ * @param {string} v2 The second version to be compared.
+ * @param {object} [options] Optional flags that affect comparison behavior:
+ *
+ *
+ * lexicographical: true compares each part of the version strings lexicographically instead of
+ * naturally; this allows suffixes such as "b" or "dev" but will cause "1.10" to be considered smaller than
+ * "1.2".
+ *
+ *
+ * zeroExtend: true changes the result if one version string has less parts than the other. In
+ * this case the shorter string will be padded with "zero" parts instead of being considered smaller.
+ *
+ *
+ * @returns {number|NaN}
+ *
+ * 0 if the versions are equal
+ * a negative integer iff v1 < v2
+ * a positive integer iff v1 > v2
+ * NaN if either version string is in the wrong format
+ *
+ */
+
+(function() {
+ 'use strict';
+
+ function utilityService() {
+
+ function compareVersions(v1, v2, options) {
+
+ var lexicographical = options && options.lexicographical,
+ zeroExtend = options && options.zeroExtend,
+ v1parts = v1.split('.'),
+ v2parts = v2.split('.');
+
+ function isValidPart(x) {
+ return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
+ }
+
+ if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
+ return NaN;
+ }
+
+ if (zeroExtend) {
+ while (v1parts.length < v2parts.length) {
+ v1parts.push("0");
+ }
+ while (v2parts.length < v1parts.length) {
+ v2parts.push("0");
+ }
+ }
+
+ if (!lexicographical) {
+ v1parts = v1parts.map(Number);
+ v2parts = v2parts.map(Number);
+ }
+
+ for (var i = 0; i < v1parts.length; ++i) {
+ if (v2parts.length === i) {
+ return 1;
+ }
+
+ if (v1parts[i] === v2parts[i]) {
+ continue;
+ } else if (v1parts[i] > v2parts[i]) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+
+ if (v1parts.length !== v2parts.length) {
+ return -1;
+ }
+
+ return 0;
+ }
+
+ function serverTimeNeedsOffsetting(){
+ //Check if we need to do server time offset to the date we are displaying
+ var needsOffsetting = false;
+ var serverOffset = 0;
+
+ //Check we have a serverTimeOffset in the Umbraco global JS object
+ if (Umbraco.Sys.ServerVariables.application.serverTimeOffset !== undefined) {
+
+ // C# server offset
+ // Will return something like 120
+ serverOffset = Umbraco.Sys.ServerVariables.application.serverTimeOffset;
+
+ //Current local user's date/time offset in JS
+ // Will return something like -120
+ var localOffset = new Date().getTimezoneOffset();
+
+ // If these aren't equal then offsetting is needed
+ // note the minus in front of serverOffset needed
+ // because C# and javascript return the inverse offset
+ needsOffsetting = (-serverOffset !== localOffset);
+ }
+
+ return needsOffsetting;
+ }
+
+
+ var service = {
+
+ compareVersions: compareVersions,
+ serverTimeNeedsOffsetting: serverTimeNeedsOffsetting
+
+ };
+
+ return service;
+
+ }
+
+
+ angular.module('umbraco.services').factory('utilityService', utilityService);
+
+
+})();
+
+
+// Testing if filter already exists, otherwise we will create it.
+angular.module("umbraco.filters").config(function($injector, $provide) {
+ if($injector.has('truncateFilter')) {
+ // Yep, we already got the filter!
+ } else {
+
+ // injecting the filter on the provider, notice we need to add 'Filter' to the name for it to be a filter.
+ $provide.provider('truncateFilter', function() {
+ return {
+ $get: function () {
+
+ // Filter code
+ return function (value, wordwise, max, tail) {
+
+ if (!value) return '';
+
+ /*
+ Overload-fix to support Forms Legacy Version:
+
+ We are making this hack to support the old version of the truncate filter.
+ The old version took different attributes, this code block checks if the first argument isnt a boolean, meaning its not the new version, meaning that the filter is begin used in the old way.
+ Therefor we use the second argument(max) to indicate wether we want a tail (…) and using the first argument(wordwise) as the second argument(max amount of characters)
+ */
+ if (typeof(wordwise) !== 'boolean') {
+ // switch arguments around to fit Forms version.
+ if (max !== true) {
+ tail = '';
+ }
+ max = wordwise;
+ wordwise = false;
+ }
+ // !end of overload fix.
+
+ max = parseInt(max, 10);
+ if (!max) return value;
+ if (value.length <= max) return value;
+
+ tail = (!tail && tail !== '') ? '…' : tail;
+
+ if (wordwise && value.substr(max, 1) === ' ') {
+ max++;
+ }
+ value = value.substr(0, max);
+
+ if (wordwise) {
+ var lastspace = value.lastIndexOf(' ');
+ if (lastspace !== -1) {
+ value = value.substr(0, lastspace+1);
+ }
+ }
+
+ return value + tail;
+ };
+ }
+ }
+ });
+ }
+});
+
+angular.module('umbraco.filters').filter('fileName', function() {
+
+ return function(input) {
+
+ // The input will be a path like so, we just want my-panda-photo.jpg
+ // /media/forms/upload/f2ab8761-6a75-4c9d-a281-92e5e508856a/my-panda-photo.jpg
+
+ input = input.split('\\').pop().split('/').pop();
+
+ return input;
+ };
+
+});
+angular.module('umbraco.filters').filter('momentDateTimeZone', function($filter) {
+
+ return function (input, momentFormat) {
+ var parseDate = moment.utc(input);
+ return parseDate.format(momentFormat);
+ };
+
+});
+
+angular.module('umbraco.filters').filter('relativeDate', function($filter) {
+
+ return function (input) {
+
+ var now = moment();
+ //Hack: Removing the Z so that moment doesn't apply an offset to the time when parsing it
+ var parseDate = moment(input.replace("Z", ""));
+
+ //Check the date is valid
+ if(parseDate.isValid() === false){
+ //Parse the value through the default date filter with the value & setting the param/format to medium {{ value | date:'medium' }}
+ return $filter('date')(input, 'medium');
+ }
+
+ return parseDate.from(now);;
+ };
+
+});
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/cs-CZ.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/cs-CZ.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/cs-CZ.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/da-DK.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/da-DK.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/da-DK.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/de-DE.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/de-DE.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/de-DE.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/en-GB.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/en-GB.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/en-GB.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/en-US.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/en-US.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/en-US.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/es-ES.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/es-ES.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/es-ES.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/fr-FR.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/fr-FR.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/fr-FR.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/he-IL.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/he-IL.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/he-IL.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/it-IT.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/it-IT.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/it-IT.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/ja-JP.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/ja-JP.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/ja-JP.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/ko-KR.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/ko-KR.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/ko-KR.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/nb-NO.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/nb-NO.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/nb-NO.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/nl-NL.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/nl-NL.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/nl-NL.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/pl-PL.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/pl-PL.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/pl-PL.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/pt-BR.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/pt-BR.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/pt-BR.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/ru-RU.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/ru-RU.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/ru-RU.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/sv-SE.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/sv-SE.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/sv-SE.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/zh-CN.xml b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/zh-CN.xml
new file mode 100644
index 0000000..4087392
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/lang/zh-CN.xml
@@ -0,0 +1,6 @@
+
+
+
+ Forms
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/App_Plugins/UmbracoForms/package.manifest b/TestSite-V8.7.3/App_Plugins/UmbracoForms/package.manifest
new file mode 100644
index 0000000..9f4d6f6
--- /dev/null
+++ b/TestSite-V8.7.3/App_Plugins/UmbracoForms/package.manifest
@@ -0,0 +1,52 @@
+{
+ "propertyEditors": [
+ {
+ "alias": "UmbracoForms.FormPicker",
+ "name": "Form Picker",
+ "isParameterEditor": true,
+ "group": "Pickers",
+ "icon": "icon-umb-contour",
+ "editor": {
+ "view": "~/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/formpicker.html"
+ },
+ "prevalues": {
+ "fields": [
+ {
+ "label": "Allowed forms",
+ "description": "The forms allowed, if none are selected all forms will be allowed",
+ "key": "allowedForms",
+ "view": "~/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/formpicker.prevalues.html"
+ }
+ ]
+ }
+ },
+ {
+ "alias": "UmbracoForms.ThemePicker",
+ "name": "Forms Theme Picker",
+ "group": "Pickers",
+ "icon": "icon-brush",
+ "isParameterEditor": true,
+ "editor": {
+ "view": "~/App_Plugins/UmbracoForms/Backoffice/PropertyEditors/themepicker.html"
+ }
+ }
+ ],
+
+ "gridEditors": [
+ {
+ "name": "Form",
+ "alias": "umbraco_form_picker",
+ "view": "/App_Plugins/UmbracoForms/Backoffice/GridEditors/formpicker.html",
+ "render": "macro",
+ "icon": "icon-umb-contour"
+ }
+ ],
+
+ "css": [
+ "~/App_Plugins/UmbracoForms/css/umbraco.forms.css"
+ ],
+
+ "javascript": [
+ "~/App_Plugins/UmbracoForms/js/umbraco.forms.js"
+ ]
+}
\ No newline at end of file
diff --git a/TestSite-V8.7.3/Global.asax b/TestSite-V8.7.3/Global.asax
new file mode 100644
index 0000000..0831274
--- /dev/null
+++ b/TestSite-V8.7.3/Global.asax
@@ -0,0 +1 @@
+<%@ Application Inherits="Umbraco.Web.UmbracoApplication" Language="C#" %>
diff --git a/TestSite-V8.7.3/Media/Web.config b/TestSite-V8.7.3/Media/Web.config
new file mode 100644
index 0000000..cd48da3
--- /dev/null
+++ b/TestSite-V8.7.3/Media/Web.config
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/TestSite-V8.7.3/Properties/AssemblyInfo.cs b/TestSite-V8.7.3/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1496d91
--- /dev/null
+++ b/TestSite-V8.7.3/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("TestSite_V8._7._3")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TestSite_V8._7._3")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("87ce9cbd-12bd-4844-b113-5ee416f8408a")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/TestSite-V8.7.3/TestSite-V8.7.3.csproj b/TestSite-V8.7.3/TestSite-V8.7.3.csproj
new file mode 100644
index 0000000..69146a2
--- /dev/null
+++ b/TestSite-V8.7.3/TestSite-V8.7.3.csproj
@@ -0,0 +1,584 @@
+
+
+
+
+
+ Debug
+ AnyCPU
+
+
+ 2.0
+ {87CE9CBD-12BD-4844-B113-5EE416F8408A}
+ {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
+ Library
+ Properties
+ TestSite_V8._7._3
+ TestSite-V8.7.3
+ v4.7.2
+ true
+
+ 44395
+
+
+
+
+
+
+
+
+ true
+ full
+ false
+ bin\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ true
+ pdbonly
+ true
+ bin\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\ClientDependency.1.9.9\lib\net45\ClientDependency.Core.dll
+
+
+ ..\packages\ClientDependency-Mvc5.1.9.3\lib\net45\ClientDependency.Core.Mvc.dll
+
+
+ ..\packages\CSharpTest.Net.Collections.14.906.1403.1082\lib\net40\CSharpTest.Net.Collections.dll
+
+
+ ..\packages\EPPlus.4.5.3.2\lib\net40\EPPlus.dll
+
+
+ ..\packages\Examine.1.1.0\lib\net452\Examine.dll
+
+
+ ..\packages\HtmlAgilityPack.1.8.14\lib\Net45\HtmlAgilityPack.dll
+
+
+ ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
+
+
+ ..\packages\ImageProcessor.2.7.0.100\lib\net452\ImageProcessor.dll
+
+
+ ..\packages\ImageProcessor.Web.4.10.0.100\lib\net452\ImageProcessor.Web.dll
+
+
+ ..\packages\LightInject.5.4.0\lib\net46\LightInject.dll
+
+
+ ..\packages\LightInject.Annotation.1.1.0\lib\net46\LightInject.Annotation.dll
+
+
+ ..\packages\LightInject.Mvc.2.0.0\lib\net46\LightInject.Mvc.dll
+
+
+ ..\packages\LightInject.Web.2.0.0\lib\net46\LightInject.Web.dll
+
+
+ ..\packages\LightInject.WebApi.2.0.0\lib\net46\LightInject.WebApi.dll
+
+
+ ..\packages\Lucene.Net.3.0.3\lib\NET40\Lucene.Net.dll
+
+
+ ..\packages\Markdown.2.2.1\lib\net451\Markdown.dll
+
+
+ ..\packages\Microsoft.AspNet.Identity.Core.2.2.2\lib\net45\Microsoft.AspNet.Identity.Core.dll
+
+
+ ..\packages\Microsoft.AspNet.Identity.Owin.2.2.2\lib\net45\Microsoft.AspNet.Identity.Owin.dll
+
+
+ ..\packages\Microsoft.AspNet.SignalR.Core.2.4.0\lib\net45\Microsoft.AspNet.SignalR.Core.dll
+
+
+
+ ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
+
+
+ ..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.2\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll
+
+
+ ..\packages\Microsoft.Owin.4.0.1\lib\net45\Microsoft.Owin.dll
+
+
+ ..\packages\Microsoft.Owin.Host.SystemWeb.4.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
+
+
+ ..\packages\Microsoft.Owin.Security.4.0.1\lib\net45\Microsoft.Owin.Security.dll
+
+
+ ..\packages\Microsoft.Owin.Security.Cookies.4.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll
+
+
+ ..\packages\Microsoft.Owin.Security.OAuth.4.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll
+
+
+ ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
+
+
+ ..\packages\MiniProfiler.4.0.138\lib\net461\MiniProfiler.dll
+
+
+ ..\packages\MiniProfiler.Shared.4.0.138\lib\net461\MiniProfiler.Shared.dll
+
+
+ ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\packages\NPoco.3.9.4\lib\net45\NPoco.dll
+
+
+ ..\packages\Owin.1.0\lib\net40\Owin.dll
+
+
+
+ ..\packages\Semver.2.0.4\lib\net452\Semver.dll
+
+
+ ..\packages\Serilog.2.8.0\lib\net46\Serilog.dll
+
+
+ ..\packages\Serilog.Enrichers.Process.2.0.1\lib\net45\Serilog.Enrichers.Process.dll
+
+
+ ..\packages\Serilog.Enrichers.Thread.3.0.0\lib\net45\Serilog.Enrichers.Thread.dll
+
+
+ ..\packages\Serilog.Filters.Expressions.2.0.0\lib\net45\Serilog.Filters.Expressions.dll
+
+
+ ..\packages\Serilog.Formatting.Compact.1.0.0\lib\net45\Serilog.Formatting.Compact.dll
+
+
+ ..\packages\Serilog.Formatting.Compact.Reader.1.0.3\lib\net45\Serilog.Formatting.Compact.Reader.dll
+
+
+ ..\packages\Serilog.Settings.AppSettings.2.2.2\lib\net45\Serilog.Settings.AppSettings.dll
+
+
+ ..\packages\Serilog.Sinks.Async.1.3.0\lib\net45\Serilog.Sinks.Async.dll
+
+
+ ..\packages\Serilog.Sinks.File.4.0.0\lib\net45\Serilog.Sinks.File.dll
+
+
+ ..\packages\Serilog.Sinks.Map.1.0.0\lib\netstandard2.0\Serilog.Sinks.Map.dll
+
+
+ ..\packages\Superpower.2.0.0\lib\net45\Superpower.dll
+
+
+
+ ..\packages\Umbraco.SqlServerCE.4.0.0.1\lib\net472\System.Data.SqlServerCe.dll
+
+
+ ..\packages\Umbraco.SqlServerCE.4.0.0.1\lib\net472\System.Data.SqlServerCe.Entity.dll
+
+
+ ..\packages\System.Diagnostics.DiagnosticSource.4.4.1\lib\net46\System.Diagnostics.DiagnosticSource.dll
+
+
+
+
+
+ ..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll
+
+
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+
+
+
+ ..\packages\System.Text.Encoding.CodePages.4.7.1\lib\net461\System.Text.Encoding.CodePages.dll
+
+
+
+ ..\packages\System.Threading.Tasks.Dataflow.4.9.0\lib\netstandard2.0\System.Threading.Tasks.Dataflow.dll
+
+
+
+ ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll
+
+
+ ..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll
+
+
+ ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.7\lib\net45\System.Web.Http.WebHost.dll
+
+
+ ..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll
+
+
+ ..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll
+
+
+ ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll
+
+
+ ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll
+
+
+ ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll
+
+
+
+
+
+
+
+
+
+ ..\packages\UmbracoCms.Core.8.13.0\lib\net472\Umbraco.Core.dll
+
+
+ ..\packages\UmbracoCms.Web.8.13.0\lib\net472\Umbraco.Examine.dll
+
+
+ ..\packages\UmbracoForms.Core.8.7.3\lib\net472\Umbraco.Forms.Core.dll
+
+
+ ..\packages\UmbracoForms.Core.8.7.3\lib\net472\Umbraco.Forms.Core.Providers.dll
+
+
+ ..\packages\UmbracoForms.Core.8.7.3\lib\net472\Umbraco.Forms.Web.dll
+
+
+ ..\packages\UmbracoForms.Core.8.7.3\lib\net472\Umbraco.Licensing.dll
+
+
+ ..\packages\UmbracoCms.Web.8.13.0\lib\net472\Umbraco.ModelsBuilder.Embedded.dll
+
+
+ ..\packages\UmbracoCms.Web.8.13.0\lib\net472\Umbraco.Web.dll
+
+
+ ..\packages\UmbracoCms.Web.8.13.0\lib\net472\Umbraco.Web.UI.dll
+
+
+
+
+ ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Web.config
+
+
+ Web.config
+
+
+
+
+ {eb1d32f5-d3d0-440e-b71e-ee08566f7d30}
+ UmbracoForms.uCaptcha
+
+
+
+ 10.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+
+
+
+
+ True
+ True
+ 60692
+ /
+ https://localhost:44395/
+ False
+ False
+
+
+ False
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TestSite-V8.7.3/Umbraco/Config/Lang/cs.xml b/TestSite-V8.7.3/Umbraco/Config/Lang/cs.xml
new file mode 100644
index 0000000..a4710d1
--- /dev/null
+++ b/TestSite-V8.7.3/Umbraco/Config/Lang/cs.xml
@@ -0,0 +1,2354 @@
+
+
+
+ Umbraco komunita
+ https://our.umbraco.com/documentation/Extending-Umbraco/Language-Files
+
+
+ Kultura a názvy hostitelů
+ Historie změn
+ Prohlížet uzel
+ Změnit typ dokumentu
+ Kopírovat
+ Vytvořit
+ Exportovat
+ Vytvořit balíček
+ Vytvořit skupinu
+ Odstranit
+ Deaktivovat
+ Vyprázdnit koš
+ Aktivovat
+ Exportovat typ dokumentu
+ Importovat typ dokumentu
+ Importovat balíček
+ Editovat na stránce
+ Odhlásit
+ Přesunout
+ Upozornění
+ Veřejný přístup
+ Publikovat
+ Nepublikovat
+ Znovu načíst uzly
+ Znovu publikovat celý web
+ Práva
+ Přejmenovat
+ Obnovit
+ Nastavit oprávnění pro stránku %0%
+ Kam zkopírovat
+ Kam přesunout
+ do struktury stromu pod
+ Choose where to copy the selected item(s)
+ Choose where to move the selected item(s)
+ bylo přesunuto
+ bylo zkopírováno
+ bylo smazáno
+ Vrátit starší verzi
+ Odeslat k publikování
+ Odeslat k překladu
+ Nastavit skupinu
+ Seřadit
+ Přeložit
+ Aktualizovat
+ Nastavit oprávnění
+ Odemknout
+ Vytvořit šablonu obsahu
+ Přeposlat pozvánku
+
+
+ Obsah
+ Administrace
+ Struktura
+ Ostatní
+
+
+ Povolit přístup k přiřazování kultury a názvů hostitelů
+ Povolit přístup k zobrazení protokolu historie uzlu
+ Povolit přístup k zobrazení uzlu
+ Povolit přístup ke změně typu dokumentu daného uzlu
+ Povolit přístup ke kopírování uzlu
+ Povolit přístup k vytváření uzlů
+ Povolit přístup k mazání uzlů
+ Povolit přístup k přesunutí uzlu
+ Povolit přístup k nastavení a změně veřejného přístupu k uzlu
+ Povolit přístup k publikování uzlu
+ Povolit přístup k zrušení publikování uzlu
+ Povolit přístup ke změně oprávnění pro uzel
+ Povolit přístup k vrácení uzlu do předchozího stavu
+ Povolit přístup k odeslání uzlu ke schválení před publikováním
+ Povolit přístup k odeslání uzlu k překladu
+ Povolit přístup ke změně pořadí uzlů
+ Povolit přístup k překladu uzlu
+ Povolit přístup k uložení uzlu
+ Povolit přístup k vytvoření šablony obsahu
+
+
+ Obsah
+ Info
+
+
+ Přístup zakázán.
+ Přidat novou doménu
+ Odebrat
+ Neplatný uzel.
+ Neplatný tvar domény.
+ Doména už byla přiřazena.
+ Doména
+ Jazyk
+ Nová doména '%0%' byla vytvořena
+ Doména '%0%' je odstraněna
+ Doména '%0%' už byla přiřazena
+ Doména '%0%' byla aktualizována
+ Editace aktuálních domén
+
+
+ Dědit
+ Kultura
+ nebo dědění kultury po nadřazeném uzlu. Vztahuje se také
+ na aktivní uzel.]]>
+ Domény
+
+
+ Zrušit výběr
+ Vybrat
+ Dělat něco jiného
+ Tučně
+ Zrušit odsazení odstavce
+ Vložit formulářové pole
+ Vložit grafický nadpis
+ Editovat Html
+ Odsadit odstavec
+ Kurzíva
+ Zarovnat na střed
+ Zarovnat na levo
+ Zarovnat na pravo
+ Vložit odkaz
+ Vložit místní odkaz (kotvu)
+ Neuspořádaný seznam
+ Číslovaný seznam
+ Vložit makro
+ Vložit obrázek
+ Publikovat a zavřít
+ Publikovat s potomky
+ Editovat vztahy
+ Zpět na seznam
+ Uložit
+ Uložit a zavřít
+ Uložit a publikovat
+ Uložit a naplánovat
+ Uložit a odeslat ke schválení
+ Náhled
+ Uložit zobrazení seznamu
+ Naplánovat
+ Náhled
+ Náhled je deaktivován, protože není přiřazena žádná šablona
+ Vybrat styl
+ Zobrazit styly
+ Vložit tabulku
+ Generovat modely a zavřít
+ Uložit a generovat modely
+ Zpět
+ Znovu
+ Obnovit
+ Smazat štítek
+ Zrušit
+ Potvrdit
+ Další možnosti publikování
+
+
+ Zobrazení pro
+ Obsah smazán
+ Obsah nepublikován
+ Obsah nepublikován pro jazyky: %0%
+ Obsah publikován
+ Obsah publikován pro jazyky: %0%
+ Obsah uložen
+ Obsah uložen pro jazyky: %0%
+ Obsah přesunut
+ Obsah zkopírován
+ Obsah vrácen zpět
+ Obsah odeslán k publikování
+ Obsah odeslán k publikování pro jazyky: %0%
+ Seřadit podřízené položky prováděné uživatelem
+ Kopírovat
+ Publikovat
+ Publikovat
+ Přesunout
+ Uložit
+ Uložit
+ Smazat
+ Nepublikovat
+ Nepublikovat
+ Vrátit zpět
+ Odeslat k publikování
+ Odeslat k publikování
+ Seřadit
+ Historie (všechny jazyky)
+
+
+ Abyste změnili typ dokumentu pro zvolený obsah, nejprve jej vyberte ze seznamu typů platných pro tohle umístění.
+ Pak potvrďte a/nebo pozměňte mapování vlastností z aktuálního typu na nový a dejte Uložit.
+ Obsah byl znovu publikován.
+ Aktuální vlastnost
+ Aktuální typ
+ Typ dokumentu nemůže být změněn, neboť neexistují alternativy platné pro toto umístění.
+ Typ dokumentu byl změněn
+ Mapování vlastností
+ Mapování na vlastnost
+ Nová šablona
+ Nový typ
+ nic
+ Obsah
+ Vybrat nový typ dokumentu
+ Typ dokumentu pro zvolený obsah byl úspěšně změněný na [new type] a následující vlastnosti byly namapovány:
+ na
+ Nelze dokončit mapování vlastností, neboť nejméně jedna z vlastností má definováno více než jedno mapování.
+ Jsou zobrazeny pouze alternativní typy platné pro aktuální umístění.
+
+
+ Nepodařilo se vytvořit složku pod rodičem s ID %0%
+ Nepodařilo se vytvořit složku pod rodičem s názvem %0%
+ Název složky nesmí obsahovat nepovolené znaky.
+ Odstranění položky se nezdařilo: %0%
+
+
+ Is Published
+ O této stránce
+ Alias
+ (jak byste popsali obrázek přes telefon)
+ Alternativní adresy URL
+ Klikněte pro editaci položky
+ Vytvořeno uživatelem
+ Původní autor
+ Aktualizováno uživatelem
+ Vytvořeno
+ Datum/čas vytvoření tohoto dokumentu
+ Typ dokumentu
+ Editování
+ Datum odebrání
+ Tato položko byla změněna po publikování
+ Tato položka není publikována
+ Naposledy publikováno
+ There are no items to show
+ There are no items to show in the list.
+ No child items have been added
+ No members have been added
+ Typ média
+ Odkaz na položky medií
+ Skupina členů
+ Role
+ Typ člena
+ No changes have been made
+ Nevybráno žádné datum
+ Titulek stránky
+ This media item has no link
+ No content can be added for this item
+ Vlastnosti
+ Tento dokument je publikován, ale není viditelný, protože jeho rodič '%0%' publikován není
+ Tato jazyková verze je publikována, ale není viditelná, protože její rodič '%0%' publikován není
+ Jejda: tento dokument je publikován, ale není v mezipaměti (vnitřní chyba)
+ Could not get the URL
+ This document is published but its URL would collide with content %0%
+ This document is published but its URL cannot be routed
+ Publikovat
+ Published
+ Published (pending changes)
+ Stav publikování
+ Publish with descendants to publish %0% and all content items underneath and thereby making their content publicly available.]]>
+ Publish with descendants to publish the selected languages and the same languages of content items underneath and thereby making their content publicly available.]]>
+ Datum publikování
+ Datum ukončení publikování
+ Datum odebrání
+ Set date
+ Třídění je aktualizováno
+ Abyste uzly setřídili, jednoduše je přetáhněte anebo klikněte na jednu z hlaviček sloupce. Podržením "shift" nebo "control" při výběru můžete označit uzlů více.
+ Statistika
+ Titulek (volitelně)
+ Alternative text (optional)
+ Typ
+ Nepublikovat
+ Draft
+ Not created
+ Naposledy změněno
+ Datum/čas poslední změny dokumentu
+ Odebrat soubor(y)
+ Click here to remove the image from the media item
+ Click here to remove the file from the media item
+ URL adresa dokumentu
+ Člen skupin(y)
+ Není člen skupin(y)
+ Podřízené položky
+ Cíl
+ This translates to the following time on the server:
+ What does this mean? ]]>
+ Are you sure you want to delete this item?
+ Are you sure you want to delete all items?
+ Property %0% uses editor %1% which is not supported by Nested Content.
+ No content types are configured for this property.
+ Add element type
+ Select element type
+ Select the group whose properties should be displayed. If left blank, the first group on the element type will be used.
+ Enter an angular expression to evaluate against each item for its name. Use
+ to display the item index
+ Add another text box
+ Remove this text box
+ Content root
+ Include drafts: also publish unpublished content items.
+ This value is hidden. If you need access to view this value please contact your website administrator.
+ This value is hidden.
+ What languages would you like to publish? All languages with content are saved!
+ What languages would you like to publish?
+ What languages would you like to save?
+ All languages with content are saved on creation!
+ What languages would you like to send for approval?
+ What languages would you like to schedule?
+ Select the languages to unpublish. Unpublishing a mandatory language will unpublish all languages.
+ Published Languages
+ Unpublished Languages
+ Unmodified Languages
+ These languages haven't been created
+ Ready to Publish?
+ Ready to Save?
+ Send for approval
+ Select the date and time to publish and/or unpublish the content item.
+ Create new
+ Paste from clipboard
+ This item is in the Recycle Bin
+
+
+ Vytvořit novou šablonu obsahu z '%0%'
+ Prázdná
+ Vybrat obsahovou šablonu
+ Šablona obsahu byla vytvořena
+ Šablona obsahu byla vytvořena z '%0%'
+ Již existuje jiná šablona obsahu se stejným názvem
+ Šablona obsahu je předdefinovaný obsah, který si editor může vybrat jako základ pro vytváření nového obsahu
+
+
+ Klikněte pro nahrání
+ nebo kliknutím sem vyberte soubory
+ Sem můžete přetáhnout a nahrát soubory.
+ Tento soubor nelze nahrát, nemá povolený typ souboru
+ Maximální velikost souboru je
+ Nejvyšší složka médií
+ Nepodařilo se přesunout média
+ Nadřazené a cílové složky nemohou být stejné
+ Médium se nepodařilo zkopírovat
+ Nepodařilo se vytvořit složku pod nadřazeným id %0%
+ Nepodařilo se přejmenovat složku s id %0%
+ Přetáhněte své soubory do oblasti
+
+
+ Vytvořit nového člena
+ Všichni členové
+ Členské skupiny nemají žádné další vlastnosti pro úpravy.
+
+
+ Kde chcete vytvořit nový %0%
+ Vytvořit položku pod
+ Vyberte typ dokumentu, pro který chcete vytvořit šablonu obsahu
+ Zadejte název složky
+ Vyberte typ a titulek
+ "typy dokumentů".]]>
+ Typy dokumentů v části Nastavení .]]>
+ Vybraná stránka ve stromu obsahu neumožňuje vytváření žádných stránek pod ní.
+ Oprávnění k úpravám pro tento typ dokumentu
+ Vytvořit nový typ dokumentu
+ Typy dokumentů v části Nastavení změnou možnosti Povolit jako root v části Oprávnění .]]>
+ "typy medií".]]>
+ Vybraná média ve stromu neumožňuje vytváření pod nimi žádná další média.
+ Upravit oprávnění pro tento typ média
+ Typ dokumentu bez šablony
+ Nová složka
+ Nový datový typ
+ Nový skript JavaScript
+ Nová prázdná částečná šablona
+ Nové makro pro částečnou šablonu
+ Nová částečná šablona ze snippetu
+ Nové makro částečné šablony ze snippetu
+ Nové makro pro částečnou šablonu (bez makra)
+ Nový soubor stylů - stylopis
+ Nový soubor stylů Rich Text editoru
+
+
+ Prohlédnout svůj web
+ - Skrýt
+ Jestli se Umbraco neotevírá, možná budete muset povolit na tomto webu vyskakovací okna
+ byl otevřený v novém okně
+ Restart
+ Navštívit
+ Vítejte
+
+
+ Zůstat zde
+ Zahodit změny
+ Máte neuložené změny
+ Opravdu chcete opustit tuto stránku? Máte neuložené změny.
+ Publikování zviditelní vybrané položky na webu.
+ Zrušení publikování odstraní vybrané položky a všechny jejich potomky z webu.
+ Zrušení publikování odstraní tuto stránku a všechny její potomky z webu.
+ Máte neuložené změny. Provedením změn typu dokumentu změny zahodíte.
+
+
+ Hotovo
+ Smazána %0% položka
+ Smazáno %0% položek
+ Smazána %0% z %1% položek
+ Smazáno %0% z %1% položek
+ Publikována %0% položka
+ Publikováno %0% položek
+ Publikována %0% z %1% položek
+ Publikováno %0% z %1% položek
+ Zrušeno publikování %0% položky
+ Zrušeno publikování %0% položek
+ Zrušeno publikování %0% z %1% položek
+ Zrušeno publikování %0% z %1% položek
+ Přesunuta %0% položka
+ Přesunuto %0% položek
+ Přesunuta %0% z %1% položek
+ Přesunuto %0% z %1% položek
+ Zkopírována %0% položka
+ Zkopírováno %0% položek
+ Zkopírována %0% z %1% položek
+ Zkopírováno %0% z %1% položek
+
+
+ Titulek odkazu
+ Odkaz
+ Kotva / dotaz
+ Název
+ Spravovat názvy hostitelů
+ Zavřít toto okno
+ Jste si jistí. že chcete odstranit
+ Jste si jistí, že chcete deaktivovat
+ Jste si jistí?
+ Jste si jistí?
+ Vyjmout
+ Editovat položku slovníku
+ Editovat jazyk
+ Edit selected media
+ Vložit místní odkaz
+ Vložit znak
+ Vložit grafický titulek
+ Vložit obrázek
+ Vložit odkaz
+ Kliknout pro přidání makra
+ Vložit tabulku
+ Tím se odstraní jazyk
+ Změna kultury jazyka může být náročná operace a bude mít za následek opětovné sestavení mezipaměti obsahu a indexů
+ Naposledy editováno
+ Odkaz
+ Místní odkaz:
+ Při používání místních odkazů vložte znak "#" před odkaz
+ Otevřít v novém okně?
+ Nastavení makra
+ Toto makro nemá žádné vlastnosti, které by bylo možno editovat
+ Vložit
+ Editovat oprávnění pro
+ Nastavit oprávnění pro
+ Nastavit oprávnění pro %0% pro skupinu %1%
+ Vyberte skupiny uživatelů, pro které chcete nastavit oprávnění
+ Položky koše jsou nyní mazány. Nezavírejte, prosím, toto okno, dokud operace probíhá
+ Koš je nyní prázdný
+ Odebrání položek z koše způsobí jejich trvalé odstranění
+ regexlib.com má v tuto chvíli nějaké problémy, které jsou mimo naší kontrolu. Omlouváme se za vzniklé nepříjemnosti.]]>
+ Vyhledat regulární výraz pro přidání validace formulářového prvku. Například: 'email, 'PSČ' 'URL'
+ Odstranit makro
+ Pole je vyžadování
+ Web je přeindexován
+ Mezipaměť webu byla obnovena. Všechen publikovaný obsah je nyní aktuální, zatímco nepublikovaný obsah zůstal nepublikovaný.
+ Mezipaměť webu bude obnovena. Všechen publikovaný obsah bude aktualizován, zatímco nepublikovaný obsah zůstane nepublikovaný.
+ Počet sloupců
+ Počet řádků
+ Klikněte na obrázek pro zobrazení v plné velikosti
+ Vybrat položku
+ Zobrazit položku mezipaměti
+ Navázat na originál
+ Včetně potomků
+ Nejpřátelštější komunita
+ Odkaz na stránku
+ Otevře propojený dokument v novém okně nebo na kartě
+ Odkaz na média
+ Vybrat počáteční uzel obsahu
+ Vybrat média
+ Vybrat typ média
+ Vybrat ikonu
+ Vybrat položku
+ Vybrat odkaz
+ Vybrat makro
+ Vybrat obsah
+ Vybrat typ obsahu
+ Vybrat počáteční uzel média
+ Vybrat člena
+ Vybrat skupinu členů
+ Vybrat typ člena
+ Vybrat uzel
+ Vybrat sekce
+ Vybrat uživatele
+ Nebyly nalezeny žádné ikony
+ Pro toto makro neexistují žádné parametry
+ K dispozici nejsou žádná makra
+ Externí poskytovatelé přihlášení
+ Podrobnosti o výjimce
+ Stacktrace
+ Vnitřní výjimka
+ Propojit se
+ Odpojit se
+ účet
+ Vybrat editora
+ Vybrat snippet
+ Tímto odstraníte uzel a všechny jeho jazyky. Pokud chcete smazat pouze jeden jazyk, měli byste zrušit publikování uzlu v tomto jazyce.
+
+
+ Nejsou žádné položky ve slovníku.
+
+
+ %0%' níže. Můžete přidat další jazyky v nabídce 'jazyky' nalevo.]]>
+ Název jazyka
+
+ Přehled slovníku
+
+
+ Konfigurovaní vyhledávače
+ Zobrazuje vlastnosti a nástroje pro libovolný konfigurovaný vyhledávač (např. pro víceindexový vyhledávač)
+ Hodnoty pole
+ Stav
+ Stav indexu a jeho čitelnost
+ Indexery
+ Informace o indexu
+ Uvádí vlastnosti indexu
+ Spravovat indexy Examine
+ Umožňuje zobrazit podrobnosti každého indexu a poskytuje některé nástroje pro správu indexů
+ Znovu vytvořit index
+ V závislosti na tom, kolik obsahu je na vašem webu, může to chvíli trvat. Nedoporučuje se znovu vytvářet index v době vysokého provozu na webu nebo při úpravách obsahu editory.
+ ]]>
+
+ Vyhledávače
+ Prohledat index a zobrazit výsledky
+ Nástroje
+ Nástroje pro správu indexu
+ pole
+ Index nelze číst a bude nutné jej znovu sestavit
+ Proces trvá déle, než se očekávalo, zkontrolujte Umbraco log a zkontrolujte, zda během této operace nedošlo k chybám
+ Tento index nelze znovu sestavit, protože nemá přiřazen
+ IIndexPopulator
+
+
+ Zadejte Vaše uživatelské jméno
+ Zadejte Vaše heslo
+ Potvrďte heslo
+ Pojmenujte %0%...
+ Zadejte jméno...
+ Zadejte e-mail...
+ Zadejte uživatelské jméno...
+ Popisek...
+ Zadejte popis...
+ Pište pro vyhledání...
+ Pište pro filtrování...
+ Pište pro vložení štítků (po každém stiskněte klávesu Enter)...
+ Vložte svůj e-mail
+ Vložte zprávu...
+ Vaše uživatelské jméno je obvykle váš e-mail
+ #hodnota or ?klíč=hodnota
+ Vložte alias...
+ Generování aliasu...
+
+
+ Vytvořit vlastní zobrazení seznamu
+ Odebrat vlastní zobrazení seznamu
+ Typ obsahu, typ média nebo typ člena s tímto aliasem již existuje
+
+
+ Přejmenováno
+ Sem zadejte nový název složky
+ %0% přejmenováno na %1%
+
+
+ Přidat předlohu
+ Databázový datový typ
+ GUID editoru vlastností
+ Editor vlastností
+ Tlačítka
+ Povolit rozšířené nastavení pro
+ Povolit kontextové menu
+ Největší výchozí rozměr pro vložené obrázky
+ Související stylopisy
+ Zobrazit jmenovku
+ Šířka a výška
+ Všechny typy vlastností a údaje o nich
+ použití tohoto datového typu bude trvale smazáno, potvrďte, že je chcete odstranit
+ Ano, smazat
+ a všechny typy vlastností a data vlastností používající tento typ dat
+ Vyberte složku, kterou chcete přesunout
+ do stromové struktury níže
+ byla přesunuta pod
+ %0% vymažete vlastnosti a jejich data z následujících položek]]>
+ Rozumím, že tato akce odstraní vlastnosti a data založená na tomto datovém typu
+
+
+ Vaše data byla uložena, ale než budete moci publikovat tuto stránku, je třeba odstranit některé chyby:
+ Současný MemberShip Provider nepodporuje změnu hesla (EnablePasswordRetrieval musí mít hodnotu true)
+ %0% již existuje
+ Vyskytly se chyby:
+ Vyskytly se chyby:
+ Heslo musí být nejméně %0% znaků dlouhé a obsahovat nejméně %1% nealfanumerických znaků
+ %0% musí být celé číslo
+ Pole %0% na záložce %1% je povinné
+ %0% je povinné pole
+ %0% v %1% není ve správném formátu
+ %0% není ve správném formátu
+
+
+ Ze serveru byla přijata chyba
+ Použití daného typu souboru bylo zakázáno adminitrátorem
+ UPOZORNĚNÍ! I když CodeMirror je dle konfigurace povolený, je zakázaný v Internet Exploreru, protože není dost stabilní.
+ Vyplňte, prosím, alias i název nového typu vlastností!
+ Vyskytl se problém při čtení/zápisu do určeného souboru nebo adresáře
+ Chyba při načítání skriptu částečné šablony (soubor: %0%)
+ Uveďte, prosím, titulek
+ Vyberte, prosím, typ
+ Chystáte se obrázek zvětšit více, než je jeho původní rozměr. Opravdu chcete pokračovat?
+ Počáteční uzel je odstraněný, kontaktujte, prosím, administrátora
+ Před změnou stylu označte, prosím, obsah
+ Žádne aktivní styly nejsou dostupné
+ Umístěte, prosím, kurzor nalevo od těch dvou buňek, které chcete sloučit
+ Nemužete rozdělit buňku, která nebyla sloučená.
+ Tato vlastnost je neplatná
+
+
+ Volby
+ O...
+ Akce
+ Akce
+ Přidat
+ Alias
+ Vše
+ Jste si jistí?
+ Zpět
+ Zpět na přehled
+ Okraj
+ o
+ Zrušit
+ Okraj buňky
+ Vybrat
+ Vyčistit
+ Zavřít
+ Zavřít okno
+ Komentovat
+ Potvrdit
+ Omezit
+ Zachovat proporce
+ Obsah
+ Pokračovat
+ Kopírovat
+ Vytvořit
+ Databáze
+ Datum
+ Výchozí
+ Odstranit
+ Odstraněno
+ Odstraňování...
+ Vzhled
+ Slovník
+ Rozměry
+ Dolů
+ Stáhnout
+ Editovat
+ Editováno
+ Prvky
+ Email
+ Chyba
+ Pole
+ Najít
+ První
+ Focal point
+ Obecné
+ Skupiny
+ Skupina
+ Výška
+ Nápověda
+ Skrýt
+ Historie
+ Ikona
+ Id
+ Import
+ Zahrnout podsložky do vyhledávání
+ Info
+ Vnitřní okraj
+ Vložit
+ Instalovat
+ Neplatné
+ Vyrovnat
+ Popisek
+ Jazyk
+ Poslední
+ Rozvržení
+ Odkazy
+ Nahrávání
+ Zamčeno
+ Přihlášení
+ Odhlášení
+ Odhlášení
+ Makro
+ Povinné
+ Zpráva
+ Přesunout
+ Název
+ Nový
+ Následující
+ Ne
+ z
+ Vypnuto
+ OK
+ Otevřít
+ Zapnuto
+ nebo
+ Seřadit podle
+ Heslo
+ Cesta
+ Moment, prosím...
+ Předchozí
+ Vlastnosti
+ Obnovit
+ Email pro obdržení formulářových dat
+ Koš
+ Váš koš je prázdný
+ Znovu načíst
+ Zbývající
+ Odebrat
+ Přejmenovat
+ Obnovit
+ Povinné
+ Načíst
+ Zopakovat
+ Oprávnění
+ Plánované publikování
+ Hledat
+ Litujeme, ale nemůžeme najít to, co hledáte.
+ Nebyly přidány žádné položky
+ Server
+ Nastavení
+ Zobrazit
+ Zobrazit stránku při odeslání
+ Rozměr
+ Seřadit
+ Stav
+ Potvrdit
+ Zadejte
+ Pište pro vyhledávání...
+ pod
+ Nahoru
+ Aktualizovat
+ Povýšit
+ Nahrání
+ URL
+ Uživatel
+ Uživatelské jméno
+ Hodnota
+ Pohled
+ Vítejte...
+ Šířka
+ Ano
+ Složka
+ Výsledky hledání
+ Přesunout
+ Skončil jsem s přesouváním
+ Náhled
+ Změnit heslo
+ na
+ Seznam
+ Ukládám...
+ aktuální
+ Vložené
+ vybrané
+ Další
+ Články
+ Videa
+ Instalování
+
+
+ Modrá
+
+
+ Přidat skupinu
+ Přidat vlastnost
+ Přidat editor
+ Přidat šablonu
+ Přidat vnořený uzel
+ Přidat potomka
+ Upravit datový typ
+ Navigace v sekcích
+ Klávesové zkratky
+ zobrazit klávesové zkratky
+ Přepnout zobrazení seznamu
+ Přepnout povolení jako root
+ Okomentovat/Odkomentovat řádky
+ Odebrat řádek
+ Kopírovat řádky nahoru
+ Kopírovat řádky dolů
+ Přesunout řádky nahoru
+ Přesunout řádky dolů
+ Obecný
+ Editor
+ Přepnout povolení jazykových verzí
+
+
+ Barva pozadí
+ Tučně
+ Barva písma
+ Font
+ Text
+
+
+ Stránka
+
+
+ Instalátor se nemůže připojit k databázi.
+ Nelze uložit soubor web.config. Modifikujte, prosím, připojovací řetězec manuálně.
+ Vyše databáze byla nalezena a je identifikována jako
+ Nastavení databáze
+ instalovat, abyste nainstalovali Umbraco %0% databázi
+ ]]>
+ následující pro pokračování.]]>
+ Databáze nenalezena! Zkontrolujte, prosím, že informace v "připojovacím řetězci" souboru "web.config" jsou správné.
+ Pro pokračování otevřete, prosím, soubor "web.config" (za pužití Visual Studia nebo Vašeho oblíbeného tedtového editoru), přejděte na jeho konec, přidejte připojovací řetězec pro Vaši databázi v klíčí nazvaném "umbracoDbDSN" a soubor uložte.
+
+ Klikněte na tlačítko zopakovat , až budete hotovi.
+ Další informace o editování souboru web.config zde .
]]>
+
+ Pokud je to nezbytné, kontaktujte vašeho poskytovatele hostingu.
+ Jestliže instalujete na místní počítač nebo server, budete potřebovat informace od Vašeho systémového administrátora.]]>
+
+ Stiskněte tlačítko povýšit pro povýšení Vaší databáze na Umbraco %0%
+
+ Neobávejte se - žádný obsah nebude odstraněn a všechno bude fungovat jak má!
+
+ ]]>
+ Stiskněte Následující pro pokračování. ]]>
+ následující, pro pokračování konfiguračního průvodce]]>
+ Heslo výchozího uživatele musí být změněno!]]>
+ Výchozí uživatel byl deaktivován, nebo nemá přístup k umbracu!Netřeba nic dalšího dělat. Klikněte na Následující pro pokračování.]]>
+ Heslo výchozího uživatele bylo úspěšně změněno od doby instalace!Netřeba nic dalšího dělat. Klikněte na Následující pro pokračování.]]>
+ Heslo je změněno!
+ Mějte skvělý start, sledujte naše uváděcí videa
+ Kliknutím na tlačítko následující (nebo modifikováním umbracoConfigurationStatus v souboru web.config) přijímáte licenci tohoto software tak, jak je uvedena v poli níže. Upozorňujeme, že tato distribuce Umbraca se skládá ze dvou různých licencí, open source MIT licence pro framework a Umbraco freeware licence, která pokrývá UI.
+ Není nainstalováno.
+ Dotčené soubory a složky
+ Další informace o nastavování oprávnění pro Umbraco zde
+ Musíte udělit ASP.NET oprávnění měnit následující soubory/složky
+ Vaše nastavení oprávnění je téměř dokonalé!
+ Můžete provozovat Umbraco bez potíží, ale nebudete smět instalovat balíčky, které jsou doporučené pro plné využívání všech možností umbraca.]]>
+ Jak to vyřešit
+ Klikněte zde, chcete-li číst textovou verzi
+ výukové video o nastavovaní oprávnění pro složky umbraca, nebo si přečtěte textovou verzi.]]>
+ Vaše nastavení oprávnění může být problém!
+
+ Můžete provozovat Umbraco bez potíží, ale nebudete smět vytvářet složky a instalovat balíčky, které jsou doporučené pro plné využívání všech možností umbraca.]]>
+ Vaše nastavení oprívnění není připraveno pro umbraco!
+
+ Abyste mohli Umbraco provozovat, budete muset aktualizovat Vaše nastavení oprávnění.]]>
+ Vaše nastavení oprávnění je dokonalé!
+ Jste připraveni provozovat Umbraco a instalovat balíčky!]]>
+ Řešení potíží se složkami
+ Následujte tento odkaz pro další informace o potížích s ASP.NET a vytvářením složek.
+ Nastavování oprávnění pro složky
+
+ Chci začít od nuly
+ zjistěte jak)
+ Stále se můžete později rozhodnout nainstalovat Runway. Za tím účelem navštivte Vývojářskou sekci a zvolte Balíčky.
+ ]]>
+ Právě jste vytvořili čistou platformu Umbraco. Co chcete dělat dále?
+ Runway je nainstalován
+
+ Toto je náš seznam doporučených modulů, vyberte ty, které chcete nainstalovat, nebo si prohlédněte úplný seznam modulů
+ ]]>
+ Doporučeno pouze pro zkušené uživatele
+ Chci začít s jednoduchým webem
+
+ "Runway" je jednoduchý web poskytující některé základní typy dokumentů a šablon. Instalátor pro Vás může Runway nainstalovat automaticky a Vy ho pak můžete jednoduše editovat, rozšířit anebo úplně odstranit. Není nezbytný a můžete bez problému provozovat Umbraco bez něj. Runway nicméně nabízí jednoduché základy založené na nejlepších praktikách tak, abyste mohli začít rychleji, než kdykoliv jindy. Rozhodnete-li se Runway si nainstalovat, můžete si volitelně vybrat základní stavební bloky zvané Moduly Runway a stránky Runway si tak vylepšit.
+
+
+ Runway obsahuje: Úvodní stránku, stránku Začínáme, stránku Instalace modulů.
+ Volitelné moduly: Horní navigace, Mapa webu, Kontakt, Galerie.
+
+ ]]>
+ Co je Runway
+ Krok 1/5: Přijetí licence
+ Krok 2/5: Konfigurace databáze
+ Krok 3/5: Ověřování oprávnění k souborům
+ Krok 4/5: Kontrola zabezpečení umbraca
+ Krok 5/5: Umbraco je připraveno a můžete začít
+ Děkujeme, že jeste si vybrali umbraco
+ Prohlédněte si svůj nový web
+ Nainstalovali jste Runway, tak proč se nepodívat, jak Váš nový web vypadá.]]>
+ Další pomoc a informace
+ Abyste získali pomoc od naší oceňované komunity, projděte si dokumentaci, nebo si pusťte některá videa zdarma o tom, jak vytvořit jednoduchý web, jak používat balíčky a rychlý úvod do terminologie umbraca]]>
+ Umbraco %0% je nainstalováno a připraveno k použití
+ soubor /web.config a upravit klíč AppSetting umbracoConfigurationStatus dole na hodnotu '%0%' .]]>
+ ihned začít kliknutím na tlačítko "Spustit Umbraco" níže. Jestliže je pro Vás Umbraco nové ,
+ spoustu zdrojů naleznete na naších stránkách "začínáme".]]>
+ Spustit Umbraco
+ Chcete-li spravovat Váš web, jednoduše přejděte do administrace umbraca a začněte přidávat obsah, upravovat šablony a stylopisy, nebo přidávat nové funkce]]>
+ Připojení k databázi selhalo.
+ Umbraco verze 3
+ Umbraco verze 4
+ Shlédnout
+ umbraca %0% jako čisté instalace nebo povýšením z 3.0.
+
+ Stiskněte "následující" pro spuštění průvodce.]]>
+
+
+ Kód jazyka
+ Název jazyka
+
+
+ Byli jste nečinní a odhlášení proběhne automaticky za
+ Obnovte nyní pro uložení práce
+
+
+ Šťastnou super neděli
+ Šťastné šílené pondělí
+ Šťastné husté úterý
+ Šťastnou překrásnou středu
+ Šťastný bouřlivý čtvrtek
+ Šťastný bláznivý pátek
+ Šťastnou kočkobotu
+ přihlašte se níže
+ Přihlásit se pomocí
+ Relace vypršela
+ © 2001 - %0% umbraco.org ]]>
+ Zapomenuté heslo?
+ Na uvedenou adresu bude zaslán e-mail s odkazem pro obnovení hesla
+ Pokud odpovídá našim záznamům, bude na zadanou adresu zaslán e-mail s pokyny k obnovení hesla
+ Zobrazit heslo
+ Skrýt heslo
+ Vrátit se na přihlašovací obrazovku
+ Zadejte nové heslo
+ Vaše heslo bylo aktualizováno
+ Odkaz, na který jste klikli, je neplatný nebo jeho platnost vypršela
+ Umbraco: Resetování hesla
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vyžadováno resetování hesla
+
+
+ Vaše uživatelské jméno pro přihlášení do backoffice Umbraco je: %0%
+
+
+
+
+ Pokud nemůžete kliknout na odkaz, zkopírujte a vložte tuto adresu URL do okna prohlížeče:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+