PageSourceSearch

https://canadatattooshows.com/cms2t/res/vit-lib/common.js

js canadatattooshows.com collected 2026-10-09 22:41:12 UTC 87,495 bytes, 3,019 lines download raw bytes

1/**********************************************************************************\
2 * Set of common java helpers.
3 * 
4 * The MIT License
5 * 
6 * Copyright (c) 2008 Victor Denisenkov aka Mr.V!T
7 * 
8 * Permission  is hereby granted, free of charge, to any person obtaining a copy of
9 * this  software  and  associated documentation files (the "Software"), to deal in
10 * the  Software  without  restriction,  including without limitation the rights to
11 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12 * the  Software, and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 * 
15 * The  above  copyright notice and this permission notice shall be included in all
16 * copies or substantial portions of the Software.
17 * 
18 * THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20 * FOR  A  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21 * COPYRIGHT  HOLDERS  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22 * IN  AN  ACTION  OF  CONTRACT,  TORT  OR  OTHERWISE,  ARISING  FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * @package vit-lib
26 * @author Victor Denisenkov aka Mr.V!T
27 * @version 1.0
28\**********************************************************************************/
29
30/** //** ----= escapeHtmlTags	 =----------------------------------------------\**//** \
31*
32* 	Converts common HTML chars into entities.
33*
34*	@param	string	str	- HTML code to convert.
35*	@return	string		- Escaped HTML.
36*
37\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
38var escapeHtmlTags_chars = {
39	'&'	: '&',
40	'<'	: '&lt;',
41	'>'	: '&gt;',
42	'"'	: '&quot;',
43	"'"	: '&#039;'
44} //OBJECT escapeHtmlTags_chars
45function escapeHtmlTags(str) {
46	
47	//If smth wrong given, just returning it back
48	if ( typeof(str) !== 'string' ) return str;
49	
50	return str.replace(/['"&<>]/g, function (c) {
51		return escapeHtmlTags_chars[c] || c;
52	}); //FUNC string.replace.callback
53} //FUNC escapeHtmlTags
54
55function decodeEntities ($str) {
56	
57	for ( var $i in escapeHtmlTags_chars )
58		$str = $str.replace(escapeHtmlTags_chars[$i], $i);
59		
60	return $str;
61} //FUNC decodeEntities
62
63function getUrlHash () {
64	return location.hash.replace(/^#/, '');
65} //FUNC getUrlHash
66
67/** //** ----= fullURL	=----------------------------------------------------------------------------------------------\**//** \
68*
69*	Takes any URL and makes it full URL adding host if necesarry.
70* 	Uses window.location for host value and autodetected scheme.
71*
72*	@param		string	$url		- Url to check.
73* 	@param		bool	[$https]	- Create https url.
74*
75*	@return		string			- Full URL
76*
77\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
78function fullURL ($url, $https) {
79
80	// Preparing desired shceme
81	if ( isUndefined($https) )
82		$scheme = window.location.protocol+'//';
83	else
84		$scheme = ($https) ? 'https://' : 'http://' ;
85
86	// Checking for sceme on string begining
87	if ( $url.indexOf($scheme) !== 0 )
88		$url = $scheme+window.location.host+'/'+$url.ltrim(' \/');
89		
90	return $url;
91} //FUNC fullURL
92
93/** //** ----= regexMatchAll	=----------------------------------------------------------------------------------------------\**//** \
94*
95*	Executes regex on string multiple times, untill no further matches found. Returns array of matches.
96*	Supports PREG_SET_ORDER and PREG_PATTERN_ORDER similar to php's preg_match_all.
97*
98*	@param		string	$str		- String to match.
99* 	@param		regex	$regex		- Regular expression.
100*
101*	@return		array			- All matches as array.
102*
103\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
104var PREG_PATTERN_ORDER	= 1;
105var PREG_SET_ORDER	= 2;
106function regexMatchAll ($regex, $str, $order) {
107
108	// Order by default is PREG_PATTERN_ORDER to mimic php
109	$order = $order || PREG_PATTERN_ORDER;
110
111	var $match; 
112	var $res = [];
113	
114	// Looping through results
115	// This will create results as for PREG_SET_ORDER flag 
116	while ( $match = $regex.exec($str) ) {
117
118		// Removing some trash, to end up with true array
119		// It's important to allow [for var in array] code.	
120		delete($match['index']);
121		delete($match['input']);
122		
123		$res.push($match);
124	} //WHILE matching
125	
126	// Done if no need to reorder
127	if ( $order === PREG_SET_ORDER )
128		return $res;
129
130	// Reordering in new array if necessary		
131	var $tmp = [];
132	for ( var $i in $res )
133		for ( var $j in $res[$i] ) 
134			// Pushing matches if subset exists, or creating new one if not
135			$tmp[$j] ? $tmp[$j].push($res[$i][$j]) : $tmp[$j] = [$res[$i][$j]];
136	
137	return $tmp;
138} //FUNC regexMatchAll
139
140if ( isUndefined( jQuery.fn.disableSelection ) ) {
141
142jQuery.fn.disableSelection = function() {
143	// Preparing event name, to allow selectstart or fallback to mousedown
144	var $eventName = ( isUndefined(this.selectstart) ? 'mousedown' : 'selectstart' ) + '.vDisableSelection';
145
146	this.on( $eventName, function( $e ) {
147		$e.preventDefault();
148	}); //FUNC onMouseDown
149
150} //FUNC disableSelection
151
152jQuery.fn.enableSelection = function() {
153	this.off('.vDisableSelection');
154} //FUNC enableSelection
155
156} //IF no disable seleciton
157
158function isDebug () {
159	
160	if ( !isEmpty( getCookie('debug') ) )
161		return true;
162
163	if ( location.search.indexOf('debug=1') != -1 )
164		return true;
165
166	return false;	
167} //FUNC isDebug
168
169function isIframe () {
170	try {
171		return window.self !== window.top;
172	} catch (e) {
173		return true;
174	}
175} //FUNC isIframe
176
177function implode(glue, obj) {
178	
179	// Faster will be call .join if array given
180
181	if ( obj instanceof Array )
182		return obj.join(glue);
183	
184	// Or doing manually for object
185	
186	var res = '';
187	
188	for ( var i in obj ) {
189		if ( res ) res += glue;
190		res += obj[i]; 
191	} //FOR each property
192	
193	return res;
194} //FUNC implode
195
196function ucfirst ($str) {
197	return $str && $str[0].toUpperCase() + $str.slice(1);
198} //FUNC ucfirst
199
200String.prototype.capitalize = function() {
201	return ucfirst(this);
202} //FUNC capitalize
203
204if ( !String.prototype.startsWith ) {
205String.prototype.startsWith = function ($needle) {
206	return this.lastIndexOf($needle, 0) === 0;
207}} //FUNC startsWith
208
209if ( !String.prototype.endsWith ) {
210String.prototype.endsWith = function ($needle) {
211	var $lastIndex	= this.lastIndexOf($needle);
212	return ( $lastIndex != -1 ) && ( $lastIndex + $needle.length == this.length );
213}} //FUNC endsWith
214
215function strRepeat ($str, $multiplier) {
216	
217	if ( !$multiplier )
218		return '';
219		
220	var $res = '';
221	
222	for ( var $i = 0; $i < $multiplier; $i++ ) {
223		$res += $str;
224	} //FOR multiple times
225	
226	return $res;
227} //FUNC strRepeat
228
229function instanceName ($var) {
230	
231	// Determining instance using basic Object.toString()
232	$res = Object.prototype.toString.call($var);
233
234	// Cutting usual [object ...] from it to get clean instance name
235	$res = $res.slice(8, -1);
236	
237	return $res;
238} //FUNC instanceName
239var getClassOf = instanceName;
240
241function isClass ($var, $class) {
242	return getClassOf($var) === $class;
243} // FUNC isBool
244
245function isBool ($var) {
246	return typeof($var) == 'boolean';
247} // FUNC isBool
248
249function isNumber ($var) {
250	return typeof($var) == 'number';
251} //FUNC isNumber
252
253function isNumeric ($var) {
254	return $var !== '' && !isNaN($var) && isFinite($var);
255} //FUNC isNumeric
256
257function isInt ($var) {
258	return !isNaN($var) && (parseInt($var) == $var);
259} //FUNC isInt
260
261function isFloat ($var) {
262	return $var !== '' && !isNaN($var) && isFinite($var) && !isInt($var);
263} //FUNC isFloat
264
265function isArray ($var) {
266	return $var instanceof Array;
267} //FUNC isArray
268
269function isObject ($var, $orArray) {
270	
271	// If not object - then false anyway
272	if ( typeof($var) != 'object' )
273		return false;
274		
275	// If arrays allowed - we have result already	
276	if ( $orArray )
277		return true;
278
279	// Now need to check if it is array
280	// Should not be array for strict check
281	return ( !isArray($var) );
282	
283} //FUNC isArray
284
285var isString = isStr;
286function isStr ($var) {
287	return typeof($var) == 'string';
288} //FUNC isStr
289
290function isIn ($var, $values) {
291	return $values.indexOf($var) > -1;
292} //FUNC isIn
293
294// Global constant for undefined type checks
295var UNDEFINED = 'undefined';
296
297function isUndefined($var) {
298	return $var === void 0;
299} //FUNC isUndefined
300
301function isDefined($var) {
302	return !isUndefined($var);
303} //FUNC isDefined
304
305function setDefault($var, $default) {
306	return isDefined($var)? $var : $default;
307} //FUNC isDefined
308
309var isset = isSet;
310function isSet ($var) {
311	return !isUndefined($var);
312} //FUNC isSet
313
314var empty = isEmpty;
315function isEmpty ($var) {
316	
317	// Fastest way to test
318	if ( !$var )
319		return true;
320	
321	// '0' means empty too
322	if ( $var === '0' )
323		return true;
324
325	// Extra test need only for objects, so if it's not object - no need to test more
326	if ( typeof($var) !== 'object' )
327		return false;
328	
329	// Testing array first (faster test)
330	if ( isArray($var) )
331		return $var.length == 0;
332		
333	// If still here - its object and need to loop through to check properties
334	// Any existing property ($i) means it's not empty
335	for ( var $i in $var )
336		return false;
337	
338	// If not triggered above - that's empty object	
339	return true;
340} //FUNC isEmpty
341
342function asBool ($var) {
343	return !isEmpty($var);
344} //FUNC asBool
345
346function isNumber ($var) {
347	return typeof($var) == 'number';
348} //FUNC isArray
349
350function isFunction ($var) {
351	return typeof($var) == 'function';
352} //FUNC isArray
353
354function isScalar ($var, $ex) {
355	
356	// Testing common scalar types
357	if ( (/boolean|number|string/).test(typeof($var)) )
358		return true;
359
360	// Extra test assumes that NULL and undefined are scalars		
361	if ( !$ex )
362		return false;
363	
364	if ( typeof($var) == 'undefined' || $var === null )
365		return true;
366		
367	return false;
368} //FUNC isScalar
369
370function isScalarArray ($var, $ex) {
371
372	if ( !isArray($var) )
373		return false;
374
375	// If at least one array item is not scalar - that's not scalar array
376	for ( var $i = 0; $i < $var.length; $i++ )
377		if ( !isScalar($var[$i], $ex) )
378			return false;
379	
380	return true;
381} //FUNC isScalar
382
383/** //** ----= arrayPath	=--------------------------------------------------------------------------------------\**//** \
384*
385*	Traversing array using key paths. Allows to get or set values.
386*
387*	@param		array	$array		- Array to traverse.
388* 	@param		mixed	$path		- Path to navigate. Either string or array. 
389* 						 E.g.: 'key1/key2/deepvalue' or ['key1', 'key2', 'deepvalue']
390* 	@param		mixed	[$value]	- Value to set for setter mode (if omited, will return value instead)
391* 	@param		string	[$divider]	- Path divider (used only if path is given as string).	 
392*
393*	@return		mixed			- Target value in getter mode, or new value in setter.
394*
395\**//** ---------------------------------------------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
396function arrayPath ($array, $path, $value, $divider) {
397
398	$divider = $divider || '/';
399
400	// Checking for setter mode
401	var $isSetter = ( !isUndefined($value) );
402	
403	// Splitting path to individual keys
404	if ( !isArray($path) ) {
405		$path = $path.split($divider);
406	} //IF not array given
407
408	// Looping down to value in array
409	// Using refs for recurcive looping
410	// Thus saving parent for last step
411	var $var	= $array;
412	var $parent	= $array;
413	
414	for ( var $i in $path ) {
415		
416		$key = $path[$i];
417				
418		// In setter mode - need to make sure that var is array
419		// In getter mode - if var is already not array - that's null return
420		if ( !isObject($var) )
421			if ( $isSetter )
422				$var = [];
423			else
424				return;		
425		
426		// Checking for key presence
427		// In getter mode unexisting key results to NULL result
428		// In setter mode - path should be created
429		// This should be done priror next iteration to avoid source array altering
430		if ( isUndefined($var[$key]) )
431			if ( $isSetter )
432				$var[$key] = {};
433			else
434				return;
435
436		// Saving ref for next iteration
437		$parent	= $var;
438		$var	= $var[$key];
439	} //FOR each path key
440
441	// At this point ref points to end value
442	// Can set and return it
443	if ( $isSetter )
444		$parent[$key] = $value;
445	
446	return $var;
447} //FUNC arrayPath
448
449if ( !Object.keys ) {
450    Object.keys = function (obj) {
451        var keys = [],
452            k;
453            
454        for ( k in obj )
455            if ( Object.prototype.hasOwnProperty.call(obj, k) )
456                keys.push(k);
457
458        return keys;
459    }; //FUNC keys
460} //IF Object have no keys method 
461
462/** //** ----= objSize	=----------------------------------------------------------------------------------------------\**//** \
463*
464*	Returns object properties count. Usefull as analog of [].length for data objects.
465*
466*	@param		object	$obj	- Object to count.
467*
468*	@return		int		- Object "size".
469*
470\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
471function objSize ($obj) {
472	
473	var $res = 0;
474	for ( $i in $obj)	
475		if ( $obj.hasOwnProperty($i) )
476			$res++;
477	
478	return $res;
479} //FUNC objSize
480
481/** //** ----= objStep	=----------------------------------------------------------------------------------------------\**//** \
482*
483*	Returns object key in "step" away from given key.
484*
485*	@param		object	$obj	- Object to search key in
486*	@param		$key	$key	- Key to step from	
487*	@param		$step	$step	- Step to count from given key (can be negatve to count backwards)	
488*
489*	@return		string		- Found key, or FALSE if smth failed
490*
491\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
492function objStep ($obj, $key, $step) {
493
494	// Using array for indexing keys, and then searching keys in it
495	// In case smth goes wrong - FALSE is returned
496	
497	var $idx = Object.keys($obj);
498	
499	if ( $idx.length == 0 )
500		return false;
501	
502	var $i = $idx.indexOf($key);
503	
504	if ( $i < 0 )
505		return false;
506
507	// Stepping from key	
508	$i += $step;
509	
510	if ( $i < 0 || $i >= $idx.length )
511		return false;
512
513	return $idx[$i];
514} //FUNC objStep
515
516/** //** ----= objNext, objPrev	=--------------------------------------------------------------------------------------\**//** \
517*
518*	Common use cases of objStep for searching next/prev keys in object
519*
520*	@param		object	$obj	- Object to search key in
521*	@param		$key	$key	- Key to step from	
522*
523*	@return		string		- Found key, or FALSE if smth failed
524*
525\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
526function objPrev ($obj, $key) {
527	return objStep($obj, $key, -1);
528} //FUNC objPrev
529function objNext ($obj, $key) {
530	return objStep($obj, $key, 1);
531} //FUNC objNext
532
533/** //** ----= objFirst, objLast	=------------------------------------------------------------------------------\**//** \
534*
535*	Returns first/last object key.
536*
537*	@param		object	$obj	- Object to search key in
538*
539*	@return		string		- Found key, or FALSE if smth failed
540*
541\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
542function objFirst ($obj) {
543
544	var $idx = Object.keys($obj);
545	
546	if ( $idx.length == 0 )
547		return false;
548		
549	return $idx[0];
550} //FUNC objFirst
551function objLast ($obj) {
552	
553	var $idx = Object.keys($obj);
554	
555	if ( $idx.length == 0 )
556		return false;
557		
558	return $idx[$idx.length-1];
559} //FUNC objLast
560
561/** //** ----= isSame	=----------------------------------------------------------------------------------------------\**//** \
562*
563* 	Compares two objects given. Designed for data objects.
564*
565*	@param	object	x, y		- Objects to compare.
566*	@param	bool	[oneway]	- Set TRUE to test only by x values (i.e y can be bigger, in other words - if X is in Y)
567*	@param	bool	[presort]	- Set TRUE to presort incoming arrays. This may 
568*					  be necessary if comparing arrys in order 
569*					  independent way. Usefull for values lists.
570*
571\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
572function isSame (x, y, oneway, presort) {
573
574	// Fast check for nulls / empties
575	if ( !x || !y ) {
576
577		if ( !x && y ) return false;
578		if ( x && !y ) return false;
579		
580		return true;
581	} //IF some is null or empty
582
583	// IF arrays come - first better check lengths
584	if ( x instanceof Array && y instanceof Array ) { 
585
586		if ( x.length != y.length )
587			return false;
588			
589		if ( presort ) {
590			x.sort();
591			y.sort();
592		} //IF presort seet
593		
594	} //IF arrays come
595	
596	// First checking properties existance.
597	// After this check full comparasions will be done in opposite direction
598
599	if ( !oneway ) {
600		for ( var p in y ) {
601			if ( typeof(x[p]) == 'undefined') 
602				return false;
603		} //FOR each property in y
604	} //IF not one way comparasion
605
606	// Type based checking, in opposite comparasion direction 
607	for ( var p in x ) {
608
609		// Checking self properties in oppose object, jsut existance first
610		if ( typeof(y[p]) == 'undefined' ) 
611			return false;
612		
613		if ( x[p] ) { // Fast symantec check, everything that is logically FALSE - no need to check by type
614
615			switch( typeof(x[p]) ) {
616				
617				case 'object' :
618				
619					// Checking objects recursively
620					// This allows multidimensional objects checks, 
621					// But can possibly hang browser. Normally will not.
622					// ToDo: prevent possible reqursions
623					if ( !isSame(x[p], y[p], oneway, presort) ) 
624						return false;  
625	
626					break;
627
628				case 'function' :
629				
630					// Of course toString is not best way to compare functions. 
631					// But normally same named funcitons should have same source code, 
632					// and it's anyway better and faster than to full syntax parsing.
633					// Fast toString comparation will work in most typical cases.
634					// Just don't use this function if U need to compare functions in objects so much!. 
635					if ( this[p].toString() != x[p].toString() )
636						return false;
637						
638					break;
639				default:
640				
641					// At last simple check that will usually used :).
642					if ( x[p] != y[p] )
643						return false;
644				
645			} //SWITCH type of x
646
647		} else { //IF is value
648
649			// Checking same property on other object
650			if ( y[p] )
651				return false;
652				
653		} //If false value
654		
655	} //FOR each property in x
656
657	return true;
658} //FUNC isSame
659
660function isXHR2 () {
661
662	if ( !window.FormData ) 
663		return false;
664
665	// Testing for XMLHttpRequest Level 2 
666	var xhr = new XMLHttpRequest();
667	if ( !xhr.upload )
668		return false;		
669
670	return true;
671} //FUNC isXHR2
672
673function isFilesAPI () {
674	
675	if ( !isXHR2() )
676		return false;
677
678	if ( !(window.File && window.FileList && window.FileReader) ) 
679		return false;
680
681	return true;
682} //FUNC isFilesAPI
683
684function isIos () {
685	return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;	
686} //FUNC isIos
687
688/** //** ----= isTouchScreen	=--------------------------------------------------------------------------------------\**//** \
689*
690*	Tests if device is touch screen enabled device.
691* 
692* 	@return bool			- TRUE if device supports touchs screen. (i.e. pointer:coarse from css4 media queries.) 
693*
694\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
695function isTouchScreen () {
696	
697	var $res = 'ontouchstart' in document.documentElement;
698	
699	return $res;
700} //FUNC isTouchScreen
701
702/** //** ----= isJQ	=----------------------------------------------------------------------------------------------\**//** \
703*
704*	Tests if given object is jQuery element
705*
706*	@param		MIXED	$val	- Value to check.
707*
708*	@return		bool		- Check result.
709*
710\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
711function isJQ ($val) {
712	
713	// Empty value is not jQuery
714	if ( !$val )
715		return false;
716		
717	return ($val instanceof jQuery || $val.jquery);
718} //FUNC isJQ
719
720/** //** ----= _jq	=----------------------------------------------------------------------------------------------\**//** \
721*
722* 	Ensures that given parameter is valid jQuery object. Avoids jQuery object clone.
723*
724*	@param	MIXED	$element	- jQuery selector, DOM element or jQuery object.
725*	@param	MIXED	[$context]	- Valid jQuery context.
726*
727*	@return	object(jQuery)		- jQuery object.
728*
729\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
730function _jq ($element, $context) {
731
732	if ( !isJQ($element) )
733		return jQuery($element, $context);
734
735	return $element;
736} //FUNC _jq
737
738function formatFileSize (bytes) {
739
740	if ( !bytes ) return bytes;	 
741	 
742	var labels	= ['b','Kb','Mb','Gb','Tb','Pb','Eb','Zb','Yb'];
743	var ex		= Math.floor( Math.log(bytes) / Math.log(1024) );
744	
745	var res		= bytes / Math.pow(1024, ex);
746	
747	return res.toFixed(2) + ' ' + labels[ex]; 
748} //FUNC formatFileSize
749
750/** //** ----= setObjectOptions	=--------------------------------------------------------------------------------------\**//** \
751*
752*	Initiates object properties from given data object. Sets properties directly, without test if property really existed.
753*	Essentially copies one object properties into another.
754* 
755* 	@param	object	$object		- Object to apply options to.
756* 	@param	array	$options	- Options to set.
757* 
758* 	@return object			- Returns given object. 
759*
760\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
761function setObjectOptions ($object, $options) {
762	
763	$options = $options || {};
764	
765	// Looping through each option given and setting it as property
766	for ( var $opt in $options )
767		$object[$opt] = $options[$opt];
768	
769	return $object;
770} //FUNC setObjectOptions
771
772/** //** ----= borderValue	=--------------------------------------------------------------------------------------\**//** \
773*
774* 	Ensures that given value is within bounds.
775*
776*	@param	MIXED	$element	- jQuery selector, DOM element or jQuery object.
777*	@param	MIXED	[$context]	- Valid jQuery context.
778*
779*	@return	object(jQuery)		- jQuery object.
780*
781\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
782function borderValue ($value, $min, $max) {
783
784	if ( $value < $min )
785		$value = $min;
786		
787	if ( $value > $max )
788		$value = $max;
789		
790	return $value;
791} //FUNC borderValue
792
793/** //** ----= vEventObject	=--------------------------------------------------------------------------------------\**//** \
794*
795* 	Extends given object to accept events callbacks. Allows events registering and chain calling later. Callback will 
796*	run within object's context and accept parameters given to event trigger.
797*
798*	@param	array	types	- List of event types to create.
799*
800*	@param	object	obj	- Object to extend.
801*
802*	@return	object		- Modified object.
803*
804\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
805function vEventObject (types, obj) {
806
807	obj = obj || {};
808
809	// Creating callbacks storage in parent
810	if ( isEmpty(obj['__events']) )
811		obj['__events'] = {};
812	
813// ---- BIND/RUNNER ----	
814	
815	/** //** ----= _runevent	=------------------------------------------------------------------------------\**//** \
816	*
817	* 	For Internal Use. Event runner, used to call events, or set new ones (in case if callback function given).
818	*
819	* 	@param	string	type	- Event type to use.
820	* 
821	*	@return	MIXED			- Mixed return.
822	*		SELF			- If setting event.
823	*		bool			- Boolean FALSE in even return - interrupts chain, and also is returned. 
824	*					  TRUE is just returned.
825	*		VOID			- Other cases.
826	*
827	\**//** --------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
828	obj._runevent = function ( type, args ) {
829
830		// Setting callback if given as first argument
831		if ( args[0] && typeof(args[0]) == 'function' ) {
832			this.__events[type].push(args[0]);
833			return obj;
834		} //IF callback set
835		
836		var res = false;
837		
838		// If no callback given (getter mode) - running all calbacks of that type, cb should contain arguments then
839		for ( var func in this.__events[type] ) {
840			var eres = this.__events[type][func].apply(obj, args);
841
842			// False in result means even chain interruption, returning it to parent also 
843			if ( eres === false ) 
844				return false;
845			
846			// True in one of events means smth for caller, we'll return it later
847			if ( eres === true ) 
848				res = true;
849			
850		} //FOR each callback
851
852		// If someone return true - we notify parent about, else - undefined return
853		if ( res ) 
854			return res;
855
856	} //FUNC _runevent
857
858// ---- UNBIND ----
859
860	/** //** ----= unbind	=--------------------------------------------------------------------------------------\**//** \
861	*
862	* 	Event remover. Unbings given event type, or given callback if specified. If no parameters specified - 
863	*	unbinding all events (usefull to get clean object).
864	*
865	* 	@param	string		[type]	- Event type to unbind.
866	*	@param	function	[fn]	- Callback to unbind within type.
867	* 
868	*	@return	SELF
869	*
870	\**//** --------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
871	obj.unbind = function (type, fn) {
872		
873		var $this = this;
874		
875		// Event clearing helper
876		function unbindEvent (e) {
877			
878			// Deleting only speciefic events, skipping body ones
879			for ( var i = 0; i < e.length; i++ ) {
880			
881				// Skipping body ones
882				if ( e[i]._bodyeventfunction ) continue;
883				
884				// Skipping all non given (if some given)
885				if ( fn && e[i] !== fn ) continue;
886				
887				e.splice(i, 1);
888				
889			} //FOR each callback
890			
891		}; //FUNC unbindEvent
892	
893		// If type specified - cleaning only that type, otherwise - all of them
894		if ( type )
895			unbindEvent(this.__events[type]);
896		else
897			for ( var i in this.__events )
898				unbindEvent(this.__events[i]);
899
900		return obj;
901		
902	}; //FUNC obj.unbind
903
904// ---- SHORTCUTS ----	
905
906	// Creating shortcut for each event
907	for ( var ev in types ) {
908
909		var type = types[ev];
910		
911		// For each type we have own array with callbacks
912		if ( isEmpty(obj.__events[type]) )
913			obj.__events[type] = [];
914		
915		// Existing event functions became first events
916		if ( isFunction(obj[type]) ) {
917			
918			// Skipping event functions
919			if ( obj[type]._runeventfunction )
920				continue;
921			else {
922				// Marking as body function - those can't be unbind
923				obj[type]._bodyeventfunction = 1;
924				obj._runevent(type, [obj[type]]);
925			} //IF own function
926			
927		} //IF function already exists in body 
928		
929		// Creating event trigger function in parent for each type
930		obj[type] = function (t) { return function () { return this._runevent(t, arguments);};}(type);
931
932		// Marking as event function to recognise later 
933		obj[type]._runeventfunction = 1;
934		
935	} //FOR each type
936	
937	return obj;
938} //FUNC vEventObject
939
940/** //** ----= reloadCSS		 =--------------------------------------\**//** \
941*
942* 	Forces browser to reload CSS sheets dynamically.
943*	
944*	@param	string	url	- CSS sheet URL.
945*
946\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
947function reloadCSS (url) {
948	
949	var salt	= randomString();
950	var salt_url	= url + '?reload=' + salt;
951	
952	var new_sheet = jQuery('<link rel="stylesheet" href="' + salt_url + '" type="text/css" />');
953	var old_sheet = jQuery('LINK[href*="' + url + '"]');
954
955	if ( document.createStyleSheet ) {
956		document.createStyleSheet(salt_url);
957	} else { //IF IE 
958		jQuery('HEAD').append( new_sheet );
959	} //IF normal browsers	
960
961	// Removing old sheet if present.
962	setTimeout( function () { old_sheet.remove(); }, 1000);
963	
964} //FUNC reloadCSS
965
966/** //** ----= countElements	 =----------------------------------------------\**//** \
967*
968* 	Returns overal page's elements count. Usefull for optimization.
969*
970*	@param	jQuery	el	- Count elements within give element. 
971*
972*	@return int		- Elements count.	
973*
974\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
975function countElements (el) {
976	
977	if ( !el )
978		return document.getElementsByTagName('*').length;
979		
980	return jQuery(el).find('*').length;
981} //FUNC countElements
982
983function randomString(type, length) {
984	
985	if ( !type ) type = 'alnum';
986	if ( !length ) length = 8;
987	
988	var chars = '';
989	
990	switch ( type.toLowerCase() ) {
991		case 'alnum'	: chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
992			break;
993		case 'alpha'	: chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
994			break;
995		case 'hex'	: chars = '0123456789ABCDEF';
996			break;
997		case 'caps'	: chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
998			break;
999		case 'capnum'	: chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
1000			break;
1001		case 'numeric'	: chars = '0123456789';
1002			break;
1003		case 'nozero'	: chars = '123456789';
1004			break;
1005		case 'keyb'	: chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ :;,.\'"\|/?[]{}()<>~`!@#$%^&*-=_+';
1006			break;
1007			
1008		default		: chars = type;
1009	} //SWITCH $type
1010
1011	if ( !chars ) return '';
1012	
1013	var str = '';
1014	
1015	for (var i = 0; i < length; i++) {
1016		var rnum = Math.floor(Math.random() * chars.length);
1017		str += chars.substring(rnum, rnum + 1);
1018	}
1019	
1020	return str;
1021} //FUNC randomString
1022
1023/** //** ----= newSN	 =---------------------------------------------------------------------------------------------\**//** \
1024*
1025*	Generates new random SN. SN is usually capnum unique string of 16 chars, starting from give char.
1026*
1027*	@param		string	[$prefix]	- Limit SN to start only with this char.
1028*	@param		string	[$length]	- SN length, 16 by default.
1029* 
1030*	@return		string			- Random SN string.
1031*
1032\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
1033function newSN ($prefix, $length) {
1034	
1035	$prefix = $prefix || '';
1036	$length	= $length || 16;
1037	
1038	return ($prefix + randomString('capnum', $length)).substring(0, $length);
1039} //FUNC newSN
1040
1041/** //** ----= fileName		 =----------------------------------------------\**//** \
1042*
1043* 	Extracts file name from full path.
1044* 	
1045* 	@param	string	path	- Full path and file name.
1046*	@return	string		- File name.
1047*
1048\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
1049function fileName (path) {
1050	if ( !path ) return '';
1051	return path.replace(/^.*\\/, '');
1052} //FUNC fileName
1053
1054/** //** ----= fileExt		 =----------------------------------------------\**//** \
1055*
1056* 	Extracts file extension from file name.
1057* 	
1058* 	@param	string	file	- Full path and file name.
1059*	@return	string		- File name.
1060*
1061\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
1062function fileExt (file) {
1063	var tmp	= file.lastIndexOf('.');
1064	
1065	if ( !tmp ) return false;
1066	
1067	return file.substr(tmp+1, file.length); 
1068} //FUNC fileExt
1069
1070/*--------------------------------------------------------------------------------*\
1071|	Humanize
1072|----------------------------------------------------------------------------------
1073| Ensures that number will be displayed as normal value (fix for JavaScript numbers)
1074| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1075|	Params:
1076|		[base]	int	- Base value to round value to.
1077|	Return:
1078|			string	- Human looking number rounded to certain base.
1079\*--------------------------------------------------------------= by Mr.V!T =-----*/
1080Number.prototype.Humanize = Number.prototype.humanize = function (base) {
1081	
1082	base = base || 10;
1083	
1084	var tmp = this.toFixed(base) + '';
1085	return tmp;
1086	
1087	var res = tmp.rtrim('0.');
1088	if ( res == '' ) res = '0';
1089	
1090	return res;
1091} //FUNC Humanize
1092
1093/*--------------------------------------------------------------------------------*\
1094|	indexOf
1095|----------------------------------------------------------------------------------
1096| Fixes indexOf for IE6.
1097| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1098|	Params:
1099|		obj		MIXED	- Item to search.
1100|		fromIndex	integer	- Search starting from index.
1101|	Return:
1102|				integer	- Item position in array, or -1 if not found.
1103\*--------------------------------------------------------------= by Mr.V!T =-----*/
1104/**/
1105if ( !Array.prototype.indexOf )
1106Array.prototype.indexOf = function (obj, fromIndex) {
1107		
1108	if ( !fromIndex ) fromIndex = 0;
1109	
1110	for ( var i in this )
1111		if ( this[i] === obj ) return i;
1112		
1113	return -1;
1114} //FUNC indexOf
1115/**/
1116
1117/*--------------------------------------------------------------------------------*\
1118|	arrayJoin
1119|----------------------------------------------------------------------------------
1120| Extended join for arrays.
1121| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1122|	Params:
1123|		array		array	- Array to process.
1124|		separator	string	- String to use as separator.
1125|		include_keys	bool	- Set TRUE to encode keys in result string.
1126|	Return:
1127|				string	- Array as string.
1128\*--------------------------------------------------------------= by Mr.V!T =-----*/
1129function arrayJoin (array, separator, include_keys) {
1130	
1131	if ( !separator ) separator = ',';
1132	
1133	var res = '';
1134	
1135	var j = 0;
1136	
1137	for ( var i in array ) {
1138		
1139		if ( typeof(array[i]) == 'function' ) continue;
1140		
1141		if ( res ) res += separator;
1142		
1143		if ( include_keys ) {
1144			
1145			if ( i != j ) 
1146				res += i + ' = ';
1147			
1148		} //IF need to include keys
1149		
1150		res += array[i];
1151		j++;	
1152		
1153	} //FOR each item
1154		
1155	return res;
1156} //FUNC arrayJoin
1157
1158/*--------------------------------------------------------------------------------*\
1159|	arraySplit
1160|----------------------------------------------------------------------------------
1161| Splits array. Extended version with keys support.
1162| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1163|	Params:
1164|		string		string	- String to process.
1165|		separator	string	- String to use as separator.
1166|		auto_tirm	string	- Allow to trim values on split.
1167|	Return:
1168|				array	- Array with values.
1169\*--------------------------------------------------------------= by Mr.V!T =-----*/
1170function arraySplit (string, separator, auto_tirm) {
1171	
1172	var res	= [];
1173	var tmp = string.split(separator);
1174	
1175	for ( var i in tmp ) {
1176		
1177		var pos = tmp[i].indexOf('=');
1178
1179		if ( pos != -1 ) {
1180			
1181			var key = tmp[i].substr(0, pos);
1182			if ( auto_tirm ) key = key.trim();
1183			
1184			var val = tmp[i].substr(pos+1);
1185			if ( auto_tirm ) val = val.trim();
1186			
1187			res[key] = val;
1188			
1189		} else { //IF eq symbol found
1190		
1191			if ( auto_tirm ) tmp[i] = tmp[i].trim();
1192			res.push(tmp[i]);
1193			
1194		} //IF single value
1195		
1196	} //FOR each value
1197	
1198	return res;
1199} //FUNC arraySplit
1200
1201String.prototype.limit = function(l, append) {
1202
1203	if ( this.length <= l ) 
1204		return this.toString();
1205	
1206	append = append || '&hellip;';
1207	al = append.substr(0, 1) == '&' ? 1 : append.length;
1208	
1209	return this.substr(0, l - al) + append;
1210} //FUNC limit
1211
1212String.prototype.ucfirst = function() {
1213
1214	// Nothing to do with empty string	
1215	if ( !this.length ) return this;
1216	
1217	return this.charAt(0).toUpperCase() + this.substr(1);
1218} //FUNC ucfirst
1219
1220/*--------------------------------------------------------------------------------*\
1221|	escape
1222|----------------------------------------------------------------------------------
1223| Escapes string for using in REGex.
1224| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1225|	Params:
1226|		NONE
1227|	Return:
1228|		NULL
1229\*--------------------------------------------------------------= by Mr.V!T =-----*/
1230String.prototype.escape = function() {
1231	return this.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!<>\|\:])/g, '\\$1');
1232} //FUNC escape
1233
1234/*--------------------------------------------------------------------------------*\
1235|	_trim
1236|----------------------------------------------------------------------------------
1237| Base function for trimming strings.
1238| ***TNX*** Ideas taken from phpjs.org
1239| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1240|	Params:
1241|		[charlist]	string	- Optional characteres to trim.
1242|		[left]		bool	- Trim left.
1243|		[right]		bool	- Trim right.
1244|	Return:
1245|				string	- Trimmed string.
1246\*--------------------------------------------------------------= by Mr.V!T =-----*/
1247String.prototype._trim = function(charlist, left, right) {
1248
1249	var str = this;
1250	
1251	if ( !str )
1252		return this;
1253	
1254	charlist = (charlist) ? charlist.escape() : ' \\n\\t\\s\u00A0';
1255	
1256	if ( left ) str	= str.replace(new RegExp('^[' + charlist + ']+', 'gm'), '');
1257	if ( right ) str = str.replace(new RegExp('[' + charlist + ']+$', 'gm'), '');
1258	
1259	return str;
1260} //FUNC _trim
1261
1262/*--------------------------------------------------------------------------------*\
1263|	ltrim
1264|----------------------------------------------------------------------------------
1265| Strips whitespace from the beginning of a string.
1266| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1267|	Params:
1268|		[charlist]	string	- Optional characteres to trim.
1269|	Return:
1270|				string	- Trimmed string.
1271\*--------------------------------------------------------------= by Mr.V!T =-----*/
1272String.prototype.ltrim = function(charlist) {
1273	return this._trim(charlist, 1, 0);
1274} //FUNC ltrim
1275
1276/*--------------------------------------------------------------------------------*\
1277|	rtrim
1278|----------------------------------------------------------------------------------
1279| Removes trailing whitespace.
1280| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1281|	Params:
1282|		[charlist]	string	- Optional characteres to trim.
1283|	Return:
1284|				string	- Trimmed string.
1285\*--------------------------------------------------------------= by Mr.V!T =-----*/
1286String.prototype.rtrim = function(charlist) {
1287	return this._trim(charlist, 0, 1);
1288} //FUNC rtrim
1289
1290/*--------------------------------------------------------------------------------*\
1291|	trim
1292|----------------------------------------------------------------------------------
1293| Removes whitespaces from both sides.
1294| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1295|	Params:
1296|		[charlist]	string	- Optional characteres to trim.
1297|	Return:
1298|				string	- Trimmed string.
1299\*--------------------------------------------------------------= by Mr.V!T =-----*/
1300String.prototype.trim = function(charlist) {
1301	return this._trim(charlist, 1, 1);
1302} //FUNC trim
1303
1304/*--------------------------------------------------------------------------------*\
1305|	xtrim
1306|----------------------------------------------------------------------------------
1307| Very fast function for trimming strings.
1308| ***TNX*** Big thanx for Steve at steves_list (at) hotmail.com. 
1309| ***TNX*** http://blog.stevenlevithan.com/
1310| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1311|	Params:
1312|		NONE
1313|	Return:
1314|		NULL
1315\*--------------------------------------------------------------= by Mr.V!T =-----*/
1316String.prototype.xtrim = function() {
1317	var str = this;
1318	str = str.replace(/^\s+/, '');
1319	for (var i = str.length - 1; i >= 0; i--) {
1320		if (/\S/.test(str.charAt(i))) {
1321			str = str.substring(0, i + 1);
1322			break;
1323		}
1324	}
1325	return str;
1326} //FUNC xtrim
1327
1328/*--------------------------------------------------------------------------------*\
1329|	multiClean
1330|----------------------------------------------------------------------------------
1331| Cleans double repeated characters. E.g. doublespaces.
1332| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1333|	Params:
1334|		[character]	string	- Optional character to clean. 
1335|	Return:
1336|				string	- Result string.
1337\*--------------------------------------------------------------= by Mr.V!T =-----*/
1338String.prototype.multiClean = function(character) {
1339	
1340	character = character || ' '; 
1341	
1342	return this.replace(new RegExp('[' + character.escape() + ']{2,}', 'g'), character);	
1343} //FUNC multiClean
1344
1345/*--------------------------------------------------------------------------------*\
1346|	toSafe
1347|----------------------------------------------------------------------------------
1348| Generates safe value from give string. I.E. safe to use as variable names.
1349| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1350|	Params:
1351|		[separator]	string	- Optional characteres to use as word 
1352|					separator.
1353|	Return:
1354|				string	- Result string.
1355\*--------------------------------------------------------------= by Mr.V!T =-----*/
1356String.prototype.toSafe = function(separator) {
1357
1358	if ( !separator )
1359		separator = '_'; 
1360	
1361	var res = this;
1362	res = res.replace(/[^a-zA-Z0-9_]/g, separator);
1363	res = res.multiClean(separator);
1364	res = res.trim(separator);
1365	
1366	return res;
1367} //FUNC toSafe
1368
1369/*--------------------------------------------------------------------------------*\
1370|	compilePath
1371|----------------------------------------------------------------------------------
1372| Compile path from several pieces using '/' as glue.
1373| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1374|	Params:
1375|		*	string	- One or several path pieces.
1376|	Return:
1377|			string	- Valid path.
1378\*--------------------------------------------------------------= by Mr.V!T =-----*/
1379function compilePath () {
1380	
1381	var len = arguments.length;
1382	if ( len == 1 ) return arguments[0];
1383	
1384	var res = (arguments[0]+'').rtrim('/');
1385	
1386	for (var i = 1; i < len; i++ ) {
1387		res += '/' + (arguments[i]+'').ltrim('/');
1388	} //FOR each argument
1389	
1390	return res;
1391} //FUNC compilePath
1392var compileUrl = compilePath;
1393
1394/** //** ----= arraySelectKey	 =----------------------------------------------\**//** \
1395*
1396*	Chooses existing key from list given in associated array.
1397*
1398*	@param	array	array	- Source array.
1399* 
1400* 	@param	MIXED	keys	
1401* 		array		- Array with possible keys. 
1402* 		string		- Single key for case insensitive search or regEx 
1403* 				  mask for possible keys (slower).
1404*
1405*	@param	bool	[regex]	- Search mode for string key.
1406*
1407*	@return	MIXED			
1408* 		string		- Existing key.
1409* 		bool		- FALSE if none exists.
1410*
1411\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
1412function arraySelectKey (array, keys, regex) {
1413
1414	if ( typeof(keys) == 'object' ) {
1415
1416		for ( var i = 0; i < keys.length; i++ ) {
1417
1418			if ( array[keys[i]] != undefined ) return keys[i];
1419
1420		} //FOR each key
1421
1422	} else { //IF searching by array
1423
1424		var reg	= keys;
1425		if ( !regex )
1426			reg = new RegExp('^' + keys.escape() + '$', 'i');
1427
1428		for ( var key in array ) {
1429			
1430		//	__(key);
1431			
1432			if ( reg.test(key) ) return key;
1433		} //FOR each
1434
1435	} //IF searshing by regex
1436
1437	return undefined;
1438} //FUNC arraySelectKey
1439
1440/** //** ----= arraySelectValue	 =----------------------------------------------\**//** \
1441*
1442*	Chooses value by one of existing keys given.
1443*
1444*	@param	array	array		- Source array.
1445*	@param	array	keys		- Array with possible keys.
1446*	@param	MIXED	[default]	- Default value to use if nothing found.
1447*
1448*	@return	MIXED			- Found value or default if none found.
1449*
1450\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
1451function arraySelectValue (array, keys, def) {
1452
1453	var key = arraySelectKey(array, keys);
1454
1455	if ( !key || !array[key] == undefined ) return def;
1456
1457	return array[key];
1458} //FUNC arraySelectValue
1459
1460/*--------------------------------------------------------------------------------*\
1461|	arrayToPost
1462|----------------------------------------------------------------------------------
1463| Prepares multidimentional array to post in native PHP format.
1464| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1465|	Params:
1466|		array	object	- Common JavaScript array object.
1467|	Return:
1468|			array	- Array in POST format.
1469\*--------------------------------------------------------------= by Mr.V!T =-----*/
1470function arrayToPost (array, prefix) {
1471	
1472	var res = {};
1473	
1474	for ( i in array ) {
1475		
1476		var key = ( prefix )? prefix + '[' + i + ']' : i;
1477		
1478		if ( typeof(array[i]) == 'object' ) {
1479
1480			var sub = arrayToPost(array[i], key);
1481			
1482			for ( j in sub ) res[j] = sub[j];
1483			
1484		} else { //IF sub array
1485			res[key] = array[i];
1486		} //IF other type
1487		
1488	} //FOR each array
1489	
1490	return res;
1491} //FUNC arrayToPost
1492
1493/** //** ----= submitUrl	=--------------------------------------------------------------------------------------\**//** \
1494*
1495*	Submits given data as POST/GET to given url. Literally simulates form submit.
1496*
1497*	@param		string	$url		- Url to submit to.
1498*	@param		object	$data		- Data to submit.
1499*	@param		string	[$blank]	- Set TRUE to open in new tab.
1500*
1501*	@return		bool			- Always FALSE.
1502*
1503\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
1504function submitUrl($url, $data, $blank) {
1505	
1506	$method	= 'post';	// No real need to have method optional
1507	$data	= $data || {};
1508	$target	= '';
1509	 
1510	if ( $blank )
1511		$target = ' target="_blank"';
1512	
1513	// Generating form html as string and appending it to body
1514	// Each data will be hidden input in form
1515	var $f = '<form method="' + $method + '" action="' + $url + '"' + $target + ' style="display:none">';
1516	
1517	for ( $i in $data ) {
1518		
1519		$f += '<input type="hidden" name="' + $i + '" value="' + $data[$i] + '" />';
1520		
1521	} //FOR each data
1522	
1523	$f += '</form>';
1524	
1525	// Appending form, getting it's element, and submiting
1526	var $el = jQuery($f).appendTo('BODY').submit();
1527
1528	return false;	
1529} //FUNC submitUrl
1530
1531/** //** ----= parseVariables	=--------------------------------------------------------------------------------------\**//** \
1532*
1533*	Parses {varables} in a template. Supporting complex vairables like {var-sub} and {var.sub}
1534*
1535*	@param		string	$str		- Template to parse.
1536*	@param		object	$vars		- Data object with variable to parse.
1537*	@param		bool	[$clean]	- Set TRUE to cleanup unused variables from template (default behavior).
1538*	@param		string	[$wrap]		- Brackets pair to use on vairables. '{}' by default. Use '[]' for bb codes. 
1539*
1540*	@return		string			- Parsed template.
1541*
1542\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
1543function parseVariables ($str, $vars, $clean, $wrap) {
1544	
1545	// Using {vars} by default
1546	$wrap = $wrap || '{}';
1547	
1548	// Nothing to do if string is empty
1549	if ( !$str )
1550		return $str;
1551		
1552	if ( isUndefined($clean) ) 
1553		$clean = true;
1554	
1555	// Preparing wrap pairs
1556	// Assuming 2 char pair like '{}' or '[]'
1557	if ( $wrap.length != 2 )
1558		throw('Invalid var wrapper');
1559	
1560	// Preparing 2 wrap variants: normal and escaped one
1561	// Oftenly strings end up as url escaped strings, escaped by parsers
1562	// Thus just searching this too
1563	var $l  = $wrap.charAt(0);
1564	var $r  = $wrap.charAt(1);
1565	var $xl = '%' + $wrap.charCodeAt(0).toString(16).toUpperCase();
1566	var $xr = '%' + $wrap.charCodeAt(1).toString(16).toUpperCase();
1567	
1568	// Looping though all vars and replacing given variables	
1569	for ( var $i in $vars ) {
1570
1571		// Skipping anything that can't be placed on template
1572		if ( !isStr($vars[$i]) && !isNumber($vars[$i]) )
1573			continue;
1574		
1575		// Searching both vars variants
1576		$str = $str.replace( new RegExp( ($l + $i + $r).escape(), 'ig'), $vars[$i]);
1577		$str = $str.replace( new RegExp( ($xl + $i + $xr).escape(), 'ig'), $vars[$i]);
1578		
1579	} //FOR each var
1580
1581	if ( $clean ) {
1582
1583		// Now cleaning unused, both normal and escaped
1584		$str = $str.replace( new RegExp( $l.escape() + '[\\w\\.-]+' + $r.escape(), 'ig'), '');
1585		$str = $str.replace( new RegExp( $xl.escape() + '[\\w\\.-]+' + $xr.escape(), 'ig'), '');
1586
1587	} //IF autoClean
1588	
1589	return $str;	
1590} //FUNC parseVariables
1591
1592/** //** ----= arrayToTemplate	=--------------------------------------------------------------------------------------\**//** \
1593*
1594*	Parses {varables} in a template. PHP counterpart alias to parseVariables.
1595*
1596*	@param		object	$vars		- Data object with variable to parse.
1597*	@param		string	$str		- Template to parse.
1598*	@param		bool	[$clean]	- Set TRUE to cleanup unused variables from template (default behavior).
1599*	@param		string	[$wrap]		- Brackets pair to use on vairables. '{}' by default. Use '[]' for bb codes. 
1600*
1601*	@return		string			- Parsed template.
1602*
1603\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
1604function arrayToTemplate ($vars, $str, $clean, $wrap) { return parseVariables($str, $vars, $clean, $wrap); }
1605
1606
1607/*--------------------------------------------------------------------------------*\
1608|	isNumeric
1609|----------------------------------------------------------------------------------
1610| Simple function for checking if given string numnber.
1611| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1612|	Params:
1613|		value	string	- Value to check.
1614|	Return:
1615|			bool	- Check status.
1616\*--------------------------------------------------------------= by Mr.V!T =-----*/
1617function isNumeric (value) {
1618	
1619	// Numerics are numeric o_O
1620	if ( typeof(value) == 'number' )
1621		return true;
1622	
1623	return (value - 0) == value && value.length > 0;
1624} //FUNC isNumeric
1625
1626/*--------------------------------------------------------------------------------*\
1627|	isEmail
1628|----------------------------------------------------------------------------------
1629| Simple function for checking if given string is correct mail.
1630| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1631|	Params:
1632|		value	string	- Value to check.
1633|	Return:
1634|			bool	- Check status.
1635\*--------------------------------------------------------------= by Mr.V!T =-----*/
1636function isEmail (value) {
1637	var filter = /^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9_\-]+\.)+[a-z]{2,6}$/i;
1638	return filter.test(value);
1639} //FUNC isEmail
1640
1641jQuery.fn.findExclude = function($selector, $exclude, $res){
1642	
1643	$res = $res || new jQuery(); 
1644
1645	// Looping through children, saving matching ones,
1646	// and recursively traversing deeper in each
1647	// Skipping ones that match exclusions ofc
1648	this.children().each( function() {
1649		
1650		var $el = jQuery(this);
1651		
1652		// Checking self to be saved in result
1653		if ( $el.is($selector) ) 
1654			$res.push(this);
1655		
1656		// Traversing deeper if allowed
1657		if( !$el.is($exclude) )
1658			$el.findExclude($selector, $exclude, $res);
1659	}); //jQuery each children
1660	
1661	return $res;
1662} //FUNC findExclude
1663
1664/** //** ----= jQuery.align	 =-----------------------------------------\**//** \
1665*
1666* 	Aligns selected element with another element or browser window.
1667*
1668*	@param	string	align	- Align type.
1669*	@param	object	target	- Element to align with.
1670*	@param	bool	fit	- Set TRUE to fit inside element (forced if no target)
1671*
1672*	@return	jQuery		- Aligned element.
1673*
1674\*--------------------------------------------------------------= by Mr.V!T =-----*/
1675jQuery.fn.align = function (align, target, fit, fixed) {
1676
1677// ---- Preparing environment
1678
1679	// Default align is center
1680	if ( align == 'center' ) align = false;
1681	align = align || 'center-center';
1682	
1683	align = align.split('-');
1684	
1685	if ( fit === undefined ) fit = false;
1686		
1687	if ( !target ) fit = true;
1688
1689	// If no target - we will use screen dimensions
1690	if ( !target ) 
1691		var screen = screenSize();
1692		
1693	// Target element dimensions
1694	var tDim = {
1695		width		: ( target )? target.outerWidth() : screen.width,
1696		height		: ( target )? target.outerHeight() : screen.height
1697	}; //OBJECT elDim
1698
1699// ---- Little complicated logic goes next, no comments there - hard to explain :)
1700
1701	var bases = {
1702		'left'		: 0,
1703		'top'		: 0,
1704		'center'	: 0.5,
1705		'right'		: 1,
1706		'bottom'	: 1
1707	} //OBJ bases
1708
1709	var ly = false;
1710
1711	if ( align[0] == 'center' )
1712		align = align.reverse();
1713
1714	if ( ['left', 'right'].indexOf(align[1]) !== -1 ) {
1715		ly = true;
1716		align = align.reverse();
1717	} //IF 
1718	
1719	if ( ['top', 'bottom'].indexOf(align[0]) !== -1 ) {
1720		ly = true;
1721		align = align.reverse();
1722	} //IF
1723	
1724	// Sub function to process aligment separately for each dimension
1725	// Using sub func to avoid copy/paste
1726	function _alignDim (t, l, s, e) {
1727		
1728		if ( fit ) l = false;
1729
1730		var d = ds = bases[t];
1731		
1732		if ( l && ds != 0.5 )
1733			ds = ( ds )? 0 : 1;
1734
1735		return e * d - s * ds;			 
1736		
1737	} //FUNC _alignDim
1738
1739// ---- Result CSS ----
1740
1741	// preCompiling css 	
1742	var css = {
1743		'left'	: _alignDim( align[0], !ly, this.outerWidth(true), tDim.width ),
1744		'top'	: _alignDim( align[1], ly, this.outerHeight(true), tDim.height ) 
1745	} //OBJECT css
1746
1747	// Correcting position, relating to target
1748	if ( target ) {
1749		var pos = (fixed) ? target.offset() : target.position();
1750	
1751		css.left += pos.left;
1752		css.top += pos.top;
1753	} //IF target set
1754	
1755	this.css(css);
1756
1757	return this;
1758} //FUNC align
1759
1760/*--------------------------------------------------------------------------------*\
1761|	centerWindow
1762|----------------------------------------------------------------------------------
1763| Adds function to jQuery for centering windows
1764| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1765|	Params:
1766|		NONE
1767|	Return:
1768|		SELF
1769\*--------------------------------------------------------------= by Mr.V!T =-----*/
1770jQuery.fn.centerWindow = function () {
1771
1772	var wnd_width	= this.width();
1773	var wnd_height	= this.height();
1774	
1775	var screen	= screenSize();
1776
1777	var wnd_left	= ( screen.width - wnd_width ) / 2;
1778	var wnd_top	= ( screen.height - wnd_height ) / 2;
1779
1780	var css		= {'top' : wnd_top, 'left' : wnd_left};
1781	
1782	this.css(css);
1783	
1784	return this;
1785} //FUNC centerWindow
1786
1787jQuery.fn.maxWidth = function ($outer, $margins) {
1788	var $max = 0;
1789	this.each( function() {
1790		$max = Math.max($max, $outer ? jQuery(this).outerWidth($margins) : jQuery(this).width() );
1791	}); //FUNC each in result    
1792	return $max;  	
1793} //FUNC maxWidth
1794
1795jQuery.fn.maxHeight = function ($outer, $margins) {
1796	var $max = 0;
1797	this.each( function() {
1798		$max = Math.max($max, $outer ? jQuery(this).outerHeight($margins) : jQuery(this).height() );
1799	}); //FUNC each in result    
1800	return $max;  	
1801} //FUNC maxHeight
1802
1803jQuery.fn.screenOffset = function () {
1804	
1805	var $pos = this.offset();
1806	
1807//	var $top = jQuery('html, body').scrollTop();
1808	var $top = jQuery(window).scrollTop();
1809	
1810	$pos.top -= $top;
1811	
1812	return $pos;   
1813} //FUNC screenOffset
1814
1815jQuery.fn.wrapAround = function ($target) {
1816
1817	// Wrapping assumes border and padding to be same around, so checking only top ones	
1818	var $border	= parseInt( this.css('border-top-width') );
1819	var $padding	= parseInt( this.css('padding-top') );
1820
1821	// Supporting direct coordinates input as 4 items array: [left, top, width, height]
1822	if ( isArray($target) ) {
1823
1824		// In array mode coords are given directly
1825		var $css = {
1826			'left'	: $target[0] - $border - $padding,	
1827			'top'	: $target[1] - $border - $padding,
1828			'width'	: $target[2],
1829			'height': $target[3]
1830		}; //OBJECT $css
1831		
1832	} else { //If dimensions given
1833
1834		if ( !$target.length )
1835			return this;
1836
1837		// Initial values, huge top/left and small width/height	
1838		var $x = 10000;
1839		var $y = 10000;
1840		
1841		var $toX = 0;
1842		var $toY = 0;
1843		
1844		// Looking through all elmements and searching for ourter max dimensions
1845		$target.each( function () {
1846			
1847			var $el = jQuery(this);
1848			
1849			// Not counting invisible elements
1850			if ( !$el.is(':visible') )
1851				return;
1852			
1853			// Getting offset and calculating tox/toy for element
1854			// Then comparing this to found ones already
1855			var $o	= $el.screenOffset();
1856	
1857			var $tx = $o.left	+ $el.outerWidth();
1858			var $ty = $o.top	+ $el.outerHeight();
1859			
1860			if ( $o.left < $x ) $x = $o.left;
1861			if ( $o.top < $y ) $y = $o.top;
1862			if ( $toX < $tx ) $toX = $tx;
1863			if ( $toY < $ty ) $toY = $ty;
1864			
1865		}); //FUNC jQuery.each
1866
1867		// Now we can build helper box
1868		var $css = {
1869			'left'	: $x - $border - $padding,	
1870			'top'	: $y - $border - $padding,
1871			'width'	: $toX - $x,
1872			'height': $toY - $y
1873		}; //OBJECT $css
1874
1875	} //IF jQuery
1876	
1877	// And apply it to self
1878	this.css($css);
1879	
1880	// Continuing chain
1881	return this;
1882} //FUNC wrapAround
1883
1884jQuery.fn.hoverClass = function ($class, $allSet) {
1885	
1886	var $this = this;
1887	
1888	// Binding with namespaces, using class as namespace
1889	var $ns		= $class.replace(/\W+/g, '');
1890	var $enter	= 'mouseenter.hoverClass.' + $ns;
1891	var $leave	= 'mouseleave.hoverClass.' + $ns;
1892
1893	this.off($enter);
1894	this.off($leave);
1895
1896	// Adding class on enter to whole set, or only one hoverred
1897	this.on($enter, function ($e) {
1898		if ( $allSet )
1899			$this.addClass($class);
1900		else
1901			jQuery(this).addClass($class);
1902	}); //FUNC onMouseenter
1903	
1904	this.on($leave, function ($e) {
1905		if ( $allSet )
1906			$this.removeClass($class);
1907		else
1908			jQuery(this).removeClass($class);
1909	}); //FUNC onMouseenter
1910
1911	return this;
1912} //FUNC hoverClass
1913
1914jQuery.fn.groupBy = function ($attribute) {
1915	
1916	// Defaulting to data-group attribute.
1917	$attribute = $attribute || 'data-group'; 
1918	
1919	var $res = {}; // Will store groups here
1920	
1921	// Looping through each element, and storing as groups
1922	this.each( function () {
1923		
1924		var $el = jQuery(this);
1925		
1926		// Getting groups attribute
1927		var $attr = $el.attr($attribute);
1928		
1929		// Nothing to do if no attribute set (ungrouped element)
1930		if ( !$attr )
1931			return;
1932		
1933		// Parsing into groups, allowing common delimiters
1934		var $groups = strToArray($attr, ',.|');
1935
1936		// Assigning element into each group, adding into existing, or creating new ones
1937		for ( var $i in $groups ) {
1938			var $group = $groups[$i];
1939			
1940			if ( !$res[$group] )
1941				$res[$group] = $el;
1942			else
1943				$res[$group] = $res[$group].add($el); 
1944			
1945		} //FOR each group
1946		
1947	}); //FUNC each.result
1948	
1949	// Returning results
1950	return $res;
1951} //FUNC groupBy
1952
1953function centerWindow (el) {
1954	jQuery(el).centerWindow();
1955} //FUNC centerWindow
1956
1957/*--------------------------------------------------------------------------------*\
1958|	jqmShowCSS
1959|----------------------------------------------------------------------------------
1960| Apllies given css to jQM window and shows it.
1961| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1962|	Params:
1963|		selector	string	- Window to show.
1964|		css		string	- Object with css to apply.
1965|		effect		string	- Effect to use on displaying.
1966|	Return:
1967|				bool	- Alwyas false.
1968\*--------------------------------------------------------------= by Mr.V!T =-----*/
1969function jqmShowCSS (selector, css, effect) {
1970	
1971	jQuery(selector).css(css);
1972
1973	if ( jqmVisible(selector) ) return false;
1974
1975	if ( !isJQM(selector) ) {
1976		
1977		var opt = {};
1978		
1979		if ( effect == 'fade' )
1980			opt = {
1981				onShow: function(h) { 
1982					h.w.fadeIn(300);
1983				},
1984				onHide: function(h) { 
1985					h.w.fadeOut(300);
1986					h.o.remove();
1987				}
1988			}; //Object o
1989		
1990		jQuery(selector).jqm(opt);
1991		if ( jQuery().jqDrag ) jQuery(selector).jqDrag('.jqmHeader');
1992		if ( jQuery().jqResize ) jQuery(selector).jqResize('.jqmResize');
1993	} //IF element is not jqm window already
1994	
1995	jQuery(selector).jqmShow();
1996
1997	return false;
1998	
1999} //FUNC jqmShowCSS
2000
2001/*--------------------------------------------------------------------------------*\
2002|	jqmShowCentered
2003|----------------------------------------------------------------------------------
2004| Fixes coordinates of jQM window to match center.
2005| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2006|	Params:
2007|		selector	string	- Window to show.
2008|		effect		string	- Effect to use on displaying.
2009|	Return:
2010|				bool	- Alwyas false.
2011\*--------------------------------------------------------------= by Mr.V!T =-----*/
2012function jqmShowCentered (selector, effect) {
2013/**/	
2014	var wnd_width	= jQuery(selector).width();
2015	var wnd_height	= jQuery(selector).height();
2016	
2017	var parent_window = screenSize();
2018
2019	var wnd_left = ( parent_window.width - wnd_width ) / 2;
2020	var wnd_top = ( parent_window.height - wnd_height ) / 2;
2021
2022	var new_css = {'top':wnd_top,'left':wnd_left};
2023/*/
2024	var new_css = {'top':0,'left':0, 'margin': 'auto auto'};
2025	
2026/**/	
2027	return jqmShowCSS(selector, new_css, effect);
2028} //FUNC jqmShowCentered
2029
2030/*--------------------------------------------------------------------------------*\
2031|	jqmShowDocked
2032|----------------------------------------------------------------------------------
2033| Fixes coordinates of jQM window to dock to given element.
2034| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2035|	Params:
2036|		selector	string	- Window to show.
2037|		dock_to		string	- Selector of element to dock to.
2038|		effect		string	- Effect to use on displaying.
2039|	Return:
2040|				bool	- Alwyas false.
2041\*--------------------------------------------------------------= by Mr.V!T =-----*/
2042function jqmShowDocked (selector, dock_to, effect) {
2043	
2044	var offset	= jQuery(dock_to).offset();
2045	if ( !offset.top ) return false;
2046	
2047	var outer	= jQuery(dock_to).outerHeight();
2048	
2049	var new_css = {
2050		'top'		: offset.top + outer + 3,
2051		'left'		: offset.left
2052	}; //New CSS
2053	
2054	return jqmShowCSS(selector, new_css, effect);
2055} //FUNC jqmShowDocked
2056
2057/*--------------------------------------------------------------------------------*\
2058|	jqmHide
2059|----------------------------------------------------------------------------------
2060| Hides JQM window.
2061| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2062|	Params:
2063|		selector	string	- Window to hide.
2064|		effect		string	- Effect to use on hiding.
2065|	Return:
2066|				bool	- Alwyas false.
2067\*--------------------------------------------------------------= by Mr.V!T =-----*/
2068function jqmHide (selector, effect) {
2069	jQuery(selector).jqmHide();
2070	return false;
2071} //FUNC jqmHide
2072
2073/*--------------------------------------------------------------------------------*\
2074|	isJQM
2075|----------------------------------------------------------------------------------
2076| Check if element is already jqModal window.
2077| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2078|	Params:
2079|		selector	string	- Element to check.
2080|	Return:
2081|		NULL
2082\*--------------------------------------------------------------= by Mr.V!T =-----*/
2083function isJQM (selector) {
2084	
2085	var tmp = jQuery(selector).attr('class');
2086	if ( tmp.indexOf('jqmID') < 0 ) return false;
2087	
2088	return true;
2089	
2090} //FUNC isJQM
2091
2092/*--------------------------------------------------------------------------------*\
2093|	jqmVisible
2094|----------------------------------------------------------------------------------
2095| Checks if jqm window is visible.
2096| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2097|	Params:
2098|		selector	string	- Element to check.
2099|	Return:
2100|		NULL
2101\*--------------------------------------------------------------= by Mr.V!T =-----*/
2102function jqmVisible (element) {
2103
2104	if ( !(element instanceof jQuery) )
2105		element = jQuery(element);
2106	
2107	var disp = element.css('display');
2108	
2109	return (disp != 'none');
2110} //FUNC jqmVisible
2111
2112function centerWindow (win) {
2113	var wnd_width	= jQuery('#'+win).width();
2114	var wnd_height	= jQuery('#'+win).height();
2115	
2116	var parent_window = screenSize();
2117
2118	var wnd_left = ( parent_window.width - wnd_width ) / 2;
2119	var wnd_top = ( parent_window.height - wnd_height ) / 2;
2120
2121	var new_css = {'top':wnd_top,'left':wnd_left};
2122	jQuery('#'+win).css(new_css);
2123} //FUNC
2124
2125function getOuterHTML (el) {
2126	
2127	if ( el.outerHTML ) return el.outerHTML;
2128	
2129	var tmp = document.createElement(el.parentNode.tagName);
2130	tmp.appendChild(el.cloneNode(true));
2131	
2132	return tmp.innerHTML;
2133} //FUNC getOuterHTML
2134
2135function strToElement (html) {
2136	var tmp = document.createElement('div');
2137	tmp.innerHTML = html;
2138	
2139	return tmp.firstChild;
2140} //FUNC strToElement
2141
2142function setOuterHTML (el, html) {
2143	
2144	if ( el.outerHTML ) return el.outerHTML = html;
2145
2146	var n = strToElement(html);
2147	
2148	el.parentNode.replaceChild(n, el);
2149} //FUNC setOuterHTML
2150
2151/** //** ----= formToArray	=--------------------------------------------------------------------------------------\**//** \
2152*
2153*	Collects input values as data object. Result is exactly same as one you get with $_POST. 
2154*	Supports nested arrays and sets in naming. E.g.: name="lvl1[lvl2][lvl3][]"
2155*
2156*	@param		object(HTMLFormElement)	
2157*					$form	- Source form.
2158*
2159*	@return		object			- Data collected from form.
2160*
2161\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
2162function formToArray ($form) {
2163
2164	// Storing results in object
2165	var $data = {};
2166
2167// ---- 3rd parties ----
2168	
2169	// If there is tiny - forcing it to save editors
2170	if ( typeof(tinyMCE) != 'undefined' ) 
2171		tinyMCE.triggerSave();
2172	
2173	// Optionally supporting jQuery elements, though shold point exactly to form
2174	if ( isJQ($form) ) {
2175		
2176		// Not proceesing if not form though
2177		if ( !$form.is('form') )
2178			return $data;
2179		
2180		// Getting DOM from jQuery
2181		$form = $form.get(0);
2182	} //IF jQuery given
2183
2184// ---- Form ----
2185
2186	// Counting inputs with same name for sets resolving
2187	var $index = {};
2188
2189	// Looping through elements and getting values for each
2190	for ( var $i = 0; $i < $form.elements.length; $i++ ) {
2191
2192	// ---- Element ----
2193			
2194		// Getting element to work with
2195		var $el		= $form.elements.item($i);
2196
2197		// Collecting value, and then storing it in data object
2198		var $val;
2199
2200		// Skipping it if it does not have name
2201		if ( !$el.name )
2202			continue;
2203
2204	// ---- Input ----
2205		
2206		switch ( $el.type ) {
2207			case 'file' :
2208				// In HTML files are not included in post
2209				continue;
2210				
2211			case 'radio' :
2212			case 'checkbox'	:
2213
2214				$val = $el.value;
2215			
2216				if ( $val == 'on' ) {
2217
2218					// Using slightly alternate behavior 
2219					// where checkboxes without values (val == on) return 1/0 instead of 1/unset
2220					$val = ( $el.checked )? 1 : 0;
2221
2222				} //IF no value 
2223				else if ( !$el.checked ) {
2224
2225					// For valued checkboxes - regular behavior
2226					continue;
2227
2228				} //IF value is set
2229
2230				break;
2231				
2232			case 'select-one' :
2233				
2234				// Using dedicated tool
2235				$val = getValue_Select($el);
2236				
2237				break;
2238
2239			case 'select-multiple' :
2240			
2241				// Using dedicated tool
2242				$val = getValue_MutliSelect($el);
2243				
2244				break;
2245				
2246			default	:
2247
2248				// Regular inputs have just value
2249				$val = $el.value;
2250		} //SWITCH
2251
2252		// Nothing to do with null
2253		if ( isUndefined($val) )
2254			continue;
2255			
2256	// ---- Data ----
2257
2258		var $name	= $el.name;	// That will be working name
2259		
2260		// Expecting array to happen, so parsing as path right away
2261		var $path	= regexMatchAll(/[\w\-]+/g, $name);
2262		
2263		// Problematic paths are skipped too
2264		if ( !$path[0] )
2265			continue;
2266			
2267		// Full match is all we need
2268		$path = $path[0];	
2269
2270		// Indexing now, as it looks like valid name
2271		$index[$name]	= isSet($index[$name]) ? ++$index[$name] : 0;
2272		
2273		// Special case for sets
2274		// Those should be stored as simple array
2275		if ( $name.endsWith('[]') ) {
2276
2277			// Need to merge with existing array if one is present
2278			var $set = arrayPath($data, $path);
2279			
2280			// Merging value into set, which will be set into data
2281
2282			if ( isObject($set, true) )
2283			
2284				// Adding into objectx using index
2285				$set[$index[$name]] = $val;
2286				
2287			else if ( isArray($set) )
2288
2289				// Pushing if array
2290				$set.push($val)
2291
2292			else
2293				// Non arrays are overwritten
2294				$set = [$val];
2295
2296			// Preparing to be set back to data				
2297			$val = $set;
2298			
2299		} //IF set given
2300		
2301		// Now we have both value and path
2302		// Just setting it
2303		arrayPath($data, $path, $val);
2304		
2305	} //FOR each element
2306	
2307	return $data;
2308} //FUNC formToArray
2309
2310/** //** ----= formFromArray	=--------------------------------------------------------------------------------------\**//** \
2311*
2312*	Sets form inputs values from given data object.
2313*	Supports arrays and sets in elements names and tinyMCE Editor if applied to textarea.
2314*
2315*	@param		object(HTMLFormElement)	
2316*					$form	- Form to setup.
2317*
2318*	@param		object		$source	- Values to set.		
2319*
2320\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
2321function formFromArray ($form, $source) {
2322	
2323	// Resaving to do not break source 
2324	var $data	= jQuery.extend({}, $source);
2325	
2326	// Counting inputs with same name for sets resolving
2327	var $index = {};
2328
2329// ---- Form ----
2330	
2331	for ( var $i = 0; $i < $form.elements.length; $i++ ) {
2332
2333	// ---- Element ----
2334	
2335		// Getting form element, it's name and value that should be applied
2336		var $el		= $form.elements.item($i);
2337
2338		// Skipping it if it does not have name
2339		if ( !$el.name )
2340			continue;
2341
2342		// Getting element name
2343		var $name	= $el.name;
2344		
2345		// Expecting array to happen, so parsing as path right away
2346		var $path	= regexMatchAll(/[\w\-]+/g, $name);
2347		
2348		// Problematic paths are skipped too
2349		if ( !$path[0] )
2350			continue;
2351			
2352		// Full match is all we need
2353		$path = $path[0];	
2354
2355		// Indexing now, as it looks like valid name
2356		$index[$name]	= isSet($index[$name]) ? ++$index[$name] : 0;
2357	
2358	// ---- Value ----
2359	
2360		var $val = arrayPath($data, $path);
2361		
2362		// Resolving set
2363		var $set = $val;
2364		if ( $set && $name.endsWith('[]') ) { 
2365			
2366			// Getting value by index
2367			$val = $set[$index[$name]];
2368			
2369		} //IF set given
2370		
2371		// Making sure value is valid after all
2372		$val = ( isUndefined($val) || $val === false || $val === null ) ? '' : $val;
2373		
2374		// Special case for date inputs
2375		if ( $val == '0000-00-00' || $val == '0000-00-00 00:00:00' )
2376			$val = '';
2377
2378	// ---- Inputs ----
2379
2380		switch ($el.type) {
2381			
2382			case 'checkbox'	: 
2383			case 'radio'	: 
2384			
2385				// For simple checkboxes - comparing against found value
2386				// Value will be either set directly or indexed in set 
2387				if ( $el.value == 'on' ) {
2388
2389					$el.checked = ( !isEmpty($val) );
2390					break;
2391
2392				} //IF simple checkbox
2393			
2394				// If not part of set - just checking values to match
2395				// Casting incoming value to string manually to ensure that match is correct for numbers
2396				// Input value is always string anyway
2397				if ( !isObject($set, true) ) {
2398					
2399					$el.checked = ( $val.toString() === $el.value );
2400					break;
2401					
2402				} //IF not a set
2403
2404				// Custom behavior if part of set - checking by value presense
2405				// Looping through and checking if value is there
2406				// Doing manually instead of array's indexOf cuz assoc array or object could happen
2407				var $tmp = false;
2408				for ( var $t in $set )
2409					if ( $t in $set && $set[$t].toString() === $el.value )
2410						$tmp = true;
2411						
2412				$el.checked = $tmp;
2413			
2414				break;
2415				
2416			case 'select-one'	:
2417			case 'select-multiple'	:
2418				
2419				setValue_Select($el, $val);
2420
2421				break;
2422				
2423			case 'file' :
2424			
2425				// File just resetting to default.
2426
2427				// Getting input HTML, then creating new element from it, 
2428				// because simple clone will not help
2429				
2430				// Skipping styled forms
2431				// ToDo: capture events instead
2432
2433				if ( $el.className.indexOf('mw') !== -1 )
2434					break;
2435
2436				var $html = getOuterHTML($el);
2437				setOuterHTML($el, $html);
2438
2439				break;
2440				
2441			case 'textarea'	:
2442				
2443				// Checking if textarea can be tinyMCE
2444				if ( $el.style.display == 'none' && ( typeof tinyMCE != 'undefined' ) ) {
2445					
2446					// Checking if tiny really applied to it
2447					var $tiny = tinyMCE.get($el.id);
2448					
2449					// If it's tiny - setting values into it too.
2450					if ( $tiny )
2451						$tiny.setContent($val);
2452					
2453				}; //IF hidden and tinyMCE exists
2454
2455				$el.value = $val;
2456				
2457				break;
2458				
2459			case 'button' :
2460			case 'submit' :
2461			
2462				break;
2463				
2464			default	:
2465				$el.value = $val;
2466		} //SWITCH
2467
2468		// Triggering onChange in case if some set.
2469		if ( isSet(jQuery) ) 
2470			jQuery($el).change();
2471
2472	} //FOR each element
2473
2474} //FUNC formFromArray
2475
2476/** //** ----= jQuery.asArray	=--------------------------------------------------------------------------------------\**//** \
2477*
2478* 	Simple jQuery wrapper for formToArray() function.
2479*	
2480*	@return	array	- Form elements valus as array.
2481*
2482\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
2483jQuery.fn.asArray = function () {
2484	
2485	if ( !this.is('FORM') ) return {};
2486
2487	return formToArray(this.get(0));
2488} //FUNC asArray
2489
2490/** //** ----= jQuery.fromArray	=--------------------------------------------------------------------------------------\**//** \
2491*
2492* 	Simple jQuery wrapper for formFromArray() function.
2493*
2494*	@param	object	data	- Array with values to set to elements.
2495*	@return	jQuery		- jQuery object for chain calls.
2496*
2497\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
2498jQuery.fn.fromArray = function (data) {
2499	
2500	if ( !this.is('FORM') ) return this;
2501
2502	formFromArray( this.get(0), data );
2503	
2504	return this;
2505} //FUNC fromArray
2506
2507/*--------------------------------------------------------------------------------*\
2508|	getValue_Select
2509|----------------------------------------------------------------------------------
2510| Returns correct value of <select> based in setted or not value attribute. IE FIX.
2511| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2512|	Params:
2513|		element	object	- DOM elemnt to get value.
2514|	Return:
2515|			MIXED
2516|			bool	- FALSE in case of error.
2517|			string	- Element value.
2518\*--------------------------------------------------------------= by Mr.V!T =-----*/
2519function getValue_Select (element) {
2520	
2521	if ( element.options.selectedIndex < 0 ) return false;
2522	
2523	var option	= element.options[element.options.selectedIndex];
2524	var value	= getValue_Option(option);
2525	//(option.attributes.value && option.attributes.value.specified)? option.value : option.text
2526	
2527	return value;
2528} //FUNC getValue_Select
2529
2530/*--------------------------------------------------------------------------------*\
2531|	getValue_MutliSelect
2532|----------------------------------------------------------------------------------
2533| Returns values of <select> with multiple selection enabled as an array.
2534| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2535|	Params:
2536|		element	object	- DOM elemnt to get value.
2537|	Return:
2538|			array	- Array with values. Can be emty.
2539\*--------------------------------------------------------------= by Mr.V!T =-----*/
2540function getValue_MutliSelect (element) {
2541
2542	var res = [] ;
2543	
2544	if ( !element.options || element.options.length <= 0 ) return res;
2545
2546	for ( var i = 0; i < element.options.length; i++ ) {
2547		
2548		if ( !element.options[i].selected ) continue;
2549		
2550		res.push(getValue_Option(element.options[i]));
2551	} //FOR all managers
2552
2553	return res;
2554} //FUNC getValue_MutliSelect
2555
2556/*--------------------------------------------------------------------------------*\
2557|	setValue_Select
2558|----------------------------------------------------------------------------------
2559| Correctly sets value to selector. Works in old IE.
2560| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2561|	Params:
2562|		element	object	- DOM elemnt to set value.
2563|		values	MIXED	- Single string value or array with selected values.
2564|	Return:
2565|			VOID
2566\*--------------------------------------------------------------= by Mr.V!T =-----*/
2567function setValue_Select (element, values) {
2568
2569	if ( element.options.length <= 0 ) return;
2570
2571	if ( !values )
2572		values = [];
2573
2574	if ( typeof(values) != 'object' ) {
2575	
2576		// Converting values depending on multiple attribute
2577	 	// If multiple - most likely it's simple array string.
2578		if ( element.multiple || element.size )
2579			values = strToArray(values);
2580		else 
2581			// Stringifying value, cuz if integer come - indexOf will ignore it
2582			values = [values+''];
2583	
2584	} //IF not array come
2585
2586	for ( var i = 0; i < element.options.length; i++ ) {
2587		
2588		var val = getValue_Option(element.options[i]);
2589		
2590		element.options[i].selected = (values.indexOf(val) != -1);
2591		
2592	} //FOR all elements
2593
2594} //FUNC setValue_Select
2595
2596/*--------------------------------------------------------------------------------*\
2597|	getValue_Option
2598|----------------------------------------------------------------------------------
2599| Returns correct value of <option> based in setted or not value attribute. IE FIX.
2600| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2601|	Params:
2602|		element	object	- DOM elemnt to get value.
2603|	Return:
2604|			string	- Element value.
2605\*--------------------------------------------------------------= by Mr.V!T =-----*/
2606function getValue_Option (element) {
2607	var value	= (element.attributes.value && element.attributes.value.specified)? element.value : element.text;
2608	return value;
2609} //FUNC getValue_Option
2610
2611/*--------------------------------------------------------------------------------*\
2612|	getSelectorOptions
2613|----------------------------------------------------------------------------------
2614| Returns array with selector values.
2615| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2616|	Params:
2617|		element	object	- DOM elemnt to get value.
2618|	Return:
2619|			array	- Selector values.
2620\*--------------------------------------------------------------= by Mr.V!T =-----*/
2621function getSelectorOptions (element) {
2622	
2623	var res = [] ;
2624	
2625	if ( !element.options || element.options.length <= 0 ) return res;
2626
2627	for ( var i = 0; i < element.options.length; i++ ) {
2628
2629		var option = element.options[i];
2630
2631		if ( option.attributes.value && option.attributes.value.specified ) {
2632			res[option.value] = option.text;
2633		} else { //IF value set
2634			res.push(option.text);
2635		} //IF value not set
2636		
2637	} //FOR each option
2638
2639	return res;
2640} //FUNC getSelectorOptions
2641
2642/** //** ----= strToArray		 =--------------------------------------\**//** \
2643*
2644* 	Splits string into array with given delimeters, trimming resulting items.
2645*
2646* 	@param	string	str	- String to split.
2647*	@return	array		- Resulting array.
2648*
2649\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
2650function strToArray(str, delim) {
2651	
2652	delim = delim || ',|';
2653	
2654	var tmp = str.split( new RegExp('\\s*[' + delim + ']\\s*') );
2655	
2656	var res = [];
2657	
2658	// Skipping empties
2659	for ( var i in tmp )
2660		if ( tmp[i] ) res.push(tmp[i]);
2661	
2662	return res; 	
2663} //FUNC strToArray
2664
2665/** //** ----= strToObj		 =----------------------------------------------\**//** \
2666*
2667* 	Splits string into object array with given delimeters
2668*
2669* 	@param	string	str	- String to split.
2670*	@return	array		- Resulting array.
2671*
2672\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
2673function strToObj (str, delim, auto_tirm) {
2674	
2675	var res	= {};
2676	
2677	if ( !str )
2678		return res;
2679	
2680	var tmp = str.split(delim);
2681	
2682	var j = 0;
2683	
2684	for ( var i in tmp ) {
2685		
2686		var pos = tmp[i].indexOf('=');
2687
2688		if ( pos != -1 ) {
2689			var key = tmp[i].substr(0, pos);
2690			var val = tmp[i].substr(pos+1);
2691		} else { //IF eq symbol found
2692			var key = j+'';
2693			var val = tmp[i];
2694		} //IF single value
2695
2696		key = key.trim();
2697
2698		if ( auto_tirm )
2699			val = val.trim();
2700			
2701		res[key] = val;
2702			
2703		j++;
2704		
2705	} //FOR each value
2706
2707	return res;
2708} //FUNC strToObj
2709
2710/** //** ----= cb			 =--------------------------------------\**//** \
2711*
2712* 	Callback runner helper. Used to simplify code. Checks if funciton given.
2713*
2714* 	@param	function	func	- Function to run.
2715*	@param	MIXED		*	- All next parameters will be passed to function.
2716*
2717*	@return	MIXED			- Funciton restult.
2718*
2719\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
2720function cb(func, args) {
2721
2722	// ToDo: apply is not applicable here, so think better way;
2723	
2724} //FUNC cb
2725
2726/** //** ----= checkAll			 =--------------------------------------\**//** \
2727*
2728* 	Sets value to all checkboxes in an element.
2729*
2730* 	@param	bool	value	- Checkbox state.
2731* 	@param	string	element	- jQuery selector.
2732*	@return	bool		- Initial value.
2733*
2734\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
2735function checkAll (value, element) {
2736	
2737	jQuery(element).find('INPUT[type=checkbox]').attr('checked', value);
2738
2739	return false;	
2740} //FUNC checkAll
2741
2742function ToggleDisplay(elementID, state) {
2743	element = document.getElementById(elementID);
2744	
2745	if ( !element ) return;
2746	
2747	if (state == undefined) {
2748		state = ( element.style.display == 'none' );
2749	} //IF no state specified
2750	
2751	element.style.display = state ? 'inline' : 'none';
2752} //FUNC ToggleDisplay
2753
2754function screenSize() {
2755    var w, h;
2756    w = (window.innerWidth ? window.innerWidth : (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.offsetWidth));
2757    h = (window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.offsetHeight));
2758    return {width:w, height:h};
2759}
2760
2761function selectRow(row, state) {
2762	var row_class =	jQuery('#'+row).attr('class');
2763	row_class = row_class.replace('_selected','');
2764	row_class += ( state )? '_selected' : '';
2765	jQuery('#'+row).attr('class', row_class);
2766} //FUNC selectRow
2767
2768/*/
2769function insert_bar (bar_place) {
2770	jQuery('#'+bar_place).html('<IMG src="/images/processing/bar.gif" alt="Loading...">');
2771} //FUNC insert_bar
2772
2773function insert_green_bar (bar_place) {
2774	jQuery('#'+bar_place).html('<IMG src="/images/processing/bar_green.gif" alt="Loading...">');
2775} //FUNC insert_bar
2776//*/
2777
2778/** //** ----= getCookie		 =--------------------------------------\**//** \
2779*
2780* 	Returns cookie with given name.
2781*
2782* 	@param	string	name	- Cookie name to search.
2783*	@param	string	[def]	- Default value to return if cookie not found.
2784*
2785*	@return	string		- Cookie value.
2786*
2787\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
2788function getCookie (name, def) {
2789
2790	if ( def == undefined ) def = '';
2791
2792	var cookieValue	= def;
2793	var cookieName	= name + '=';
2794	
2795	if ( document.cookie.length > 0 ) { 
2796	
2797		offset = document.cookie.lastIndexOf(cookieName);
2798		if ( offset != -1 ) { 
2799		
2800			offset	+= cookieName.length;
2801			
2802			end	= document.cookie.indexOf(';', offset);
2803			if (end == -1) end = document.cookie.length;
2804			
2805			cookieValue = unescape(document.cookie.substring(offset, end))
2806		
2807		} //IF found smth
2808	
2809	} //IF there are cookies
2810	
2811	return cookieValue;
2812} //FUNC getCookie
2813
2814/** //** ----= setCookie	 =----------------------------------------------\**//** \
2815*
2816*	Sets cookie with given name.
2817*
2818*	@param	string	name	- Cookie name to set.
2819*	@param	string	value	- Value of cookie.
2820*	@param	string	[hours]	- Expiration date in hours.
2821*
2822\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
2823function setCookie (name, value, hours) {
2824	
2825	var expire	= "";
2826	
2827	if ( hours ) {
2828		expire = new Date((new Date()).getTime() + hours * 3600000);
2829		expire = "; expires=" + expire.toGMTString();
2830	} //IF there is set expiration
2831	
2832	document.cookie = name + "=" + escape(value) + expire + ';path=/;';
2833} //FUNC setCookie
2834
2835function get_controller_views(views) {
2836		insert_bars(views);
2837		insert_views(views,0);
2838} //FUNC get_controller_views
2839
2840function mark_checkboxes(container_form,val) {
2841	for (var i = 0; i < container_form.elements.length; i++) {
2842		el = container_form.elements[i];
2843		if (el.type=='checkbox')
2844			el.checked=val;
2845	}
2846} //FUNC mark_checkboxes
2847
2848function status_string(message,style_class,padding) {
2849	if (message == '') return '';
2850	if (!style_class) style_class = 'status_error';
2851	if (!padding) padding = 0;
2852	return '<div class="'+style_class+'" style="padding:'+padding+'px">'+message+'</div>';
2853} //FUNC error_string
2854
2855function ajax_pack_data(controller_url,place_to_put, data, ajax_options) {
2856	var res = [];
2857	res['controller']	= controller_url;
2858	res['place']		= place_to_put;
2859	if (!data) data	= {};
2860	res['data']		= data;
2861	if (!ajax_options) ajax_options	= {};
2862	res['options']		= ajax_options;
2863	return res;
2864} //FUNC pack_view
2865
2866function ajax_insert_bars(views) {
2867	for (i=0; i < views.length; i++) {
2868		insert_bar(views[i]['place']);
2869	} //FOR each views
2870} //FUNC insert_bars
2871
2872function ajax_insert_views(views,num) {
2873	if (num >= views.length) return false;
2874
2875	var tdata = views[num]['data'];
2876	
2877	if (views[num]['options'].onLoad) {views[num]['options'].onLoad(tdata)};
2878	jQuery.ajax({
2879		type	: 'POST', dataType: 'html',
2880		url	: views[num]['controller'],
2881		data	: views[num]['data'],
2882		success	: function(obj){
2883				jQuery('#'+views[num]['place']).html(obj);
2884				ajax_insert_views(views,num+1);
2885				if (views[num]['options'].onSuccess) {views[num]['options'].onSuccess(tdata)};
2886			},//FUNC success
2887		error : function (XMLHttpRequest, textStatus, errorThrown) {
2888				jQuery('#'+views[num]['place']).html(status_string('This section is not avaible now (Possibly under construction). Try again later.'));
2889				ajax_insert_views(views,num+1);
2890			} //FUNC error
2891	}); //ajax
2892}//FUNC insert_views
2893
2894function ajax_get_views(views) {
2895		ajax_insert_bars(views);
2896		ajax_insert_views(views,0);
2897} //FUNC get_controller_views
2898
2899function ajax_get_view(controller_url,place_to_put,data, ajax_options) {
2900	ajax_get_views([ajax_pack_data(controller_url,place_to_put,data, ajax_options)]);
2901} //FUNC get_controller_view
2902
2903function ajax_post (post_form,controller,status_place,settings) {
2904	insert_bar(status_place);
2905	var tt = document.getElementById(post_form);
2906	if (!tt) alert('no form');
2907//*/
2908	jQuery.ajaxUpload ({
2909		type		: 'POST', dataType : 'html',
2910	        url		: controller,
2911	        secureuri	: false,
2912	        uploadform	: document.getElementById(post_form),
2913	        success		: function (res, status) {
2914					data = res.split('<!-- CUT -->');
2915					jQuery('#'+status_place).html(data[0]);
2916
2917					if ((data.length != 1) && (data[1] == 'success') ) {
2918						if (settings.success) settings.success(data);
2919					} else {
2920						if (settings.error) settings.error(data);
2921					} //IF returned status
2922
2923				}, //FUNC sucess
2924		error		: function (res, status) {
2925					alert('error');
2926					jQuery('#'+status_place).html(status_string('Error: '+status));
2927					if (settings.error) settings.error();
2928				} //FUNC error
2929
2930	}); //AJAX
2931//*/	
2932} //FUNC ajax_post
2933
2934/** //** ----= getDimensions	=--------------------------------------------------------------------------------------\**//** \
2935*
2936*	Parses strings like '100x200' into [x,y] dimensions pair (with Y being optional). 
2937* 	Returns FALSE if string does not contain valid dimensions string.
2938*
2939*	@param		string	$dimensions	- Dimensions string.
2940* 	@param		bool	[$strict]	- Strict validation. Will require Y to present
2941*
2942*	@return		MIXED			- Array with named dimensons or FALSE if failed.
2943*
2944\**//** ---------------------------------------------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
2945function getDimensions ($dimensions, $strict) {
2946	
2947	// Nothing to do if notihng fiven
2948	if ( !$dimensions )
2949		return false;
2950	
2951	// Simple check for compatability with parsed dimensions, allowing mixed params in callee funcions.
2952	if ( isArray($dimensions) || isObject($dimensions) ) {
2953		
2954		// Fast validation for X to be present: it's minimal requirement for valid dimensions array
2955		if ( !isSet($dimensions['x']) )
2956			return false;
2957			
2958		// Fast validation for strict mode
2959		if ( $strict && !isSet($dimensions['y']) )
2960			return false;
2961		
2962		return $dimensions;
2963	} //IF array given
2964	
2965	// Parsing for dimensions, using regex. It also allows to validate dimensions stirng.
2966	// X and Y will be named in matches, which makes it easyer to return. 
2967
2968	// Strict option really changes counter for second (x200) match
2969	$strict = $strict ? '+' : '?';
2970
2971	// Capturing groups and then checking once that good
2972	var $reg	= '^([0-9]+)(x([0-9]+))' + $strict + '$';
2973	var $match	= $dimensions.match( new RegExp($reg, 'i') );
2974	
2975	// Checking existing  params
2976	if ( !$match )
2977		return false;
2978	
2979	// Grabbing only named matches into result (to keep result clear)
2980	var $res = {};
2981	
2982	// X always present at this step (othewise we'd returned already)
2983	$res['x']	= $match[1];	
2984	
2985	// Y is optional	
2986	if ( isSet($match[3]) )
2987		$res['y'] = $match[3];
2988	
2989	// Can return now
2990	return $res;
2991} //FUNC getDimensions
2992
2993/* #### MATH ################################################################################################################ */ 
2994
2995/** //** ----= asDeg	=----------------------------------------------------------------------------------------------\**//** \
2996*
2997*	Converts radians to degrees.
2998*
2999*	@param		float	$angle	- Angle in radians.
3000*
3001*	@return		flaot		- Angle in degrees.
3002*
3003\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
3004function asDeg ($angle) {
3005	return $angle * (180 / Math.PI);
3006} //FUNC asDeg
3007
3008/** //** ----= asRad	=----------------------------------------------------------------------------------------------\**//** \
3009*
3010*	Converts degrees to radians.
3011*
3012*	@param		float	$angle	- Angle in degrees.
3013*
3014*	@return		flaot		- Angle in radians.
3015*
3016\**//** ----------------------------------------------------------------------------------------------= by Mr.V!T =----/** //**/
3017function asRad ($angle) {
3018	return $angle * (Math.PI / 180);
3019} //FUNC asRad

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.