(function(window, document, undefined) {

	// FORM CLASS ==========================================================
	var mzForm = {
		// PROPERTIES ======================================================
		resolution: 1,
		div: null,
		_id: null,
		

		// INIT INTERFACE AND GET FORM VIA AJAX ============================
		init: function() {
			mzForm.div = document.getElementById('helpdonatie');
			if (!mzForm.div) return;
			
			// ID
			mzForm._id = mzForm.div.hasAttribute('data-id') ? mzForm.div.getAttribute('data-id') : false;

			// ADD FONTS
			var font = document.createElement('LINK');
			font.setAttribute('href', "https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap");
			font.setAttribute('rel', "stylesheet");
			document.head.appendChild(font);

			// AJAX
			var xhr = new XMLHttpRequest();
			xhr.open("POST", "https://helpautism.ro/helpdonatie");
			xhr.onreadystatechange = mzForm.gotajax.bind(xhr);
			xhr.send(xhrParams([['url', window.location],['id',mzForm._id || '0']]));
			
			setTimeout( function() {
				if ( !mzForm.gTaggedLoad ) {
					mzForm.gTaggedLoad = true;
					gtag( "event", "click", {
						"event_category": "helpautism_f230",
						"event_label": "formular_deschis"
					} );
				}
			}, 1000 );
		},
		copyLink: function( e ) {
			if ( !e || !e.target ) return;
			var inp = e.target;
			
			while ( !inp.hasAttribute('href') && !!inp.parentNode )
				inp = inp.parentNode;
			if ( !inp.hasAttribute( 'href' ) ) return;
			var val = inp.getAttribute( 'href' );
			
			inp = document.createElement('textarea');
			inp.style.position = 'fixed';
			inp.style.opacity = '0';
			inp.style.left = '50%';
			inp.style.top = '50%';
			inp.style.width = '1px';
			inp.style.height = '1px';
			inp.value = val;
			document.body.appendChild( inp );
			inp.select();
			inp.setSelectionRange( 0, val.length ); // MOBILE
			try {
				document.execCommand('copy');
				e.preventDefault(); e.stopPropagation();
				document.getElementById('copylinktxt').innerHTML = 'Text copiat!';
				setTimeout( mzForm.copied, 3000 );
			} catch (eee) { console.log( eee ); }
			inp.parentNode.removeChild( inp );
		},
		copied: function( btn ) {
			document.getElementById('copylinktxt').innerHTML = 'Copiază';
		},
		referent: function(e) {
			var ref = document.getElementById('don_refe');
			var chk = document.getElementById('don_refe_check');
			var dsc = document.getElementById('don_refe_desc');
			if (!ref || !dsc) return;
			var val = ref.value;
			var ok = false;
			
			if (chk.checked) {
				for (var i=0,o=ref.querySelectorAll('option'),n=o.length; i<n; i++) {
					if (o[i].value == val) {
						ok = o[i].getAttribute('data-place');
						if (ok != '') {
							dsc.setAttribute('placeholder', ok);
							ok = true;
						}
						break;
					}
				}
			}
			ref.parentNode.style.display = chk.checked ? 'block' : 'none';
			dsc.parentNode.parentNode.style.display = ok ? 'flex' : 'none';
		},
		gotajax: function () {
			if (this.readyState !== 4 || this.status !== 200) return;
			try {
				var msg = JSON.parse(this.responseText);
				if (msg.status == 'ok') {
					// ALREADY PRESENT
					if (!!document.getElementById('helpdon')) return;

					// INSERT POSITION
					var after = document.getElementById('helpdonatie');
					//if (!after) after = document.body.querySelector('script[src*=helpdonatie]');
					if (!after) return;

					// HTML
					var div = document.createElement('div');
					div.id = 'helpdon';

					// DPI
					/*
					this.resolution = window.devicePixelRatio;
					if (this.resolution < 1.2) {
						div.style.fontSize = Math.round(17 * this.resolution).toString() + 'px';
					} else {
						div.style.fontSize = Math.round(17 * this.resolution * 0.3).toString() + 'px';
					}
					*/

					// PARAMS
					div.className = 'helpout';
					div.innerHTML = msg.html;
					
					// INSERT
					after.parentNode.insertBefore(div, after.nextSibling);
					after.parentNode.removeChild(after);
					
					// EXPIRAT
					var expirat = div.querySelector('#helpexpirat');
					if (!!expirat && expirat.hasAttribute('data-activ') && expirat.getAttribute('data-activ')=='1') {
						expirat.style.display = "block";
						expirat.className = expirat.className.replace('hidden', '');
						setTimeout(function(){expirat.style.opacity = '1';}, 10);
						if (expirat.className.indexOf('noform') >= 0) {
							div.querySelector('form').style.display = 'none';
							return;
						}
					}

					// EMBED
					var emb = document.getElementById('helpembed');
					emb.addEventListener('click', function(){
						document.getElementById('helpdon-pop').style.display = 'block';
					});
					document.getElementById('helpdon-pop').addEventListener('click', function(){
						document.getElementById('helpdon-pop').style.display = 'none';
					});
					document.getElementById('helpdon-pop-content').addEventListener('click', function(e){
						e.stopPropagation();
						e.preventDefault();
					});
					
					// SPECIALS
					var don_refe = document.getElementById('don_refe');
					if (!!don_refe) {
						document.getElementById('don_refe_check').addEventListener('change', mzForm.referent);
						don_refe.addEventListener('change', mzForm.referent);
					}

					// ANIMATE
					setTimeout(function(){
						this.className = '';
						mzForm.semnatura.resize();
					}.bind(div), 50);
					// ATTACH FUNCS
					mzForm.gotform(div);
					// RESOLUTION 2
					if (this.resolution > 1.2)
						document.getElementById('maimic').style.fontSize="0.5em";
				} else { console.log(msg); }
			} catch (e) { console.log(this.responseText); }
		},

		// ATTACH FUNCTIONS ================================================
		gotform: function (div) {
			var i, max, fn, sel;

			// CREATE SIGNATURE
			this.semnatura = new MzSign(
				document.getElementById('semnatura-cnt'),
				document.getElementById('semnatura-res'),
				1000, 400, mzForm.semnat_set
			);
			this.semnatura.canvas.id = 'semnatura';

			// TRIMITERE
			document.getElementById('helpdonsend').addEventListener('click', mzForm.submit);

			// SELECT ONCHANGE
			sel = document.body.querySelectorAll('#helpdon select');
			for (i = 0, max = sel.length; i < max; i++) {
				fn = mzForm.selChange.bind(sel[i]);
				sel[i].addEventListener('change', fn);
				fn();
			}

			// TEXT / SELECT VALIDATION
			sel = document.body.querySelectorAll('#helpdon input[type=text], #helpdon select');
			for (i = 0, max = sel.length; i < max; i++) {
				if (!sel[i].hasAttribute('data-help-optional')) {
					if (sel[i].hasAttribute('data-help-cnp')) {
						fn = mzForm.validCNP.bind(sel[i]);
					} else if (sel[i].hasAttribute('data-help-mail')) {
						fn = mzForm.validMail.bind(sel[i]);
					} else if (sel[i].hasAttribute('data-help-tel')) {
						fn = mzForm.validTel.bind(sel[i]);
					} else if (sel[i].name == 'county') {
						sel[i].addEventListener('change', mzForm.validJudet.bind(sel[i]));
						fn = mzForm.validEmpty.bind(sel[i]);
					} else {
						fn = mzForm.validEmpty.bind(sel[i]);
					}
					mzForm.validators.push(fn);
					if (sel[i].tagName.toLowerCase() == 'input')
						sel[i].addEventListener('keyup', fn);
					sel[i].addEventListener('change', fn);
				} else if (sel[i].hasAttribute('data-help-number')) {
					fn = mzForm.validNumber.bind(sel[i]);
					mzForm.validators.push(fn);
					sel[i].addEventListener('keyup', fn);
					sel[i].addEventListener('change', fn);
				}
			}
			
			// COPYLINK
			var e = document.getElementById('copylink');
			if ( !!e )
				e.addEventListener( 'click', mzForm.copyLink );

			// CHECKBOX VALIDATION
			sel = document.body.querySelectorAll('#helpdon input[type=checkbox]');
			for (i = 0, max = sel.length; i < max; i++) {
				if (!sel[i].hasAttribute('data-help-optional')) {
					fn = mzForm.validCheck.bind(sel[i]);
					mzForm.validators.push(fn);
					sel[i].addEventListener('change', fn);
				}
			}
		},


		// SIGNATURE =======================================================
		semnat: false,
		semnatura : false,
		semnat_set: function (val) {
			mzForm.semnat = val;
			setClass(document.getElementById('semnatura-cnt'), 'incomplet', !val);
		},

		// INPUT VALUE CHANGE HANDLER ======================================
		selChange: function () {
			this.style.color = this.value == "" ? '#b0b0b0' : '#000000';
		},

		// SUBMIT ==========================================================
		gTaggedLoad: false,
		gTaggedDone: false,
		submit: function(){
			// VALIDATE
			if (!mzForm.validAll()) {
				shake(document.getElementById('helpdon'));
				return;
			};

			// BUILD
			var form   = document.getElementById('helpdon').getElementsByTagName('form')[0];
			var params = new FormData(form);

			params.append('semnatura',
				mzForm.semnatura.ucanvas.toDataURL());
			var jud = document.getElementById('helpjudet');
			var loc = document.getElementById('helploca');
			params.append('countyName',
				jud.options[jud.selectedIndex].text);
			params.append('localityName',
				loc.options[loc.selectedIndex].text);
			if (!!mzForm._id)
				params.append('id', mzForm._id);

			// SEND
			var xhr = new XMLHttpRequest();
			xhr.open("POST", "https://helpautism.ro/helpdonatie");
			xhr.onreadystatechange = function(){
				if (xhr.readyState !== 4 || xhr.status !== 200) return;
				try {
					var msg = JSON.parse(xhr.responseText);
					if (msg.status == 'error') {
						alert(msg.message);
						shake(document.getElementById('helpdon'));
					} else if (msg.status == 'ok') {
						document.getElementById('helpdon').className = 'helpsent';
						setTimeout( function() {
							document.getElementById('helpdon').querySelector('form').style.display = 'none';
							var thanks = document.getElementById('helpthanks');
							thanks.style.display = 'block';
							thanks.removeAttribute('class');
						}, 900);
						if (!!msg.pdf) {
							window.location =
								'https://helpautism.ro/helpdonatie/' + msg.pdf;
							document.getElementById('helpthanks-but').setAttribute('href',
								'https://helpautism.ro/helpdonatie/' + msg.pdf);
						}
						if ( !mzForm.gTaggedDone ) {
							mzForm.gTaggedDone = true;
							gtag( "event", "click", {
								"event_category": "helpautism_f230",
								"event_label": "trimis_cu_succes"
							} );
						}
					} else { console.log(msg); }
				} catch (e) { alert('Eroare server, va rugam reincercati.'); console.log(xhr.responseText); }
			}.bind(this);
			xhr.send(params);
		},

		// VALIDATION ======================================================
		validAll: function () {
			var valid = true;

			// CONTROLS
			for (var i = 0, max = mzForm.validators.length; i < max; i++) {
				valid = mzForm.validators[i]() && valid;
			}

			// SEMNATURA
			setClass(document.getElementById('semnatura-cnt'), 'incomplet', !mzForm.semnat);
			valid = valid && mzForm.semnat;

			// MAIL VS TELEFON
			/*
			var mail = document.getElementById('zemail');
			var tel = document.getElementById('zetel');
			if ((!mail.value || mail.value == '')
				&& (!tel.value ||  tel.value == '')) {
				alert('Va rugam completati fie mailul fie telefonul.');
				valid = false;
			}
			*/

			// RETURN
			return valid;
		},

		// VALIDATOR FUNCTIONS =============================================
		validators: [],
		validCNP: function () {
			if (!this.value || this.value == '') {
				remClass(this.parentNode, 'incorect');
				addClass(this.parentNode, 'incomplet');
				return false;
			} else {
				var valid = mzForm.testCNP(this.value);
				remClass(this.parentNode, 'incomplet');
				setClass(this.parentNode, 'incorect', !valid);
				return valid;
			}
		},
		testCNP: function (p_cnp) {
			var i = 0, year = 0, hashResult = 0, cnp = [],
				hashTable = [2,7,9,1,4,6,3,5,8,2,7,9];
			if (p_cnp.length !== 13)  return false;
			for (i = 0; i < 13; i++) {
				cnp[i] = parseInt(p_cnp.charAt(i), 10);
				if (isNaN(cnp[i])) return false;
				if (i < 12)
					hashResult = hashResult + (cnp[i] * hashTable[i]);
			}
			hashResult = hashResult % 11;
			if (hashResult === 10) hashResult = 1;
			year = (cnp[1] * 10) + cnp[2];
			switch (cnp[0]) {
				case 1 :
				case 2 : { year += 1900; } break;
				case 3 :
				case 4 : { year += 1800; } break;
				case 5  :
				case 6 : { year += 2000; } break;
				case 7  :
				case 8 :
				case 9 : {
					year += 2000;
					if (year > (parseInt(new Date().getYear(), 10) - 14))
						year -= 100;
					} break;
				default : { return false; }
			}
			if (year < 1800 || year > 2099) return false;
			return cnp[12] === hashResult;
		},
		validJudet: function() {
			if (mzForm.validEmpty.call(this) == false) {
				var loc = document.getElementById('helploca');
				loc.style.opacity = '0.4';
				var empty = loc.querySelector('.helpplh');
				loc.removeChild(empty);
				empty.innerHTML = 'Localitate (alege judetul)';
				loc.innerHTML = '';
				loc.appendChild(empty);
				return false;
			}
			var xhr = new XMLHttpRequest();
			xhr.open("POST", "https://helpautism.ro/helpdonatie");
			xhr.onreadystatechange = function(){
				if (xhr.readyState !== 4 || xhr.status !== 200) return;
				try {
					var msg = JSON.parse(xhr.responseText);
					var loc = document.getElementById('helploca');
					loc.style.opacity = '1';
					var empty = loc.querySelector('.helpplh');
					loc.removeChild(empty);
					empty.innerHTML = 'Localitate (alege)';
					loc.innerHTML = '';
					loc.appendChild(empty);
					var o;
					for (var i in msg) {
						//if (Object.prototype.hasOwnProperty.call(obj, prop)) {}
						o = document.createElement('OPTION');
						o.value = i;
						o.innerHTML = msg[i];
						loc.appendChild(o);
					}
					for (var i=0, max=msg.length; i<max; i++) {

					}
				} catch (e) { console.log(xhr.responseText); }
			}.bind(this);
			xhr.send(xhrParams([['localitati', this.value]]));
			return true;
		},
		validMail: function () {
			if (!this.value || this.value == '') {
				remClass(this.parentNode, 'incorect');
				//setClass(this.parentNode, 'incomplet', this.parentNode.getAttribute());
				return true;
			} else {
				var valid = (/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(this.value));
				//remClass(this.parentNode, 'incomplet');
				setClass(this.parentNode, 'incorect', !valid);
				return valid;
			}
		},
		validTel: function () {
			if (!this.value || this.value == '') {
				remClass(this.parentNode, 'incorect');
				setClass(this.parentNode, 'incomplet', this.required);//this.parentNode.getAttribute());
				return true;
			} else {
				var valid = (/^[0-9]+$/.test(this.value) && this.value.length == 10);
				remClass(this.parentNode, 'incomplet');
				setClass(this.parentNode, 'incorect', !valid);
				return valid;
			}
		},
		validNumber:function() {
			if (!this.value || this.value == '') {
				remClass(this.parentNode, 'incorect');
				setClass(this.parentNode, 'incomplet', this.required);
				return !this.required;
			} else {
				remClass(this.parentNode, 'incomplet');
				var valid = /^[0-9]+$/.test(this.value);
				setClass(this.parentNode, 'incorect', !valid);
				return valid;
			}
		},
		validEmpty: function () {
			var invalid = !this.value || this.value == '';
			setClass(this.parentNode, 'incomplet', invalid);
			return !invalid;
		},
		validCheck: function () {
			setClass(this.parentNode.parentNode, 'incomplet', !this.checked);
			return this.checked;
		}
	};

	// SIGNATURE CLASS =====================================================
	function MzSign(element, resetbtn, width, height, onvalid) {
		this.binder(this);

		// PARAMS
		this.width  = width;
		this.height = height;
		if (!!onvalid) this.onvalid = onvalid.bind(this);

		// Main canvas
		var canvas = document.createElement('CANVAS');
		canvas.addEventListener('touchstart' , this.press); // PRESS
		canvas.addEventListener('mousedown'  , this.press);
		canvas.addEventListener('touchmove'  , this.move); // MOVE
		canvas.addEventListener('mousemove'  , this.move);
		canvas.addEventListener('touchcancel', this.lift); // UNPRESS
		canvas.addEventListener('mouseleave' , this.lift);
		canvas.addEventListener('touchend'   , this.lift);
		canvas.addEventListener('mouseup'    , this.lift);
		this.ctx = canvas.getContext('2d');
		this.ctx.lineJoin  = 'round';
		this.ctx.lineCap   = 'round';
		element.appendChild(canvas);
		this.canvas = canvas;

		// Main canvas resize listener
		window.addEventListener('resize', this.resize);

		// Hidden full res canvas
		var ucanvas = document.createElement('CANVAS');
		ucanvas.style.display = 'none';
		ucanvas.setAttribute('width', width);
		ucanvas.setAttribute('height', height);
		this.ctu = ucanvas.getContext('2d');
		this.ctu.lineJoin = 'round';
		this.ctu.lineCap  = 'round';
		element.appendChild(ucanvas);
		this.ucanvas = ucanvas;

		// Adapt to view
		this.resize();

		// Reset button
		resetbtn.addEventListener('click', this.clear);
	};
	MzSign.prototype = {
		constructor: MzSign,

		// ELEMENTS __________________________________
		ucanvas: null,
		canvas: null,
		ctu: null,
		ctx: null,
		points: [],

		// DRAW PARAMS _______________________________
		redraw_timer: false,
		untouched: true,
		drawing: false,
		thickness: 3,
		area: false,

		// UPLOADED IMAGE SIZE _______________________
		width:  100,
		height: 100,

		// VALIDATION ________________________________
		valid_treshold: 8, // Points
		onvalid: false,    // Handler
		valid: false,      // Is valid


		// METHOD BINDER _____________________________
		binder: function(_this) {
			_this.endline = _this.endline.bind(_this);
			_this.lift = _this.lift.bind(_this);
			_this.resize  = _this.resize.bind(_this);
			_this.recalc  = _this.recalc.bind(_this);
			_this.getpos = _this.getpos.bind(_this);
			_this.point   = _this.point.bind(_this);
			_this.press   = _this.press.bind(_this);
			_this.clear   = _this.clear.bind(_this);
			_this.move    = _this.move.bind(_this);
			_this.draw    = _this.draw.bind(_this);
		},

		// RESIZE FUNCTION ___________________________
		resize: function() {
			this.area = this.canvas.getBoundingClientRect();
			this.canvas.width  = this.area.width;
			this.canvas.height = this.ucanvas.height / this.ucanvas.width * this.area.width;
			this.canvas.style.height = this.canvas.height + 'px';
			if (this.untouched || this.points.length < 2) return;
			if (!!this.redraw_timer) window.clearTimeout(this.redraw_timer);
			this.redraw_timer = window.setTimeout(this.draw, 100); //\\
		},

		// MOUSE / TOUCH POSITION ____________________
		getpos: function(e) {
			if (!!e.touches && e.touches.length > 0)
				return {
					x: ((e.touches[0] || e.changedTouches[0]).clientX - this.area.left)
						/ parseFloat(this.area.width),
					y: ((e.touches[0] || e.changedTouches[0]).clientY - this.area.top )
						/ parseFloat(this.area.height)
				};
			else
				return {
					x: (e.clientX - this.area.left) / parseFloat(this.area.width),
					y: (e.clientY - this.area.top ) / parseFloat(this.area.height)
				};
		},

		// POINT INSERTION ___________________________
		point: function(e) {
			var p0 = (this.points.length < 1 ? false : this.points[this.points.length - 1]);
			var p = this.getpos(e);
			p.end = false;
			if (p0 == false || this.isfar(p0, p)) {
				this.points.push(p);
				this.draw();
			}
		},
		endline: function(e) {
			if (this.points.length < 2) return;
			/*
			var p = this.getpos(e);
			this.points[this.points.length - 1] = {
				x: p.x,
				y: p.y,
				end: true
			};
			*/
			this.points[this.points.length - 1].end = true;
			this.draw();
		},


		// MOUSE / TOUCH INTERACTION _________________
		press: function(e) {
			e.preventDefault(); e.stopPropagation();
			this.resize();
			this.untouched = false;
			this.drawing = true;
			this.point(e);
		},
		move: function(e) {
			e.preventDefault(); e.stopPropagation();
			if (!this.drawing) return;
			this.point(e);
		},
		lift: function(e) {
			e.preventDefault(); e.stopPropagation();
			if (!this.drawing) return;
			this.drawing = false;
			this.endline(e);
			if (!this.untouched) {
				var _valid = this.valid;
				this.valid = this.points.length >= this.valid_treshold;
				if (!!this.onvalid && _valid != this.valid)
					this.onvalid(this.valid);
			}
		},

		// DRAWING ___________________________________
		draw: function() {
			// CLEAN CANVASES
			this.ctx.clearRect(0, 0, this.area.width, this.area.height);
			this.ctu.clearRect(0, 0,      this.width,      this.height);

			// NOTHING TO DO, RETURN
			if (this.points.length < 2) return;

			// PARAMS
			this.ctx.lineWidth = this.thickness;
			this.ctu.lineWidth = this.thickness * 2.5;
			this.ctx.strokeStyle = "#1e66d9";
			this.ctu.strokeStyle = "#1e66d9";

			// RESIZE POINTS TO SCREEN & UPLOAD CANVASES
			var points = this.recalc();
			this.ctu.beginPath();
			this.ctx.beginPath();
			this.ctu.moveTo(points[1][0].x, points[1][0].y);
			this.ctx.moveTo(points[0][0].x, points[0][0].y);

			// DRAW
			for (var i=1, max=points[0].length; i<max; i++) {
				var mid0 = this.midpoint(points[0][i-1], points[0][i]);
				var mid1 = this.midpoint(points[1][i-1], points[1][i]);
				if (points[0][i-1].end) {
					// CLOSE LAST
					if (i > 2) {
						this.ctx.lineTo(points[0][i-1].x, points[0][i-1].y);
						this.ctu.lineTo(points[1][i-1].x, points[1][i-1].y);
					}
					// JUMP TO NEXT
					this.ctx.moveTo(points[0][i].x, points[0][i].y);
					this.ctu.moveTo(points[1][i].x, points[1][i].y);
				} else {
					this.ctx.quadraticCurveTo(points[0][i-1].x, points[0][i-1].y, mid0.x, mid0.y);
					this.ctu.quadraticCurveTo(points[1][i-1].x, points[1][i-1].y, mid1.x, mid1.y);
				}
			}

			// FINISH LINE
			i--;
			this.ctx.lineTo(points[0][i].x, points[0][i].y);
			this.ctu.lineTo(points[1][i].x, points[1][i].y);

			// DRAW
			this.ctx.stroke();
			this.ctu.stroke();
		},
		clear: function() {
			// CLEAN CANVASES
			this.ctx.clearRect(0, 0, this.area.width, this.area.height);
			this.ctu.clearRect(0, 0,      this.width,      this.height);
			this.points = [];
			this.valid = false;
			if (!!this.onvalid) this.onvalid(this.valid);
		},

		// DRAWING HELPERS ___________________________
		midpoint: function(a, b)  { // Bezier midpoint
			return {
				x: a.x + (b.x - a.x) / 2,
				y: a.y + (b.y - a.y) / 2
			}
		},
		isfar: function(a, b) { // Is newpoint far enough
			return (
				(a.x < b.x - 0.003 || a.x > b.x + 0.003) ||
				(a.y < b.y - 0.003 || a.y > b.y + 0.003)
			);
		},
		recalc: function() {
			var screen = [];
			var upload = [];
			var xx, yy,
				w = this.area.width, h = this.area.height;
			for (var i=0, max = this.points.length; i<max; i++) {
				screen.push({
					x: (xx = this.points[i].x * w)
						   < w ? xx : w,
					y: (yy = this.points[i].y * h)
						   < h ? yy : h,
					end: this.points[i].end
				});
				upload.push({
					x: (xx = this.points[i].x * this.width)
						   < this.width ? xx : this.width,
					y: (yy = this.points[i].y * this.height)
						   < this.height ? yy : this.height,
					end: this.points[i].end
				});
			}
			return [screen, upload];
		}
	},

	// TOOLS - CSS =====================================================
	function hasClass(e, classname) {
		return (e.className.indexOf(classname) >= 0);
	};
	function addClass(e, classname) {
		if (e.className.indexOf(classname) < 0) e.className += ' ' + classname;
	};
	function remClass(e, classname) {
		e.className = e.className.replace(new RegExp(classname, "g"), '').trim().replace('  ', ' ');
	};
	function togClass(e, classname) {
		if (e.className.indexOf(classname) < 0) {
			e.className += ' ' + classname;
			return true;
		}
		e.className = e.className.replace(new RegExp(classname, "g"), '');
		return false;
	};
	function setClass(e, classname, state) {
		if (!state)
			remClass(e, classname);
		else
			addClass(e, classname);
	};

	// TOOLS - CSS ANIMATIONS ==========================================
	function shake(e) {
		addClass(e, 'helpshake');
		setTimeout(function () {
			remClass(this, 'helpshake');
		}.bind(e), 1000);
	}

	// TOOLS - FORMDATA ================================================

	function xhrParams(params) {
		var fdat = new FormData();
		for (var i=0, max=params.length; i<max; i++)
			fdat.append(params[i][0], params[i][1]);
		return fdat;
	};

	// INITIALIZE & DOWNLOAD ===============================================
	window.mzForm = mzForm;
	window.MzSign = MzSign;
	window.addEventListener('load', mzForm.init);

}(window, document));