PageSourceSearch

https://www.sojos.com/sites/all/themes/fakre/js/jquery.main.js?st2e1d

js sojos.com collected 2026-10-02 08:04:10 UTC 205,551 bytes, 11,373 lines download raw bytes

1// page init
2
3var path_theme = jQuery('#path-theme').val();
4
5jQuery(function(){
6
7	"use strict";
8
9	initVideoPlayer();
10
11	initNumCounter();
12
13	initFitVids();
14
15	initCarousel();
16
17	initCountDown();
18
19	initSlideShow();
20
21	initAccordion();
22
23	initFlickrPhotos();
24
25	initVimeoPlayer();
26
27	initAudioPlayer();
28
29	initCustomForms();
30
31	initAnimatedProgressbars();
32
33	initYoutubePlayer();
34
35	initCycleCarousel();
36
37    initFormValidation();
38
39	initGoToTop();
40
41	initJqureyAnimation();
42
43	initGoToTopScroll();
44
45	initPieCharts();
46
47	initInstagramPics('2311561473.1677ed0.4e364b1ee1664889b061b4bb21612abe', ' e37e5979509b44cb811a8be2b1067f11');
48
49	initFlexSlider();
50
51	initOwlSlider();
52
53});
54
55jQuery(window).on('load', function() {
56
57	"use strict";
58
59	MegaMenu();
60
61	initPreLoader();
62
63	initTabs();
64
65	initMarquee();
66
67	initIsotope();
68
69	initLightbox();
70
71	initAjaxLoad();
72
73	initGoogleMap();
74
75	initMobileNav();
76
77	initSameHeight();
78
79	initParallaxBg();
80
81	initStyleChanger();
82
83	initHasDropClasses();
84
85	initStickyHeader();
86
87	initIsotopControl();
88
89	initBackgroundResize();
90
91	jQuery('input, textarea').placeholder();
92
93	initAnchors();
94
95});
96
97
98
99jQuery(window).scroll(function() {
100
101	initPieCharts();
102
103	initGoToTopScroll();
104
105	initAnimatedProgressbars();
106
107});
108
109
110
111// FlexSlider init
112
113function initFlexSlider() {
114
115	jQuery('.flexslider').flexslider({
116
117		animation: "slide"
118
119	});
120
121}
122
123
124
125// OwlSlider init
126
127function initOwlSlider() {
128
129	jQuery('#owl-example').owlCarousel({
130
131		autoPlay: true
132
133	});
134
135}
136
137
138
139// sticky header init
140
141function initStickyHeader() {
142
143	var win = jQuery(window),
144
145		stickyClass = 'fixed-position';
146
147
148
149	jQuery('#header').each(function() {
150
151		var header = jQuery(this);
152
153		var headerOffset = header.offset().top || 0;
154
155		var flag = true;
156
157
158
159		function scrollHandler() {
160
161			if (win.scrollTop() > headerOffset) {
162
163				if (flag){
164
165					flag = false;
166
167					header.addClass(stickyClass);
168
169				}
170
171			} else {
172
173				if (!flag) {
174
175					flag = true;
176
177					header.removeClass(stickyClass);
178
179				}
180
181			}
182
183
184
185			ResponsiveHelper.addRange({
186
187				'..767': {
188
189					on: function() {
190
191						header.removeClass(stickyClass);
192
193					}
194
195				}
196
197			});
198
199		}
200
201
202
203		scrollHandler();
204
205		win.on('scroll resize orientationchange', scrollHandler);
206
207	});
208
209}
210
211
212
213// instagram photos init
214
215function initInstagramPics(instaToken, instaID) {
216
217	var instaBox = jQuery('.instagram-photos');
218
219
220
221	jQuery.fn.spectragram.accessData = {
222
223		accessToken: instaToken,
224
225		clientID: instaID
226
227	};
228
229
230
231	instaBox.each(function() {
232
233		var item = jQuery(this);
234
235		var userName = item.attr('data-user');
236
237		var limit = item.attr('data-count') ? Number(item.attr('data-count')) : 8;
238
239
240
241		item.spectragram('getPopular',{
242
243			max: limit,
244
245			size: 'medium',
246
247			wrapEachWith: ' '
248
249		});
250
251	});
252
253}
254
255
256
257// animation init
258
259function initJqureyAnimation() {
260
261	var sections = jQuery('[data-animate]');
262
263	var	pageBody = jQuery('body');
264
265
266
267	sections.each(function() {
268
269		var item = jQuery(this);
270
271		var delay = item.attr('data-delay') ? Number(item.attr('data-delay')) + 500 : 500;
272
273		var animation = item.attr('data-animate');
274
275
276
277		if(!item.hasClass('animated')) {
278
279			item.addClass('not-animated');
280
281			item.appear(function () {
282
283				setTimeout(function() {
284
285					item.removeClass('not-animated').addClass(animation + ' animated');
286
287				}, delay);
288
289			},{accX: 0, accY: -120},'easeInCubic');
290
291		}
292
293	});
294
295}
296
297
298
299// flickr feed init
300
301function initFlickrPhotos() {
302
303	var flickrBox = jQuery('.flickr-feed');
304
305
306
307	flickrBox.each(function() {
308
309		var item = jQuery(this);
310
311		var feedType = item.attr('data-type');
312
313
314
315		item.jflickrfeed({
316
317			feedapi: feedType === 'group' ? 'groups_pool.gne' : feedType,
318
319			limit: Number(item.attr('data-count')) || 8,
320
321			qstrings: {
322
323				id: item.attr('data-id')
324
325			},
326
327			itemTemplate: '<a href="{{image_b}}" title="{{title}}" rel="lightbox">' + '<img src="{{image_s}}" alt="{{title}}" />' + '</a>'
328
329		});
330
331	});
332
333}
334
335
336
337// animate pie charts init
338
339function initPieCharts() {
340
341	if(typeof jQuery.fn.easyPieChart != 'undefined'){
342
343		jQuery(".pie-chart:in-viewport").each(function() {
344
345			var item = jQuery(this);
346
347			var dimension = item.attr("data-barSize");
348
349
350
351			item.css({
352
353				'height': dimension,
354
355				'width': dimension,
356
357				'line-height': dimension + 'px'
358
359			});
360
361
362
363			item.easyPieChart({
364
365				animate: 2000,
366
367				lineCap: "square",
368
369				lineWidth: item.attr("data-lineWidth"),
370
371				size: dimension,
372
373				barColor: item.attr("data-barColor"),
374
375				trackColor: item.attr("data-trackColor"),
376
377				scaleColor: "transparent",
378
379				onStep: function(from, to, percent) {
380
381					jQuery(this.el).find('.pie-chart-percent span').text(Math.round(from));
382
383				}
384
385			});
386
387		});
388
389	}
390
391}
392
393
394
395// progressbars init
396
397function initAnimatedProgressbars() {
398
399	jQuery(".progress-bar .progress-bar-outer:in-viewport").each(function() {
400
401		var item = jQuery(this);
402
403		var percent = item.attr('data-width');
404
405		var animationSpeed = 2500;
406
407		var flag = false;
408
409
410
411		if(!flag) {
412
413			item.animate({
414
415				width: percent + "%"
416
417			}, animationSpeed);
418
419
420
421			flag = true;
422
423		}
424
425	});
426
427}
428
429
430
431// count down init
432
433function initCountDown() {
434
435	if (jQuery('#countdown').length) {
436
437		var year = jQuery('#countdown').data('year');
438
439		var month = jQuery('#countdown').data('month') - 1;
440
441		var day = jQuery('#countdown').data('day');
442
443		var newDate = new Date(year, month, day);
444
445		jQuery('#countdown').countdown({until: newDate});
446
447	}
448
449}
450
451
452
453// counter init
454
455function initNumCounter() {
456
457	var counters = jQuery('.counter');
458
459	var pageBody = jQuery('body');
460
461
462
463	counters.each(function() {
464
465		var item = jQuery(this);
466
467		var isComma = item.find('span').attr('data-comma');
468
469
470
471		item.appear(function() {
472
473			if(isComma) {
474
475				item.find('span').countTo({
476
477					formatter: function (value, options) {
478
479						value = value.toFixed(options.decimals);
480
481						value = value.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
482
483						return value;
484
485					}
486
487				});
488
489			} else {
490
491				item.find('span').countTo();
492
493			}
494
495		});
496
497	});
498
499}
500
501
502
503// go to top init
504
505function initGoToTop() {
506
507	var linkTop = jQuery('#gotoTop');
508
509	var animationSpeed = 600;
510
511
512
513	linkTop.click(function(e) {
514
515		e.preventDefault();
516
517
518
519		jQuery('body,html').stop(true).animate({
520
521			scrollTop: 0
522
523		}, animationSpeed);
524
525	});
526
527}
528
529
530
531// go to top scroll init
532
533function initGoToTopScroll() {
534
535	var linkTop = jQuery('#gotoTop'),
536
537		win = jQuery(window);
538
539
540
541	if(win.scrollTop() > 0) {
542
543		linkTop.fadeIn();
544
545	} else {
546
547		linkTop.fadeOut();
548
549	}
550
551}
552
553
554
555// PreLoader init
556
557function initPreLoader() {
558
559	jQuery('#pre-loader').delay(1200).fadeOut();
560
561}
562
563
564
565// AudioPlayer init
566
567function initAudioPlayer() {
568
569	jQuery('audio').mediaelementplayer();
570
571}
572
573
574
575// VimeoPlayer init
576
577function initVimeoPlayer() {
578
579	var vimeoHolder = jQuery('.vimeo-area');
580
581
582
583	vimeoHolder.each(function(index, item) {
584
585		var container = jQuery(item);
586
587		var vimeoBox = container.find('.vimeo');
588
589		var iframe = jQuery('#player1')[0];
590
591		var player = $f(iframe);
592
593		var button = container.find('.btn-play');
594
595		var activeClass = 'playing';
596
597
598
599		window.setTimeout(function() {
600
601			vimeoBox.css({
602
603				visibility: 'visible'
604
605			});
606
607		}, 2000);
608
609
610
611		player.addEvent('ready', function() {
612
613			player.api('setVolume', 0);
614
615			button.on('click', function(e) {
616
617				e.preventDefault();
618
619
620
621				if(button.hasClass(activeClass)) {
622
623					player.api('pause');
624
625					button.removeClass(activeClass);
626
627				} else {
628
629					player.api('play');
630
631					button.addClass(activeClass);
632
633				}
634
635			});
636
637		});
638
639	});
640
641}
642
643
644
645// initVideoPlayer init
646
647function initVideoPlayer() {
648
649	jQuery('.video-area').each(function() {
650
651		var container = jQuery(this);
652
653		var player = container.find('video').mediaelementplayer().get(0);
654
655		var button = container.find('.btn-play');
656
657		var activeClass = 'playing';
658
659
660
661
662
663		if(container.hasClass('mute')) {
664
665		   player.setVolume(0);
666
667		}
668
669		button.on('click', function(e) {
670
671			e.preventDefault();
672
673
674
675			if(button.hasClass(activeClass)) {
676
677				player.pause();
678
679				button.removeClass(activeClass);
680
681			} else {
682
683				player.play();
684
685				button.addClass(activeClass);
686
687			}
688
689		});
690
691	});
692
693}
694
695
696
697// GoogleMap init
698
699function initGoogleMap() {
700
701	jQuery('.map').googleMapAPI({
702
703		marker: path_theme+'/images/icons/marker.png',
704
705		mapInfoContent: '.map-info',
706
707		streetViewControl: false,
708
709		mapTypeControl: false,
710
711		scrollwheel: false,
712
713		panControl: false,
714
715		zoomControl: false
716
717	});
718
719}
720
721
722
723//  Custom variables for isotop
724
725function initIsotopControl() {
726
727	var isotopeHolder = jQuery('#work'),
728
729		win = jQuery(window);
730
731
732
733	isotopeHolder.isotope({transitionDuration: '0.75s'});
734
735
736
737	setTimeout(function() {
738
739		isotopeHolder.isotope('layout');
740
741	}, 100);
742
743
744
745	jQuery('#work-filter a').click(function(e){
746
747		e.preventDefault();
748
749
750
751		jQuery('#work-filter li').removeClass('active');
752
753		jQuery(this).parent('li').addClass('active');
754
755		var selector = jQuery(this).attr('data-filter');
756
757		isotopeHolder.isotope({ filter: selector });
758
759	});
760
761
762
763	jQuery('#work-shuffle').click(function() {
764
765		isotopeHolder.isotope('updateSortData').isotope({
766
767			sortBy: 'random'
768
769		});
770
771	});
772
773
774
775	win.resize(function() {
776
777		isotopeHolder.isotope('layout');
778
779	});
780
781}
782
783
784
785// style changer
786
787function initStyleChanger() {
788
789	var element = jQuery('#style-changer');
790
791
792
793	if(element) {
794
795		$.ajax({
796
797			url: element.attr('data-src'),
798
799			type: 'get',
800
801			dataType: 'text',
802
803			success: function(data) {
804
805				var newContent = jQuery('<div>', {
806
807					html: data
808
809				});
810
811
812
813				newContent.appendTo(element);
814
815				jQuery('body').mobileNav({
816
817					hideOnClickOutside: false,
818
819					menuActiveClass: 'changer-active',
820
821					menuOpener: '.changer-opener'
822
823				});
824
825				jQuery('body').mobileNav({
826
827					hideOnClickOutside: false,
828
829					menuActiveClass: 'boxed-v',
830
831					menuOpener: '.boxed-link, .btn2',
832
833					onInit: function() {
834
835						initIsotopControl();
836
837						initBackgroundResize();
838
839					},
840
841					onHide: function() {
842
843						initIsotopControl();
844
845						initBackgroundResize();
846
847					}
848
849				});
850
851
852
853				var sheet,
854
855					darkSheet,
856
857					sheetName,
858
859					darkSheetName = 'dark',
860
861					sheetAdded = false,
862
863					darkStylesAdded = false;
864
865
866
867				jQuery('.list-color li').each(function() {
868
869					var item = jQuery(this),
870
871						link = item.find('a').eq(0);
872
873					var path_theme = jQuery('#style-changer').data('path-theme');
874
875					link.on('click', function(e) {
876
877						e.preventDefault();
878
879						sheetName = item.attr('class');
880
881
882
883						if(!sheetAdded) {
884
885							sheet = jQuery('<link>').attr('rel','stylesheet')
886
887										.attr('type','text/css')
888
889										.attr('href', path_theme+'/css/color/' + sheetName + '.css')
890
891										.appendTo('head');
892
893
894
895							sheetAdded = true;
896
897						} else {
898
899							sheet.attr('href', path_theme+'/css/color/' + sheetName + '.css');
900
901						}
902
903					});
904
905				});
906
907				jQuery('.list-bg-color li').each(function() {
908
909					var body = jQuery('body'),
910
911						item = jQuery(this),
912
913						link = item.find('a').eq(0);
914
915
916
917					link.on('click', function(e) {
918
919						e.preventDefault();
920
921
922
923						body.removeClass('dark');
924
925						if(link.hasClass('dark')) {
926
927							if(!body.hasClass('dark')) {
928
929								body.addClass('dark');
930
931							}
932
933						}
934
935					});
936
937				});
938
939			}
940
941		});
942
943	}
944
945}
946
947
948
949// initialize smooth anchor links
950
951function initAnchors() {
952
953	new SmoothScroll({
954
955		anchorLinks: 'a[href^="#"].smoothanchor',
956
957		extraOffset: 66,
958
959		activeClasses: 'parent'
960
961	});
962
963}
964
965
966
967// content tabs init
968
969function initTabs() {
970
971	jQuery('ul.beans-tabset').contentTabs({
972
973		addToParent: true,
974
975		tabLinks: 'a'
976
977	});
978
979	jQuery('ul.tabset').contentTabs({
980
981		addToParent: true,
982
983		tabLinks: 'a'
984
985	});
986
987	jQuery('ul.tabset-onepage').contentTabs({
988
989		addToParent: true,
990
991		tabLinks: 'a'
992
993	});
994
995}
996
997
998
999// Isotope init
1000
1001function initIsotope() {
1002
1003	jQuery('#masonry-container').isotope({
1004
1005		itemSelector: '.item',
1006
1007		transitionDuration: '0.6s',
1008
1009		masonry: {
1010
1011			columnWidth: 2,
1012
1013			gutter: 0,
1014
1015			isResizable: false
1016
1017		}
1018
1019	});
1020
1021}
1022
1023
1024
1025// init youtube background player
1026
1027function initYoutubePlayer() {
1028
1029	jQuery(".youtube_bg_video").each(function() {
1030
1031		var player = jQuery(this),
1032
1033			btnPlay = player.closest('.video-section').find('.play-icon'),
1034
1035			videoPlaying = false;
1036
1037			player.YTPlayer();
1038
1039
1040
1041		btnPlay.on('click', function(e) {
1042
1043			e.preventDefault();
1044
1045			if(videoPlaying) {
1046
1047				player.pauseYTP();
1048
1049				btnPlay.removeClass('video-playing').addClass('video-pause');
1050
1051				videoPlaying = false;
1052
1053			} else {
1054
1055				player.playYTP();
1056
1057				btnPlay.removeClass('video-pause').addClass('video-playing');
1058
1059				videoPlaying = true;
1060
1061			}
1062
1063		});
1064
1065	});
1066
1067}
1068
1069
1070
1071// handle flexible video size
1072
1073function initFitVids() {
1074
1075	jQuery('.vimeo').fitVids();
1076
1077	jQuery('.video-area').fitVids();
1078
1079}
1080
1081
1082
1083// align blocks height
1084
1085function initSameHeight() {
1086
1087	setSameHeight({
1088
1089		holder: '.same-block',
1090
1091		elements: '.same-column',
1092
1093		flexible: true,
1094
1095		multiLine: true,
1096
1097		biggestHeight: true
1098
1099	});
1100
1101}
1102
1103
1104
1105// ajax load init
1106
1107function initAjaxLoad(){
1108
1109	jQuery('.ajax-area').ajaxPopup({
1110
1111		button: '.btn-load',
1112
1113		ajaxHold: '#ajax-holder',
1114
1115		appendToBody: false,
1116
1117		attr: 'href',
1118
1119	 	animSpeed: 500,
1120
1121	 	onChange: function(){
1122
1123	 		initCycleCarousel();
1124
1125	 		initBackgroundResize();
1126
1127	 	}
1128
1129	});
1130
1131}
1132
1133
1134
1135// scroll galleries init
1136
1137function initCarousel() {
1138
1139	jQuery('.beans-stepslider').scrollGallery({
1140
1141		mask: '.beans-mask',
1142
1143		slider: '.beans-slideset',
1144
1145		slides: '.beans-slide',
1146
1147		btnPrev: 'a.btn-prev',
1148
1149		btnNext: 'a.btn-next',
1150
1151		generatePagination: '.beans-pagination',
1152
1153		stretchSlideToMask: true,
1154
1155		maskAutoSize: true,
1156
1157		autoRotation: false,
1158
1159		switchTime: 6000,
1160
1161		animSpeed: 1000,
1162
1163		step: 1
1164
1165	});
1166
1167}
1168
1169
1170
1171// cycle scroll galleries init
1172
1173function initCycleCarousel() {
1174
1175	jQuery('.beans-slider').scrollAbsoluteGallery({
1176
1177		mask: '.beans-mask',
1178
1179		slider: '.beans-slideset',
1180
1181		slides: '.beans-slide',
1182
1183		btnPrev: 'a.btn-prev',
1184
1185		btnNext: 'a.btn-next',
1186
1187		generatePagination: '.beans-pagination',
1188
1189		stretchSlideToMask: true,
1190
1191		pauseOnHover: false,
1192
1193		maskAutoSize: true,
1194
1195		autoRotation: false,
1196
1197		switchTime: 3000,
1198
1199		animSpeed: 1000
1200
1201	});
1202
1203	jQuery('.beans-stepslider2').scrollAbsoluteGallery({
1204
1205		mask: '.beans-mask',
1206
1207		slider: '.beans-slideset',
1208
1209		slides: '.beans-slide',
1210
1211		btnPrev: 'a.btn-prev',
1212
1213		btnNext: 'a.btn-next',
1214
1215		pagerLinks: '.beans-pagination ul li',
1216
1217		stretchSlideToMask: true,
1218
1219		pauseOnHover: false,
1220
1221		maskAutoSize: true,
1222
1223		autoRotation: false,
1224
1225		switchTime: 3000,
1226
1227		animSpeed: 1000
1228
1229	});
1230
1231}
1232
1233
1234
1235// fade gallery init
1236
1237function initSlideShow() {
1238
1239	jQuery('.beans-fadeslider').fadeGallery({
1240
1241		slides: '.slide',
1242
1243		btnPrev: 'a.btn-prev',
1244
1245		btnNext: 'a.btn-next',
1246
1247		generatePagination: '.beans-pagination',
1248
1249		event: 'click',
1250
1251		useSwipe: true,
1252
1253		autoRotation: true,
1254
1255		autoHeight: true,
1256
1257		switchTime: 3000,
1258
1259		animSpeed: 1000
1260
1261	});
1262
1263}
1264
1265
1266
1267// mobile menu init
1268
1269function initMobileNav() {
1270
1271	jQuery('body').mobileNav({
1272
1273		hideOnClickOutside: true,
1274
1275		menuActiveClass: 'sidenav-active',
1276
1277		menuOpener: '.menu-opener , .btn-close',
1278
1279		menuDrop: '.menu-nav'
1280
1281	});
1282
1283	jQuery('body').mobileNav({
1284
1285		hideOnClickOutside: false,
1286
1287		menuActiveClass: 'search-active',
1288
1289		menuOpener: '.search-opener , .close-btn'
1290
1291	});
1292
1293	jQuery('body').mobileNav({
1294
1295		hideOnClickOutside: false,
1296
1297		menuActiveClass: 'mainnav-active',
1298
1299		menuOpener: '.nav-opener',
1300
1301		menuDrop: '.sidemenu-photo'
1302
1303	});
1304
1305	jQuery('body').mobileNav({
1306
1307		hideOnClickOutside: true,
1308
1309		menuActiveClass: 'mainnav-active',
1310
1311		menuOpener: '.main-navopener2',
1312
1313		menuDrop: '.main-menu'
1314
1315	});
1316
1317	jQuery('body').mobileNav({
1318
1319		hideOnClickOutside: true,
1320
1321		menuActiveClass: 'nav-active',
1322
1323		menuOpener: '.portfolio-nav-opener'
1324
1325	});
1326
1327}
1328
1329//Mega menu
1330
1331function MegaMenu() {
1332
1333	jQuery('.nav-top > li.expanded').each(function(index, el) {
1334
1335		var menu = '';
1336
1337		if($(this).hasClass('has-mega-drop')) {
1338
1339			menu += '<a href="'+$(this).find('>a').attr("href")+'" class="'+$(this).find('>a').attr("class")+'">';
1340
1341			menu += $(this).find('>a').text()+'</a><div class="mega-drop"><div class="drop-holder">';
1342
1343			$(this).find('> .list-unstyled >li').each(function(index, el) {
1344
1345				if($(this).hasClass('title')) {
1346
1347					menu += '<div class="coll"><strong class="title">' + $(this).find('>a').text() + '</strong>';
1348
1349					menu += '<ul class="list-unstyled">';
1350
1351					$(this).find('>.list-unstyled >li').each(function(index, el) {
1352
1353						if($(this).hasClass('title')) {
1354
1355							menu += '<strong class="title">' + $(this).find('>a').text() + '</strong>';
1356
1357							if($(this).find('.list-unstyled').html()) {
1358
1359								menu += '<ul class="list-unstyled">' +$(this).find('>.list-unstyled').html() + '</ul>';
1360
1361							} else menu += '';
1362
1363
1364
1365						} else {
1366
1367							menu += '<li>' +$(this).html()+ '</li>';
1368
1369						}
1370
1371
1372
1373					});
1374
1375					menu += '</div>';
1376
1377
1378
1379				} else {
1380
1381					menu += '<strong class="title">' + $(this).find('>a').text() + '</strong>';
1382
1383					if($(this).find('.list-unstyled').html()) {
1384
1385						menu += '<ul class="list-unstyled">' + $(this).find('.list-unstyled').html() + '</ul></div>';
1386
1387					} else menu += '</div>';
1388
1389				}
1390
1391			});
1392
1393			menu += '</div></div>';
1394
1395			$(this).html(menu);
1396
1397		} else {
1398
1399			menu += '<a href="'+$(this).find('>a').attr("href")+'">'+ $(this).find('>a').text() + '</a>';
1400
1401			menu += '<div class="drop"><ul class="list-unstyled">';
1402
1403			$(this).find(">.list-unstyled >li").each(function(index, el) {
1404
1405				if($(this).hasClass('expanded')) {
1406
1407					menu += '<li class="has-drop"><a href="' + $(this).find('>a').attr('href')+'">'+ $(this).find('>a').text()+ '</a>';
1408
1409					if($(this).find('.list-unstyled').html()) {
1410
1411						menu += '<div class="drop"><ul class="list-unstyled">';
1412
1413						$(this).find('>.list-unstyled >li').each(function(index, el) {
1414
1415							if($(this).hasClass('expanded')) {
1416
1417								menu += '<li class="has-drop"><a href="' + $(this).find('>a').attr('href')+'">'+ $(this).find('>a').text()+ '</a>';
1418
1419								if($(this).find('.list-unstyled').html()) {
1420
1421									menu += '<div class="drop"><ul class="list-unstyled">' + $(this).find('.list-unstyled').html()+ '</ul></div>';
1422
1423								} else {
1424
1425									menu += '<div class="drop"></div>';
1426
1427								}
1428
1429								menu += '</li>';
1430
1431							} else {
1432
1433								menu += '<li><a href="' + $(this).find('>a').attr('href')+'">'+ $(this).find('>a').text()+ '</a></li>';
1434
1435							}
1436
1437						});
1438
1439						menu += '</ul></div>';
1440
1441					} else {
1442
1443
1444
1445					}
1446
1447					menu += '</li>';
1448
1449				} else {
1450
1451					menu += '<li><a href="' + $(this).find('>a').attr('href')+'">'+ $(this).find('>a').text()+ '</a></li>';
1452
1453				}
1454
1455			});
1456
1457			menu += '</ul></div>';
1458
1459			$(this).html(menu);
1460
1461		}
1462
1463	});
1464
1465}
1466
1467// dropdown classes
1468
1469function initHasDropClasses() {
1470
1471	var dropClassName = 'has-drop',
1472
1473		megaDropClassName = 'has-mega-drop';
1474
1475
1476
1477	jQuery('#nav li').each(function(index, item) {
1478
1479		var container = jQuery(item),
1480
1481			link = container.find('a'),
1482
1483			drop = container.find('.drop'),
1484
1485			megaDrop = container.find('.mega-drop');
1486
1487
1488
1489		if(drop.length) {
1490
1491			container.addClass(dropClassName);
1492
1493		}
1494
1495
1496
1497		if(megaDrop.length) {
1498
1499			container.addClass(megaDropClassName);
1500
1501		}
1502
1503	});
1504
1505}
1506
1507
1508
1509// initialize Parallax background
1510
1511function initParallaxBg() {
1512
1513	jQuery('.parallax-holder').parallaxBG({
1514
1515		parent: '.parallax-frame',
1516
1517		image: 'img',
1518
1519		parallaxOffset: 100,
1520
1521		fallbackFunc: initBgStretch
1522
1523	});
1524
1525}
1526
1527
1528
1529// stretch background to fill blocks
1530
1531function initBackgroundResize() {
1532
1533	jQuery('.stretch').each(function() {
1534
1535		ImageStretcher.add({
1536
1537			container: this,
1538
1539			image: 'img'
1540
1541		});
1542
1543	});
1544
1545}
1546
1547
1548
1549// running line init
1550
1551function initMarquee() {
1552
1553	jQuery('.line-box').marquee({
1554
1555		line: '.line',
1556
1557		animSpeed: 50
1558
1559	});
1560
1561}
1562
1563
1564
1565// initialize custom form elements
1566
1567function initCustomForms() {
1568
1569	jcf.replaceAll();
1570
1571}
1572
1573
1574
1575// fancybox modal popup init
1576
1577function initLightbox() {
1578
1579	jQuery('a.lightbox, a[rel*="lightbox"]').fancybox({
1580
1581		padding: 0,
1582
1583		loop: false,
1584
1585		helpers: {
1586
1587			overlay: {
1588
1589				css: {background: 'rgba(0, 0, 0, 0.35)'}
1590
1591			}
1592
1593		},
1594
1595		afterLoad: function(current, previous) {
1596
1597			// handle custom close button in inline modal
1598
1599			if(current.href.indexOf('#') === 0) {
1600
1601				jQuery(current.href).find('a.close').off('click.fb').on('click.fb', function(e){
1602
1603					e.preventDefault();
1604
1605					jQuery.fancybox.close();
1606
1607				});
1608
1609			}
1610
1611		}
1612
1613	});
1614
1615}
1616
1617
1618
1619// accordion menu init
1620
1621function initAccordion() {
1622
1623	jQuery('.blog-accordion').slideAccordion({
1624
1625		opener: 'a.opener',
1626
1627		slider: '.blog-slide',
1628
1629		animSpeed: 300
1630
1631	});
1632
1633	jQuery('.beans-accordion').slideAccordion({
1634
1635		opener: 'a.opener',
1636
1637		slider: '.beans-slide',
1638
1639		animSpeed: 300
1640
1641	});
1642
1643}
1644
1645
1646
1647// form validation init
1648
1649function initFormValidation() {
1650
1651	//if submit button is clicked
1652
1653	$('#submit,#submit2').click(function () {
1654
1655
1656
1657        //Get the data from all the fields
1658
1659        var name = $('input[name=name]');
1660
1661        var email = $('input[name=email]');
1662
1663        var website = $('input[name=website]');
1664
1665        var comment = $('textarea[name=comment]');
1666
1667        var returnError = false;
1668
1669
1670
1671        //Simple validation to make sure user entered something
1672
1673        //Add your own error checking here with JS, but also do some error checking with PHP.
1674
1675        //If error found, add hightlight class to the text field
1676
1677        if (name.val()=='') {
1678
1679            name.addClass('error');
1680
1681            returnError = true;
1682
1683        } else name.removeClass('error');
1684
1685
1686
1687        if (email.val()=='') {
1688
1689            email.addClass('error');
1690
1691            returnError = true;
1692
1693        } else email.removeClass('error');
1694
1695
1696
1697        if (comment.val()=='') {
1698
1699            comment.addClass('error');
1700
1701            returnError = true;
1702
1703        } else comment.removeClass('error');
1704
1705
1706
1707        // Highlight all error fields, then quit.
1708
1709        if(returnError == true) {
1710
1711            return false;
1712
1713        }
1714
1715
1716
1717        //organize the data
1718
1719        var data = 'name=' + name.val() + '&email=' + email.val() + '&website=' + website.val() + '&comment='  + encodeURIComponent(comment.val());
1720
1721
1722
1723        //disabled all the text fields
1724
1725        $('.text').attr('disabled','true');
1726
1727
1728
1729        //show the loading sign
1730
1731        $('.loading').show();
1732
1733
1734
1735        //start the ajax
1736
1737        $.ajax({
1738
1739            //this is the php file that processes the data and sends email
1740
1741            url: "inc/process.php",
1742
1743
1744
1745            //GET method is used
1746
1747            type: "GET",
1748
1749
1750
1751            //pass the data
1752
1753            data: data,
1754
1755
1756
1757            //Do not cache the page
1758
1759            cache: false,
1760
1761
1762
1763            //success
1764
1765            success: function (html) {
1766
1767            //if process.php returned 1/true (send mail success)
1768
1769                if (html==1) {
1770
1771                //hide the form
1772
1773                $('.email-form').fadeOut('slow');
1774
1775
1776
1777                //show the success message
1778
1779                $('.done-massage').fadeIn('slow');
1780
1781
1782
1783                //if process.php returned 0/false (send mail failed)
1784
1785                } else alert('Sorry, unexpected error. Please try again later.');
1786
1787            }
1788
1789        });
1790
1791
1792
1793        //cancel the submit button default behaviours
1794
1795        return false;
1796
1797	});
1798
1799	//if submit button is clicked
1800
1801	$('#form-submit').click(function () {
1802
1803
1804
1805        //Get the data from all the fields
1806
1807        var name = $('input[name=name]');
1808
1809        var email = $('input[name=email]');
1810
1811        var purchase = $('input[name=purchase]');
1812
1813        var profile = $('input[name=profile]');
1814
1815        var comment = $('textarea[name=comment]');
1816
1817        var returnError = false;
1818
1819
1820
1821        //Simple validation to make sure user entered something
1822
1823        //Add your own error checking here with JS, but also do some error checking with PHP.
1824
1825        //If error found, add hightlight class to the text field
1826
1827        if (name.val()=='') {
1828
1829            name.addClass('error');
1830
1831            returnError = true;
1832
1833        } else name.removeClass('error');
1834
1835
1836
1837        if (email.val()=='') {
1838
1839            email.addClass('error');
1840
1841            returnError = true;
1842
1843        } else email.removeClass('error');
1844
1845
1846
1847        if (purchase.val()=='') {
1848
1849            purchase.addClass('error');
1850
1851            returnError = true;
1852
1853        } else purchase.removeClass('error');
1854
1855
1856
1857        if (profile.val()=='') {
1858
1859            profile.addClass('error');
1860
1861            returnError = true;
1862
1863        } else profile.removeClass('error');
1864
1865
1866
1867        if (comment.val()=='') {
1868
1869            comment.addClass('error');
1870
1871            returnError = true;
1872
1873        } else comment.removeClass('error');
1874
1875
1876
1877        // Highlight all error fields, then quit.
1878
1879        if(returnError == true) {
1880
1881            return false;
1882
1883        }
1884
1885
1886
1887        //organize the data
1888
1889        var data = 'name=' + name.val() + '&email=' + email.val() + '&purchase=' + purchase.val() + '&profile=' + profile.val() + '&website=' + website.val() + '&comment='  + encodeURIComponent(comment.val());
1890
1891
1892
1893        //disabled all the text fields
1894
1895        $('.form-control').attr('disabled','true');
1896
1897
1898
1899        //show the loading sign
1900
1901        $('.loading').show();
1902
1903
1904
1905        //start the ajax
1906
1907        $.ajax({
1908
1909            //this is the php file that processes the data and sends email
1910
1911            url: "inc/process2.php",
1912
1913
1914
1915            //GET method is used
1916
1917            type: "GET",
1918
1919
1920
1921            //pass the data
1922
1923            data: data,
1924
1925
1926
1927            //Do not cache the page
1928
1929            cache: false,
1930
1931
1932
1933            //success
1934
1935            success: function (html) {
1936
1937            //if process.php returned 1/true (send mail success)
1938
1939                if (html==1) {
1940
1941                //hide the form
1942
1943                $('.email-form').fadeOut('slow');
1944
1945
1946
1947                //show the success message
1948
1949                $('.done-massage').fadeIn('slow');
1950
1951
1952
1953                //if process.php returned 0/false (send mail failed)
1954
1955                } else alert('Sorry, unexpected error. Please try again later.');
1956
1957            }
1958
1959        });
1960
1961
1962
1963        //cancel the submit button default behaviours
1964
1965        return false;
1966
1967	});
1968
1969}
1970
1971
1972
1973
1974
1975/*
1976
1977 * jQuery Carousel plugin
1978
1979 */
1980
1981;(function($){function ScrollGallery(options) {this.options = $.extend({mask: 'div.mask',slider: '>*',slides: '>*',activeClass:'active',disabledClass:'disabled',btnPrev: 'a.btn-prev',btnNext: 'a.btn-next',generatePagination: false,pagerList: '<ul>',pagerListItem: '<li><a href="#"></a></li>',pagerListItemText: 'a',pagerLinks: '.pagination li',currentNumber: 'span.current-num',totalNumber: 'span.total-num',btnPlay: '.btn-play',btnPause: '.btn-pause',btnPlayPause: '.btn-play-pause',galleryReadyClass: 'gallery-js-ready',autorotationActiveClass: 'autorotation-active',autorotationDisabledClass: 'autorotation-disabled',stretchSlideToMask: false,circularRotation: true,disableWhileAnimating: false,autoRotation: false,pauseOnHover: false,maskAutoSize: false,switchTime: 4000,animSpeed: 600,event:'click',swipeThreshold: 15,handleTouch: true,vertical: false,useTranslate3D: false,step: false}, options);this.init();}ScrollGallery.prototype = {init: function() {if(this.options.holder) {this.findElements();this.attachEvents();this.refreshPosition();this.refreshState(true);this.resumeRotation();this.makeCallback('onInit', this);}},findElements: function() {this.fullSizeFunction = this.options.vertical ? 'outerHeight' : 'outerWidth';this.innerSizeFunction = this.options.vertical ? 'height' : 'width';this.slideSizeFunction = 'outerHeight';this.maskSizeProperty = 'height';this.animProperty = this.options.vertical ? 'marginTop' : 'marginLeft';this.gallery = $(this.options.holder).addClass(this.options.galleryReadyClass);this.mask = this.gallery.find(this.options.mask);this.slider = this.mask.find(this.options.slider);this.slides = this.slider.find(this.options.slides);this.btnPrev = this.gallery.find(this.options.btnPrev);this.btnNext = this.gallery.find(this.options.btnNext);this.currentStep = 0; this.stepsCount = 0;if(this.options.step === false) {var activeSlide = this.slides.filter('.'+this.options.activeClass);if(activeSlide.length) {this.currentStep = this.slides.index(activeSlide);}}this.calculateOffsets();if(typeof this.options.generatePagination === 'string') {this.pagerLinks = $();this.buildPagination();} else {this.pagerLinks = this.gallery.find(this.options.pagerLinks);this.attachPaginationEvents();}this.btnPlay = this.gallery.find(this.options.btnPlay);this.btnPause = this.gallery.find(this.options.btnPause);this.btnPlayPause = this.gallery.find(this.options.btnPlayPause);this.curNum = this.gallery.find(this.options.currentNumber);this.allNum = this.gallery.find(this.options.totalNumber);},attachEvents: function() {var self = this;this.bindHandlers(['onWindowResize']);$(window).bind('load resize orientationchange', this.onWindowResize);if(this.btnPrev.length) {this.prevSlideHandler = function(e) {e.preventDefault();self.prevSlide();};this.btnPrev.bind(this.options.event, this.prevSlideHandler);}if(this.btnNext.length) {this.nextSlideHandler = function(e) {e.preventDefault();self.nextSlide();};this.btnNext.bind(this.options.event, this.nextSlideHandler);}if(this.options.pauseOnHover && !isTouchDevice) {this.hoverHandler = function() {if(self.options.autoRotation) {self.galleryHover = true;self.pauseRotation();}};this.leaveHandler = function() {if(self.options.autoRotation) {self.galleryHover = false;self.resumeRotation();}};this.gallery.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});}if(this.btnPlay.length) {this.btnPlayHandler = function(e) {e.preventDefault();self.startRotation();};this.btnPlay.bind(this.options.event, this.btnPlayHandler);}if(this.btnPause.length) {this.btnPauseHandler = function(e) {e.preventDefault();self.stopRotation();};this.btnPause.bind(this.options.event, this.btnPauseHandler);}if(this.btnPlayPause.length) {this.btnPlayPauseHandler = function(e) {e.preventDefault();if(!self.gallery.hasClass(self.options.autorotationActiveClass)) {self.startRotation();} else {self.stopRotation();}};this.btnPlayPause.bind(this.options.event, this.btnPlayPauseHandler);}if(isTouchDevice && this.options.useTranslate3D) {this.slider.css({'-webkit-transform': 'translate3d(0px, 0px, 0px)'});}if(isTouchDevice && this.options.handleTouch && window.Hammer && this.mask.length) {this.swipeHandler = new Hammer.Manager(this.mask[0]);this.swipeHandler.add(new Hammer.Pan({direction: self.options.vertical ? Hammer.DIRECTION_VERTICAL : Hammer.DIRECTION_HORIZONTAL,threshold: self.options.swipeThreshold}));this.swipeHandler.on('panstart', function() {if(self.galleryAnimating) {self.swipeHandler.stop();} else {self.pauseRotation();self.originalOffset = parseFloat(self.slider.css(self.animProperty));}}).on('panmove', function(e) {var tmpOffset = self.originalOffset + e[self.options.vertical ? 'deltaY' : 'deltaX'];tmpOffset = Math.max(Math.min(0, tmpOffset), self.maxOffset);self.slider.css(self.animProperty, tmpOffset);}).on('panend', function(e) {self.resumeRotation();if(e.distance > self.options.swipeThreshold) {if(e.offsetDirection === Hammer.DIRECTION_RIGHT || e.offsetDirection === Hammer.DIRECTION_DOWN) {self.nextSlide();} else {self.prevSlide();}} else {self.switchSlide();}});}},onWindowResize: function() {if(!this.galleryAnimating) {this.calculateOffsets();this.refreshPosition();this.buildPagination();this.refreshState();this.resizeQueue = false;} else {this.resizeQueue = true;}},refreshPosition: function() {this.currentStep = Math.min(this.currentStep, this.stepsCount - 1);this.tmpProps = {};
1981this.tmpProps[this.animProperty] = this.getStepOffset();this.slider.stop().css(this.tmpProps);},calculateOffsets: function() {var self = this, tmpOffset, tmpStep;if(this.options.stretchSlideToMask) {var tmpObj = {};tmpObj[this.innerSizeFunction] = this.mask[this.innerSizeFunction]();this.slides.css(tmpObj);}this.maskSize = this.mask[this.innerSizeFunction]();this.sumSize = this.getSumSize();this.maxOffset = this.maskSize - this.sumSize;if(this.options.vertical && this.options.maskAutoSize) {this.options.step = 1;this.stepsCount = this.slides.length;this.stepOffsets = [0];tmpOffset = 0;for(var i = 0; i < this.slides.length; i++) {tmpOffset -= $(this.slides[i])[this.fullSizeFunction](true);this.stepOffsets.push(tmpOffset);}this.maxOffset = tmpOffset;return;}if(typeof this.options.step === 'number' && this.options.step > 0) {this.slideDimensions = [];this.slides.each($.proxy(function(ind, obj){self.slideDimensions.push( $(obj)[self.fullSizeFunction](true) );},this));this.stepOffsets = [0];this.stepsCount = 1;tmpOffset = tmpStep = 0;while(tmpOffset > this.maxOffset) {tmpOffset -= this.getSlideSize(tmpStep, tmpStep + this.options.step);tmpStep += this.options.step;this.stepOffsets.push(Math.max(tmpOffset, this.maxOffset));this.stepsCount++;}}else {this.stepSize = this.maskSize;this.stepsCount = 1;tmpOffset = 0;while(tmpOffset > this.maxOffset) {tmpOffset -= this.stepSize;this.stepsCount++;}}},getSumSize: function() {var sum = 0;this.slides.each($.proxy(function(ind, obj){sum += $(obj)[this.fullSizeFunction](true);},this));this.slider.css(this.innerSizeFunction, sum);return sum;},getStepOffset: function(step) {step = step || this.currentStep;if(typeof this.options.step === 'number') {return this.stepOffsets[this.currentStep];} else {return Math.min(0, Math.max(-this.currentStep * this.stepSize, this.maxOffset));}},getSlideSize: function(i1, i2) {var sum = 0;for(var i = i1; i < Math.min(i2, this.slideDimensions.length); i++) {sum += this.slideDimensions[i];}return sum;},buildPagination: function() {if(typeof this.options.generatePagination === 'string') {if(!this.pagerHolder) {this.pagerHolder = this.gallery.find(this.options.generatePagination);}if(this.pagerHolder.length && this.oldStepsCount != this.stepsCount) {this.oldStepsCount = this.stepsCount;this.pagerHolder.empty();this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder);for(var i = 0; i < this.stepsCount; i++) {$(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1);}this.pagerLinks = this.pagerList.children();this.attachPaginationEvents();}}},attachPaginationEvents: function() {var self = this;this.pagerLinksHandler = function(e) {e.preventDefault();self.numSlide(self.pagerLinks.index(e.currentTarget));};this.pagerLinks.bind(this.options.event, this.pagerLinksHandler);},prevSlide: function() {if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {if(this.currentStep > 0) {this.currentStep--;this.switchSlide();} else if(this.options.circularRotation) {this.currentStep = this.stepsCount - 1;this.switchSlide();}}},nextSlide: function(fromAutoRotation) {if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {if(this.currentStep < this.stepsCount - 1) {this.currentStep++;this.switchSlide();} else if(this.options.circularRotation || fromAutoRotation === true) {this.currentStep = 0;this.switchSlide();}}},numSlide: function(c) {if(this.currentStep != c) {this.currentStep = c;this.switchSlide();}},switchSlide: function() {var self = this;this.galleryAnimating = true;this.tmpProps = {};this.tmpProps[this.animProperty] = this.getStepOffset();this.slider.stop().animate(this.tmpProps, {duration: this.options.animSpeed, complete: function(){self.galleryAnimating = false;if(self.resizeQueue) {self.onWindowResize();}self.makeCallback('onChange', self);self.autoRotate();}});this.refreshState();this.makeCallback('onBeforeChange', this);},refreshState: function(initial) {if(this.options.step === 1 || this.stepsCount === this.slides.length) {this.slides.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass);}this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentStep).addClass(this.options.activeClass);this.curNum.html(this.currentStep+1);this.allNum.html(this.stepsCount);if(this.options.maskAutoSize && typeof this.options.step === 'number') {this.tmpProps = {};this.tmpProps[this.maskSizeProperty] = this.slides.eq(Math.min(this.currentStep,this.slides.length-1))[this.slideSizeFunction](true);this.mask.stop()[initial ? 'css' : 'animate'](this.tmpProps);}if(!this.options.circularRotation) {this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass);if(this.currentStep === 0) this.btnPrev.addClass(this.options.disabledClass);if(this.currentStep === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass);}
1981this.gallery.toggleClass('not-enough-slides', this.sumSize <= this.maskSize);},startRotation: function() {this.options.autoRotation = true;this.galleryHover = false;this.autoRotationStopped = false;this.resumeRotation();},stopRotation: function() {this.galleryHover = true;this.autoRotationStopped = true;this.pauseRotation();},pauseRotation: function() {this.gallery.addClass(this.options.autorotationDisabledClass);this.gallery.removeClass(this.options.autorotationActiveClass);clearTimeout(this.timer);},resumeRotation: function() {if(!this.autoRotationStopped) {this.gallery.addClass(this.options.autorotationActiveClass);this.gallery.removeClass(this.options.autorotationDisabledClass);this.autoRotate();}},autoRotate: function() {var self = this;clearTimeout(this.timer);if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) {this.timer = setTimeout(function(){self.nextSlide(true);}, this.options.switchTime);} else {this.pauseRotation();}},bindHandlers: function(handlersList) {var self = this;$.each(handlersList, function(index, handler) {var origHandler = self[handler];self[handler] = function() {return origHandler.apply(self, arguments);};});},makeCallback: function(name) {if(typeof this.options[name] === 'function') {var args = Array.prototype.slice.call(arguments);args.shift();this.options[name].apply(this, args);}}};var isTouchDevice = /Windows Phone/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;$.fn.scrollGallery = function(opt){return this.each(function(){$(this).data('ScrollGallery', new ScrollGallery($.extend(opt,{holder:this})));});};}(jQuery));
1982
1983
1984
1985/*
1986
1987 * jQuery Cycle Carousel plugin
1988
1989 */
1990
1991;(function($){function ScrollAbsoluteGallery(options) {this.options = $.extend({activeClass: 'active',mask: 'div.slides-mask',slider: '>ul',slides: '>li',btnPrev: '.btn-prev',btnNext: '.btn-next',pagerLinks: 'ul.pager > li',generatePagination: false,pagerList: '<ul>',pagerListItem: '<li><a href="#"></a></li>',pagerListItemText: 'a',galleryReadyClass: 'gallery-js-ready',currentNumber: 'span.current-num',totalNumber: 'span.total-num',maskAutoSize: false,autoRotation: false,pauseOnHover: false,stretchSlideToMask: false,switchTime: 3000,animSpeed: 500,handleTouch: true,swipeThreshold: 15,vertical: false}, options);this.init();}ScrollAbsoluteGallery.prototype = {init: function() {if(this.options.holder) {this.findElements();this.attachEvents();this.makeCallback('onInit', this);}},findElements: function() {this.holder = $(this.options.holder).addClass(this.options.galleryReadyClass);this.mask = this.holder.find(this.options.mask);this.slider = this.mask.find(this.options.slider);this.slides = this.slider.find(this.options.slides);this.btnPrev = this.holder.find(this.options.btnPrev);this.btnNext = this.holder.find(this.options.btnNext);this.currentNumber = this.holder.find(this.options.currentNumber);this.totalNumber = this.holder.find(this.options.totalNumber);this.updateAttributes();if(typeof this.options.generatePagination === 'string') {this.pagerLinks = this.buildPagination();} else {this.pagerLinks = this.holder.find(this.options.pagerLinks);}this.sizeProperty = this.options.vertical ? 'height' : 'width';this.positionProperty = this.options.vertical ? 'top' : 'left';this.animProperty = this.options.vertical ? 'marginTop' : 'marginLeft';this.slideSize = this.slides[this.sizeProperty]();this.currentIndex = 0;this.prevIndex = 0;this.options.maskAutoSize = this.options.vertical ? false : this.options.maskAutoSize;if(this.options.vertical) {this.mask.css({height: this.slides.innerHeight()});}if(this.options.maskAutoSize){this.mask.css({height: this.slider.height()});}this.slider.css({position: 'relative',height: this.options.vertical ? this.slideSize * this.slides.length : '100%'});this.slides.css({position: 'absolute'}).css(this.positionProperty, -9999).eq(this.currentIndex).css(this.positionProperty, 0);this.refreshState();},updateAttributes: function() {if(this.holder.attr('data-rotate') === 'true') {this.options.autoRotation = true;}if(this.holder.attr('data-direction') === 'vertical') {this.options.vertical = true;}if(this.holder.attr('data-pause-hover') === 'true') {this.options.pauseOnHover = true;}if(this.holder.attr('data-speed')) {this.options.animSpeed = parseFloat(this.holder.attr('data-speed'));}},buildPagination: function() {var pagerLinks = $();if(!this.pagerHolder) {this.pagerHolder = this.holder.find(this.options.generatePagination);}if(this.pagerHolder.length) {this.pagerHolder.empty();this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder);for(var i = 0; i < this.slides.length; i++) {$(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1);}
1991pagerLinks = this.pagerList.children();}return pagerLinks;},updateAttributes: function() {if(this.holder.attr('data-rotate') === 'true') {this.options.autoRotation = true;}if(this.holder.attr('data-direction') === 'vertical') {this.options.vertical = true;}if(this.holder.attr('data-pause-hover') === 'true') {this.options.pauseOnHover = true;}if(this.holder.attr('data-speed')) {this.options.animSpeed = parseFloat(this.holder.attr('data-speed'));}},attachEvents: function() {var self = this;if(this.btnPrev.length) {this.btnPrevHandler = function(e) {e.preventDefault();self.prevSlide();};this.btnPrev.click(this.btnPrevHandler);}if(this.btnNext.length) {this.btnNextHandler = function(e) {e.preventDefault();self.nextSlide();};this.btnNext.click(this.btnNextHandler);}if(this.pagerLinks.length) {this.pagerLinksHandler = function(e) {e.preventDefault();self.numSlide(self.pagerLinks.index(e.currentTarget));};this.pagerLinks.click(this.pagerLinksHandler);}if(this.options.pauseOnHover) {this.hoverHandler = function() {clearTimeout(self.timer);};this.leaveHandler = function() {self.autoRotate();};this.holder.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});}this.resizeHandler = function() {if(!self.animating) {if(self.options.stretchSlideToMask) {self.resizeSlides();}self.resizeHolder();self.setSlidesPosition(self.currentIndex);}};$(window).bind('load resize orientationchange', this.resizeHandler);if(self.options.stretchSlideToMask) {self.resizeSlides();}if(this.options.handleTouch && window.Hammer && this.mask.length && this.slides.length > 1 && isTouchDevice) {this.swipeHandler = new Hammer.Manager(this.mask[0]);this.swipeHandler.add(new Hammer.Pan({direction: self.options.vertical ? Hammer.DIRECTION_VERTICAL : Hammer.DIRECTION_HORIZONTAL,threshold: self.options.swipeThreshold}));this.swipeHandler.on('panstart', function() {if(self.animating) {self.swipeHandler.stop();} else {clearTimeout(self.timer);}}).on('panmove', function(e) {self.swipeOffset = -self.slideSize + e[self.options.vertical ? 'deltaY' : 'deltaX'];self.slider.css(self.animProperty, self.swipeOffset);clearTimeout(self.timer);}).on('panend', function(e) {if(e.distance > self.options.swipeThreshold) {if(e.offsetDirection === Hammer.DIRECTION_RIGHT || e.offsetDirection === Hammer.DIRECTION_DOWN) {self.nextSlide();} else {self.prevSlide();}} else {var tmpObj = {};tmpObj[self.animProperty] = -self.slideSize;self.slider.animate(tmpObj, {duration: self.options.animSpeed});self.autoRotate();}self.swipeOffset = 0;});}this.autoRotate();this.resizeHolder();this.setSlidesPosition(this.currentIndex);},resizeSlides: function() {this.slideSize = this.mask[this.options.vertical ? 'height' : 'width']();this.slides.css(this.sizeProperty, this.slideSize);},resizeHolder: function() {if(this.options.maskAutoSize) {this.mask.css({height: this.slides.eq(this.currentIndex).outerHeight(true)});}},prevSlide: function() {if(!this.animating && this.slides.length > 1) {this.direction = -1;this.prevIndex = this.currentIndex;if(this.currentIndex > 0) this.currentIndex--;else this.currentIndex = this.slides.length - 1;this.switchSlide();}},nextSlide: function(fromAutoRotation) {if(!this.animating && this.slides.length > 1) {this.direction = 1;this.prevIndex = this.currentIndex;if(this.currentIndex < this.slides.length - 1) this.currentIndex++;else this.currentIndex = 0;this.switchSlide();}},numSlide: function(c) {if(!this.animating && this.currentIndex !== c && this.slides.length > 1) {this.direction = c > this.currentIndex ? 1 : -1;this.prevIndex = this.currentIndex;this.currentIndex = c;this.switchSlide();}},preparePosition: function() {this.setSlidesPosition(this.prevIndex, this.direction < 0 ? this.currentIndex : null, this.direction > 0 ? this.currentIndex : null, this.direction);},setSlidesPosition: function(index, slideLeft, slideRight, direction) {if(this.slides.length > 1) {var prevIndex = (typeof slideLeft === 'number' ? slideLeft : index > 0 ? index - 1 : this.slides.length - 1);var nextIndex = (typeof slideRight === 'number' ? slideRight : index < this.slides.length - 1 ? index + 1 : 0);this.slider.css(this.animProperty, this.swipeOffset ? this.swipeOffset : -this.slideSize);this.slides.css(this.positionProperty, -9999).eq(index).css(this.positionProperty, this.slideSize);if(prevIndex === nextIndex && typeof direction === 'number') {var calcOffset = direction > 0 ? this.slideSize*2 : 0;this.slides.eq(nextIndex).css(this.positionProperty, calcOffset);} else {this.slides.eq(prevIndex).css(this.positionProperty, 0);this.slides.eq(nextIndex).css(this.positionProperty, this.slideSize*2);}}},switchSlide: function() {var self = this;var oldSlide = this.slides.eq(this.prevIndex);var newSlide = this.slides.eq(this.currentIndex);self.hideContent();this.animating = true;if(this.options.maskAutoSize) {this.mask.animate({height: newSlide.outerHeight(true)}, {duration: this.options.animSpeed});}var animProps = {};animProps[this.animProperty] = this.direction > 0 ? -this.slideSize*2 : 0;this.preparePosition();this.slider.animate(animProps,{duration:this.options.animSpeed, complete:function() {self.showContent();self.setSlidesPosition(self.currentIndex);self.animating = false;self.autoRotate();self.makeCallback('onChange', self);}});this.refreshState();this.makeCallback('onBeforeChange', this);},hideContent: function() {$(this.slides.eq(this.currentIndex)).find('.heading2, anim-heading').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);$(this.slides.eq(this.currentIndex)).find('.btn-box').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);$(this.slides.eq(this.currentIndex)).find('.title2').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);},showContent: function() {$(this.slides.eq(this.currentIndex)).find('.heading2, anim-heading').animate({bottom: 0,opacity: 1}, 700);$(this.slides.eq(this.currentIndex)).find('.btn-box').animate({bottom: 0,opacity: 1}, 700);$(this.slides.eq(this.currentIndex)).find('.title2').animate({bottom: 0,opacity: 1}, 700);},refreshState: function(initial) {this.slides.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);this.currentNumber.html(this.currentIndex + 1);this.totalNumber.html(this.slides.length);
1991this.holder.toggleClass('not-enough-slides', this.slides.length === 1);},autoRotate: function() {var self = this;clearTimeout(this.timer);if(this.options.autoRotation) {this.timer = setTimeout(function() {self.nextSlide();}, this.options.switchTime);}},makeCallback: function(name) {if(typeof this.options[name] === 'function') {var args = Array.prototype.slice.call(arguments);args.shift();this.options[name].apply(this, args);}}};var isTouchDevice = /Windows Phone/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;$.fn.scrollAbsoluteGallery = function(opt){return this.each(function(){$(this).data('ScrollAbsoluteGallery', new ScrollAbsoluteGallery($.extend(opt,{holder:this})));});};}(jQuery));
1992
1993
1994
1995/*
1996
1997 * Simple Mobile Navigation
1998
1999 */
2000
2001;(function($) {
2002
2003	function MobileNav(options) {
2004
2005		this.options = $.extend({
2006
2007			container: null,
2008
2009			hideOnClickOutside: false,
2010
2011			menuActiveClass: 'nav-active',
2012
2013			menuOpener: '.nav-opener',
2014
2015			menuDrop: '.nav-drop',
2016
2017			toggleEvent: 'click',
2018
2019			outsideClickEvent: 'click touchstart pointerdown MSPointerDown'
2020
2021		}, options);
2022
2023		this.initStructure();
2024
2025		this.attachEvents();
2026
2027	}
2028
2029	MobileNav.prototype = {
2030
2031		initStructure: function() {
2032
2033			this.page = $('html');
2034
2035			this.container = $(this.options.container);
2036
2037			this.opener = this.container.find(this.options.menuOpener);
2038
2039			this.drop = this.container.find(this.options.menuDrop);
2040
2041		},
2042
2043		attachEvents: function() {
2044
2045			var self = this;
2046
2047
2048
2049			if(activateResizeHandler) {
2050
2051				activateResizeHandler();
2052
2053				activateResizeHandler = null;
2054
2055			}
2056
2057
2058
2059			this.outsideClickHandler = function(e) {
2060
2061				if(self.isOpened()) {
2062
2063					var target = $(e.target);
2064
2065					if(!target.closest(self.opener).length && !target.closest(self.drop).length) {
2066
2067						self.hide();
2068
2069					}
2070
2071				}
2072
2073			};
2074
2075
2076
2077			this.openerClickHandler = function(e) {
2078
2079				e.preventDefault();
2080
2081				self.toggle();
2082
2083			};
2084
2085
2086
2087			this.opener.on(this.options.toggleEvent, this.openerClickHandler);
2088
2089		},
2090
2091		isOpened: function() {
2092
2093			return this.container.hasClass(this.options.menuActiveClass);
2094
2095		},
2096
2097		show: function() {
2098
2099			this.container.addClass(this.options.menuActiveClass);
2100
2101			if(this.options.hideOnClickOutside) {
2102
2103				this.page.on(this.options.outsideClickEvent, this.outsideClickHandler);
2104
2105			}
2106
2107			this.makeCallback('onInit', this);
2108
2109		},
2110
2111		hide: function() {
2112
2113			this.container.removeClass(this.options.menuActiveClass);
2114
2115			if(this.options.hideOnClickOutside) {
2116
2117				this.page.off(this.options.outsideClickEvent, this.outsideClickHandler);
2118
2119			}
2120
2121			this.makeCallback('onHide', this);
2122
2123		},
2124
2125		toggle: function() {
2126
2127			if(this.isOpened()) {
2128
2129				this.hide();
2130
2131			} else {
2132
2133				this.show();
2134
2135			}
2136
2137		},
2138
2139		makeCallback: function(name) {
2140
2141			if(typeof this.options[name] === 'function') {
2142
2143				var args = Array.prototype.slice.call(arguments);
2144
2145				args.shift();
2146
2147				this.options[name].apply(this, args);
2148
2149			}
2150
2151		},
2152
2153		destroy: function() {
2154
2155			this.container.removeClass(this.options.menuActiveClass);
2156
2157			this.opener.off(this.options.toggleEvent, this.clickHandler);
2158
2159			this.page.off(this.options.outsideClickEvent, this.outsideClickHandler);
2160
2161		}
2162
2163	};
2164
2165
2166
2167	var activateResizeHandler = function() {
2168
2169		var win = $(window),
2170
2171			doc = $('html'),
2172
2173			resizeClass = 'resize-active',
2174
2175			flag, timer;
2176
2177		var removeClassHandler = function() {
2178
2179			flag = false;
2180
2181			doc.removeClass(resizeClass);
2182
2183		};
2184
2185		var resizeHandler = function() {
2186
2187			if(!flag) {
2188
2189				flag = true;
2190
2191				doc.addClass(resizeClass);
2192
2193			}
2194
2195			clearTimeout(timer);
2196
2197			timer = setTimeout(removeClassHandler, 500);
2198
2199		};
2200
2201		win.on('resize orientationchange', resizeHandler);
2202
2203	};
2204
2205
2206
2207	$.fn.mobileNav = function(options) {
2208
2209		return this.each(function() {
2210
2211			var params = $.extend({}, options, {container: this}),
2212
2213				instance = new MobileNav(params);
2214
2215			$.data(this, 'MobileNav', instance);
2216
2217		});
2218
2219	};
2220
2221}(jQuery));
2222
2223
2224
2225/*! http://mths.be/placeholder v2.0.7 by @mathias */
2226
2227;(function(window, document, $) {
2228
2229
2230
2231	// Opera Mini v7 doesn’t support placeholder although its DOM seems to indicate so
2232
2233	var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]';
2234
2235	var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini;
2236
2237	var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini;
2238
2239	var prototype = $.fn;
2240
2241	var valHooks = $.valHooks;
2242
2243	var propHooks = $.propHooks;
2244
2245	var hooks;
2246
2247	var placeholder;
2248
2249
2250
2251	if (isInputSupported && isTextareaSupported) {
2252
2253
2254
2255		placeholder = prototype.placeholder = function() {
2256
2257			return this;
2258
2259		};
2260
2261
2262
2263		placeholder.input = placeholder.textarea = true;
2264
2265
2266
2267	} else {
2268
2269
2270
2271		placeholder = prototype.placeholder = function() {
2272
2273			var $this = this;
2274
2275			$this
2276
2277				.filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
2278
2279				.not('.placeholder')
2280
2281				.bind({
2282
2283					'focus.placeholder': clearPlaceholder,
2284
2285					'blur.placeholder': setPlaceholder
2286
2287				})
2288
2289				.data('placeholder-enabled', true)
2290
2291				.trigger('blur.placeholder');
2292
2293			return $this;
2294
2295		};
2296
2297
2298
2299		placeholder.input = isInputSupported;
2300
2301		placeholder.textarea = isTextareaSupported;
2302
2303
2304
2305		hooks = {
2306
2307			'get': function(element) {
2308
2309				var $element = $(element);
2310
2311
2312
2313				var $passwordInput = $element.data('placeholder-password');
2314
2315				if ($passwordInput) {
2316
2317					return $passwordInput[0].value;
2318
2319				}
2320
2321
2322
2323				return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
2324
2325			},
2326
2327			'set': function(element, value) {
2328
2329				var $element = $(element);
2330
2331
2332
2333				var $passwordInput = $element.data('placeholder-password');
2334
2335				if ($passwordInput) {
2336
2337					return $passwordInput[0].value = value;
2338
2339				}
2340
2341
2342
2343				if (!$element.data('placeholder-enabled')) {
2344
2345					return element.value = value;
2346
2347				}
2348
2349				if (value == '') {
2350
2351					element.value = value;
2352
2353					// Issue #56: Setting the placeholder causes problems if the element continues to have focus.
2354
2355					if (element != safeActiveElement()) {
2356
2357						// We can't use `triggerHandler` here because of dummy text/password inputs :(
2358
2359						setPlaceholder.call(element);
2360
2361					}
2362
2363				} else if ($element.hasClass('placeholder')) {
2364
2365					clearPlaceholder.call(element, true, value) || (element.value = value);
2366
2367				} else {
2368
2369					element.value = value;
2370
2371				}
2372
2373				// `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
2374
2375				return $element;
2376
2377			}
2378
2379		};
2380
2381
2382
2383		if (!isInputSupported) {
2384
2385			valHooks.input = hooks;
2386
2387			propHooks.value = hooks;
2388
2389		}
2390
2391		if (!isTextareaSupported) {
2392
2393			valHooks.textarea = hooks;
2394
2395			propHooks.value = hooks;
2396
2397		}
2398
2399
2400
2401		$(function() {
2402
2403			// Look for forms
2404
2405			$(document).delegate('form', 'submit.placeholder', function() {
2406
2407				// Clear the placeholder values so they don't get submitted
2408
2409				var $inputs = $('.placeholder', this).each(clearPlaceholder);
2410
2411				setTimeout(function() {
2412
2413					$inputs.each(setPlaceholder);
2414
2415				}, 10);
2416
2417			});
2418
2419		});
2420
2421
2422
2423		// Clear placeholder values upon page reload
2424
2425		$(window).bind('beforeunload.placeholder', function() {
2426
2427			$('.placeholder').each(function() {
2428
2429				this.value = '';
2430
2431			});
2432
2433		});
2434
2435
2436
2437	}
2438
2439
2440
2441	function args(elem) {
2442
2443		// Return an object of element attributes
2444
2445		var newAttrs = {};
2446
2447		var rinlinejQuery = /^jQuery\d+$/;
2448
2449		$.each(elem.attributes, function(i, attr) {
2450
2451			if (attr.specified && !rinlinejQuery.test(attr.name)) {
2452
2453				newAttrs[attr.name] = attr.value;
2454
2455			}
2456
2457		});
2458
2459		return newAttrs;
2460
2461	}
2462
2463
2464
2465	function clearPlaceholder(event, value) {
2466
2467		var input = this;
2468
2469		var $input = $(input);
2470
2471		if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
2472
2473			if ($input.data('placeholder-password')) {
2474
2475				$input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
2476
2477				// If `clearPlaceholder` was called from `$.valHooks.input.set`
2478
2479				if (event === true) {
2480
2481					return $input[0].value = value;
2482
2483				}
2484
2485				$input.focus();
2486
2487			} else {
2488
2489				input.value = '';
2490
2491				$input.removeClass('placeholder');
2492
2493				input == safeActiveElement() && input.select();
2494
2495			}
2496
2497		}
2498
2499	}
2500
2501
2502
2503	function setPlaceholder() {
2504
2505		var $replacement;
2506
2507		var input = this;
2508
2509		var $input = $(input);
2510
2511		var id = this.id;
2512
2513		if (input.value == '') {
2514
2515			if (input.type == 'password') {
2516
2517				if (!$input.data('placeholder-textinput')) {
2518
2519					try {
2520
2521						$replacement = $input.clone().attr({ 'type': 'text' });
2522
2523					} catch(e) {
2524
2525						$replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
2526
2527					}
2528
2529					$replacement
2530
2531						.removeAttr('name')
2532
2533						.data({
2534
2535							'placeholder-password': $input,
2536
2537							'placeholder-id': id
2538
2539						})
2540
2541						.bind('focus.placeholder', clearPlaceholder);
2542
2543					$input
2544
2545						.data({
2546
2547							'placeholder-textinput': $replacement,
2548
2549							'placeholder-id': id
2550
2551						})
2552
2553						.before($replacement);
2554
2555				}
2556
2557				$input = $input.removeAttr('id').hide().prev().attr('id', id).show();
2558
2559				// Note: `$input[0] != input` now!
2560
2561			}
2562
2563			$input.addClass('placeholder');
2564
2565			$input[0].value = $input.attr('placeholder');
2566
2567		} else {
2568
2569			$input.removeClass('placeholder');
2570
2571		}
2572
2573	}
2574
2575
2576
2577	function safeActiveElement() {
2578
2579		// Avoid IE9 `document.activeElement` of death
2580
2581		// https://github.com/mathiasbynens/jquery-placeholder/pull/99
2582
2583		try {
2584
2585			return document.activeElement;
2586
2587		} catch (err) {}
2588
2589	}
2590
2591
2592
2593}(this, document, jQuery));
2594
2595
2596
2597/*
2598
2599 * Window Height CSS rules
2600
2601 */
2602
2603;(function() {
2604
2605	var styleSheet;
2606
2607
2608
2609	var getWindowHeight = function() {
2610
2611		return window.innerHeight || document.documentElement.clientHeight;
2612
2613	};
2614
2615
2616
2617	var createStyleTag = function() {
2618
2619		// create style tag
2620
2621		var styleTag = jQuery('<style>').appendTo('head');
2622
2623		styleSheet = styleTag.prop('sheet') || styleTag.prop('styleSheet');
2624
2625
2626
2627		// crossbrowser style handling
2628
2629		var addCSSRule = function(selector, rules, index) {
2630
2631			if(styleSheet.insertRule) {
2632
2633				styleSheet.insertRule(selector + '{' + rules + '}', index);
2634
2635			} else {
2636
2637				styleSheet.addRule(selector, rules, index);
2638
2639			}
2640
2641		};
2642
2643
2644
2645		// create style rules
2646
2647		addCSSRule('.win-min-height', 'min-height:0');
2648
2649		addCSSRule('.win-height', 'height:auto');
2650
2651		addCSSRule('.win-max-height', 'max-height:100%');
2652
2653		resizeHandler();
2654
2655	};
2656
2657
2658
2659	var resizeHandler = function() {
2660
2661		// handle changes in style rules
2662
2663		var currentWindowHeight = getWindowHeight(),
2664
2665			styleRules = styleSheet.cssRules || styleSheet.rules;
2666
2667
2668
2669		jQuery.each(styleRules, function(index, currentRule) {
2670
2671			var currentProperty = currentRule.selectorText.toLowerCase().replace('.win-', '').replace('-h','H');
2672
2673			currentRule.style[currentProperty] = currentWindowHeight + 'px';
2674
2675		});
2676
2677	};
2678
2679
2680
2681	createStyleTag();
2682
2683	jQuery(window).on('resize orientationchange', resizeHandler);
2684
2685}());
2686
2687
2688
2689
2690
2691;(function($){
2692
2693	function ParallaxBG(opt) {
2694
2695		this.options = $.extend({
2696
2697			parent: '.bg-frame',
2698
2699			image: 'img',
2700
2701			parallaxOffset: 100,
2702
2703			fallbackFunc: function() {}
2704
2705		}, opt);
2706
2707		this.init();
2708
2709	}
2710
2711	ParallaxBG.prototype = {
2712
2713		init: function() {
2714
2715			if(this.options.holder) {
2716
2717				if(typeof this.options.fallbackFunc == 'function' && (oldIe || isTouchDevice)) {
2718
2719					this.options.fallbackFunc();
2720
2721					return;
2722
2723				}
2724
2725				this.getStructure();
2726
2727				this.attachEvents();
2728
2729			}
2730
2731		},
2732
2733		getStructure: function() {
2734
2735			this.holder = $(this.options.holder);
2736
2737			this.parent = this.holder.find(this.options.parent);
2738
2739			this.holderHeight = this.holder.height();
2740
2741			this.holderOffset = this.holder.offset().top;
2742
2743
2744
2745			// generate bg
2746
2747			this.image = this.parent.find(this.options.image).eq(0).css({visibility: 'hidden'});
2748
2749			this.imageRatio = this.image.attr('width')/this.image.attr('height') || this.image.width()/this.image.height();
2750
2751
2752
2753			this.parent.css({
2754
2755				backgroundImage: 'url('+this.image.attr('src')+')',
2756
2757				backgroundRepeat: 'no-repeat',
2758
2759				backgroundAttachment: 'fixed'
2760
2761			});
2762
2763
2764
2765			this.win = $(window);
2766
2767			this.winHeight = this.win.height();
2768
2769			this.winWidth = this.win.width();
2770
2771			this.winScroll = this.win.scrollTop();
2772
2773			this.bgHeight = this.winHeight + this.options.parallaxOffset;
2774
2775		},
2776
2777		attachEvents: function() {
2778
2779			var self = this;
2780
2781			this.bindHandlers(['scrollLayout']);
2782
2783			this.bindHandlers(['resizeLayout']);
2784
2785			this.win.bind('scroll', this.scrollLayout).bind('resize load', this.resizeLayout);
2786
2787
2788
2789			// fix load problem
2790
2791			setTimeout(function() {
2792
2793				self.resizeLayout();
2794
2795				self.win.trigger('scroll');
2796
2797			}, 500);
2798
2799		},
2800
2801		resizeLayout: function() {
2802
2803			// get dimensions
2804
2805			this.winHeight = this.win.height();
2806
2807			this.winWidth = this.win.width();
2808
2809			this.holderHeight = this.holder.height();
2810
2811			this.holderOffset = this.holder.offset().top;
2812
2813
2814
2815			this.blockHeight = this.winHeight + this.options.parallaxOffset;
2816
2817			this.currentTop = Math.max(0, this.blockHeight - this.holderHeight);
2818
2819
2820
2821			// get parallax ratio and image ratio state
2822
2823			this.parallaxRatio = this.win.width()/(this.winHeight + this.options.parallaxOffset);
2824
2825			this.ratioState = this.imageRatio <= this.parallaxRatio;
2826
2827
2828
2829			if(this.ratioState) {
2830
2831				this.bgWidth = this.winWidth;
2832
2833				this.bgHeight = this.bgWidth/this.imageRatio;
2834
2835			} else {
2836
2837				this.bgWidth = 'auto';
2838
2839				this.bgHeight = this.winHeight + this.options.parallaxOffset;
2840
2841			}
2842
2843
2844
2845			this.parent.css({
2846
2847				paddingBottom: this.currentTop,
2848
2849				backgroundSize: this.bgWidth != 'auto' ? this.bgWidth +'px '+this.bgHeight+'px' : this.bgWidth +' '+this.bgHeight+'px'
2850
2851			});
2852
2853			this.scrollLayout();
2854
2855		},
2856
2857		scrollLayout: function() {
2858
2859			this.winScroll = this.win.scrollTop();
2860
2861			this.offsetPercentage = Math.max(0, Math.min((this.winScroll + this.winHeight - this.holderOffset)/(this.winHeight + this.holderHeight), 1)).toFixed(4);
2862
2863
2864
2865			if(!!this.ratioState) {
2866
2867				var curPos = '50% ' + ((-parseFloat(this.offsetPercentage)*this.options.parallaxOffset) - (this.bgHeight - this.winHeight)/2)+'px';
2868
2869			} else {
2870
2871				var curPos = '50% ' + (-parseFloat(this.offsetPercentage)*this.options.parallaxOffset)+'px';
2872
2873			}
2874
2875
2876
2877			this.parent.css({backgroundPosition: curPos});
2878
2879		},
2880
2881		bindHandlers: function(handlersList) {
2882
2883			var self = this;
2884
2885			$.each(handlersList, function(index, handler) {
2886
2887				var origHandler = self[handler];
2888
2889				self[handler] = function() {
2890
2891					return origHandler.apply(self, arguments);
2892
2893				};
2894
2895			});
2896
2897		}
2898
2899	};
2900
2901
2902
2903	// detect device type
2904
2905	var isTouchDevice = /MSIE 10.*Touch/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
2906
2907	var oldIe = window.attachEvent && !window.addEventListener;
2908
2909
2910
2911	// jquery parallax plugin
2912
2913	$.fn.parallaxBG = function(opt){
2914
2915		return this.each(function(){
2916
2917			new ParallaxBG($.extend(opt,{holder:this}));
2918
2919		});
2920
2921	};
2922
2923}(jQuery));
2924
2925
2926
2927// background stretching
2928
2929function initBgStretch() {
2930
2931	jQuery('.bg-frame').each(function() {
2932
2933		var holder = jQuery(this);
2934
2935		var image = holder.find('img');
2936
2937		jQuery(window).bind('load resize', function() {
2938
2939			var settings = getProportions(getDimensions(image, holder));
2940
2941			resizeAll(image, settings);
2942
2943		});
2944
2945	});
2946
2947
2948
2949	function getProportions(dimensions) {
2950
2951		var ratio = dimensions.ratio || (dimensions.elementWidth / dimensions.elementHeight);
2952
2953		var slideWidth = dimensions.maskWidth, slideHeight = slideWidth / ratio;
2954
2955		if(slideHeight < dimensions.maskHeight) {
2956
2957			slideHeight = dimensions.maskHeight;
2958
2959			slideWidth = slideHeight * ratio;
2960
2961		}
2962
2963		return {
2964
2965			width: slideWidth,
2966
2967			height: slideHeight,
2968
2969			top: (dimensions.maskHeight - slideHeight) / 2,
2970
2971			left: (dimensions.maskWidth - slideWidth) / 2
2972
2973		}
2974
2975	}
2976
2977
2978
2979	function getDimensions(img, block) {
2980
2981		img.css({
2982
2983			height: '',
2984
2985			left: '',
2986
2987			top: '',
2988
2989			width: ''
2990
2991		});
2992
2993		return {
2994
2995			ratio: img.width()/img.height(),
2996
2997			maskWidth: block.width(),
2998
2999			maskHeight: block.outerHeight(true)
3000
3001		};
3002
3003	}
3004
3005
3006
3007	function resizeAll(img, obj) {
3008
3009		img.css({
3010
3011			height: obj.height,
3012
3013			left: obj.left,
3014
3015			top: obj.top,
3016
3017			width: obj.width
3018
3019		});
3020
3021	}
3022
3023}
3024
3025
3026
3027
3028
3029/*
3030
3031 * Image Stretch module
3032
3033 */
3034
3035var ImageStretcher = {
3036
3037	getDimensions: function(data) {
3038
3039		// calculate element coords to fit in mask
3040
3041		var ratio = data.imageRatio || (data.imageWidth / data.imageHeight),
3042
3043			slideWidth = data.maskWidth,
3044
3045			slideHeight = slideWidth / ratio;
3046
3047
3048
3049		if(slideHeight < data.maskHeight) {
3050
3051			slideHeight = data.maskHeight;
3052
3053			slideWidth = slideHeight * ratio;
3054
3055		}
3056
3057		return {
3058
3059			width: slideWidth,
3060
3061			height: slideHeight,
3062
3063			top: (data.maskHeight - slideHeight) / 2,
3064
3065			left: (data.maskWidth - slideWidth) / 2
3066
3067		};
3068
3069	},
3070
3071	getRatio: function(image) {
3072
3073		if(image.prop('naturalWidth')) {
3074
3075			return image.prop('naturalWidth') / image.prop('naturalHeight');
3076
3077		} else {
3078
3079			var img = new Image();
3080
3081			img.src = image.prop('src');
3082
3083			return img.width / img.height;
3084
3085		}
3086
3087	},
3088
3089	imageLoaded: function(image, callback) {
3090
3091		var self = this;
3092
3093		var loadHandler = function() {
3094
3095			callback.call(self);
3096
3097		};
3098
3099		if(image.prop('complete')) {
3100
3101			loadHandler();
3102
3103		} else {
3104
3105			image.one('load', loadHandler);
3106
3107		}
3108
3109	},
3110
3111	resizeHandler: function() {
3112
3113		var self = this;
3114
3115		jQuery.each(this.imgList, function(index, item) {
3116
3117			if(item.image.prop('complete')) {
3118
3119				self.resizeImage(item.image, item.container);
3120
3121			}
3122
3123		});
3124
3125	},
3126
3127	resizeImage: function(image, container) {
3128
3129		this.imageLoaded(image, function() {
3130
3131			var styles = this.getDimensions({
3132
3133				imageRatio: this.getRatio(image),
3134
3135				maskWidth: container.width(),
3136
3137				maskHeight: container.height()
3138
3139			});
3140
3141			image.css({
3142
3143				width: styles.width,
3144
3145				height: styles.height,
3146
3147				marginTop: styles.top,
3148
3149				marginLeft: styles.left
3150
3151			});
3152
3153		});
3154
3155	},
3156
3157	add: function(options) {
3158
3159		var container = jQuery(options.container ? options.container : window),
3160
3161			image = typeof options.image === 'string' ? container.find(options.image) : jQuery(options.image);
3162
3163
3164
3165		// resize image
3166
3167		this.resizeImage(image, container);
3168
3169
3170
3171		// add resize handler once if needed
3172
3173		if(!this.win) {
3174
3175			this.resizeHandler = jQuery.proxy(this.resizeHandler, this);
3176
3177			this.imgList = [];
3178
3179			this.win = jQuery(window);
3180
3181			this.win.on('resize orientationchange', this.resizeHandler);
3182
3183		}
3184
3185
3186
3187		// store item in collection
3188
3189		this.imgList.push({
3190
3191			container: container,
3192
3193			image: image
3194
3195		});
3196
3197	}
3198
3199};
3200
3201
3202
3203/*
3204
3205 * jQuery SlideShow plugin
3206
3207 */
3208
3209;(function($){function FadeGallery(options) {this.options = $.extend({slides: 'ul.slideset > li',activeClass:'active',disabledClass:'disabled',btnPrev: 'a.btn-prev',btnNext: 'a.btn-next',generatePagination: false,pagerList: '<ul>',pagerListItem: '<li><a href="#"></a></li>',pagerListItemText: 'a',pagerLinks: '.pagination li',currentNumber: 'span.current-num',totalNumber: 'span.total-num',btnPlay: '.btn-play',btnPause: '.btn-pause',btnPlayPause: '.btn-play-pause',galleryReadyClass: 'gallery-js-ready',autorotationActiveClass: 'autorotation-active',autorotationDisabledClass: 'autorotation-disabled',autorotationStopAfterClick: false,circularRotation: true,switchSimultaneously: true,disableWhileAnimating: false,disableFadeIE: false,autoRotation: false,pauseOnHover: false,autoHeight: false,useSwipe: false,swipeThreshold: 15,switchTime: 4000,animSpeed: 600,event:'click'}, options);this.init();}FadeGallery.prototype = {init: function() {if(this.options.holder) {this.findElements();this.attachEvents();this.refreshState(true);this.autoRotate();this.makeCallback('onInit', this);}},findElements: function() {this.gallery = $(this.options.holder).addClass(this.options.galleryReadyClass);this.slides = this.gallery.find(this.options.slides);this.slidesHolder = this.slides.eq(0).parent();this.stepsCount = this.slides.length;this.btnPrev = this.gallery.find(this.options.btnPrev);this.btnNext = this.gallery.find(this.options.btnNext);this.currentIndex = 0;
3209if(this.options.disableFadeIE && !$.support.opacity) {this.options.animSpeed = 0;}if(typeof this.options.generatePagination === 'string') {this.pagerHolder = this.gallery.find(this.options.generatePagination).empty();this.pagerList = $(this.options.pagerList).appendTo(this.pagerHolder);for(var i = 0; i < this.stepsCount; i++) {$(this.options.pagerListItem).appendTo(this.pagerList).find(this.options.pagerListItemText).text(i+1);}this.pagerLinks = this.pagerList.children();} else {this.pagerLinks = this.gallery.find(this.options.pagerLinks);}var activeSlide = this.slides.filter('.'+this.options.activeClass);if(activeSlide.length) {this.currentIndex = this.slides.index(activeSlide);}this.prevIndex = this.currentIndex;this.btnPlay = this.gallery.find(this.options.btnPlay);this.btnPause = this.gallery.find(this.options.btnPause);this.btnPlayPause = this.gallery.find(this.options.btnPlayPause);this.curNum = this.gallery.find(this.options.currentNumber);this.allNum = this.gallery.find(this.options.totalNumber);this.slides.css({display:'block',opacity:0}
3209).eq(this.currentIndex).css({opacity:''});},updateAttributes: function() {if(this.holder.attr('data-rotate') === 'true') {this.options.autoRotation = true;}if(this.holder.attr('data-direction') === 'vertical') {this.options.vertical = true;}if(this.holder.attr('data-pause-hover') === 'true') {this.options.pauseOnHover = true;}if(this.holder.attr('data-speed')) {this.options.animSpeed = parseFloat(this.holder.attr('data-speed'));}},attachEvents: function() {var self = this;this.resizeHandler = function() {self.onWindowResize();};$(window).bind('load resize orientationchange', this.resizeHandler);if(this.btnPrev.length) {this.btnPrevHandler = function(e){e.preventDefault();self.prevSlide();if(self.options.autorotationStopAfterClick) {self.stopRotation();}};this.btnPrev.bind(this.options.event, this.btnPrevHandler);}if(this.btnNext.length) {this.btnNextHandler = function(e) {e.preventDefault();self.nextSlide();if(self.options.autorotationStopAfterClick) {self.stopRotation();}};this.btnNext.bind(this.options.event, this.btnNextHandler);}if(this.pagerLinks.length) {this.pagerLinksHandler = function(e) {e.preventDefault();self.numSlide(self.pagerLinks.index(e.currentTarget));if(self.options.autorotationStopAfterClick) {self.stopRotation();}};this.pagerLinks.bind(self.options.event, this.pagerLinksHandler);}if(this.btnPlay.length) {this.btnPlayHandler = function(e) {e.preventDefault();self.startRotation();};this.btnPlay.bind(this.options.event, this.btnPlayHandler);}if(this.btnPause.length) {this.btnPauseHandler = function(e) {e.preventDefault();self.stopRotation();};this.btnPause.bind(this.options.event, this.btnPauseHandler);}if(this.btnPlayPause.length) {this.btnPlayPauseHandler = function(e){e.preventDefault();if(!self.gallery.hasClass(self.options.autorotationActiveClass)) {self.startRotation();} else {self.stopRotation();}};this.btnPlayPause.bind(this.options.event, this.btnPlayPauseHandler);}if(this.options.useSwipe && window.Hammer && isTouchDevice) {this.swipeHandler = new Hammer.Manager(this.gallery[0]);this.swipeHandler.add(new Hammer.Swipe({direction: Hammer.DIRECTION_HORIZONTAL,threshold: self.options.swipeThreshold}));this.swipeHandler.on('swipeleft', function() {self.nextSlide();}).on('swiperight', function() {self.prevSlide();});}if(this.options.pauseOnHover) {this.hoverHandler = function() {if(self.options.autoRotation) {self.galleryHover = true;self.pauseRotation();}};this.leaveHandler = function() {if(self.options.autoRotation) {self.galleryHover = false;self.resumeRotation();}};this.gallery.bind({mouseenter: this.hoverHandler, mouseleave: this.leaveHandler});}},onWindowResize: function(){if(this.options.autoHeight) {this.slidesHolder.css({height: this.slides.eq(this.currentIndex).outerHeight(true) });}},prevSlide: function() {if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {this.prevIndex = this.currentIndex;if(this.currentIndex > 0) {this.currentIndex--;this.switchSlide();} else if(this.options.circularRotation) {this.currentIndex = this.stepsCount - 1;this.switchSlide();}}},nextSlide: function(fromAutoRotation) {if(!(this.options.disableWhileAnimating && this.galleryAnimating)) {this.prevIndex = this.currentIndex;if(this.currentIndex < this.stepsCount - 1) {this.currentIndex++;this.switchSlide();} else if(this.options.circularRotation || fromAutoRotation === true) {this.currentIndex = 0;this.switchSlide();}}},numSlide: function(c) {if(this.currentIndex != c) {this.prevIndex = this.currentIndex;this.currentIndex = c;this.switchSlide();}},switchSlide: function() {var self = this;var oldSlide = this.slides.eq(this.prevIndex);var newSlide = this.slides.eq(this.currentIndex);self.hideContent();this.animating = true;if(this.slides.length > 1) {this.galleryAnimating = true;if(!this.options.animSpeed) {this.slides.eq(this.prevIndex).css({opacity:0});} else {this.slides.eq(this.prevIndex).stop().animate({opacity:0}
3209,{duration: this.options.animSpeed});}this.switchNext = function() {if(!self.options.animSpeed) {self.slides.eq(self.currentIndex).css({opacity:''});} else {self.slides.eq(self.currentIndex).stop().animate({opacity:1},{duration: self.options.animSpeed});}clearTimeout(this.nextTimer);this.nextTimer = setTimeout(function() {self.showContent();self.slides.eq(self.currentIndex).css({opacity:''});self.galleryAnimating = false;self.autoRotate();self.makeCallback('onChange', self);}, self.options.animSpeed);};if(this.options.switchSimultaneously) {self.switchNext();} else {clearTimeout(this.switchTimer);this.switchTimer = setTimeout(function(){self.switchNext();}, this.options.animSpeed);}this.refreshState();this.makeCallback('onBeforeChange', this);}},hideContent: function() {$(this.slides.eq(this.currentIndex)).find('.heading').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);$(this.slides.eq(this.currentIndex)).find('.btn-box').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);$(this.slides.eq(this.currentIndex)).find('.txt').css({position: 'relative'}).animate({bottom: -50,opacity: 0}, 500);},showContent: function() {$(this.slides.eq(this.currentIndex)).find('.heading').animate({bottom: 0,opacity: 1}, 700);$(this.slides.eq(this.currentIndex)).find('.btn-box').animate({bottom: 0,opacity: 1}, 700);$(this.slides.eq(this.currentIndex)).find('.txt').animate({bottom: 0,opacity: 1}, 700);},refreshState: function(initial) {this.slides.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);this.pagerLinks.removeClass(this.options.activeClass).eq(this.currentIndex).addClass(this.options.activeClass);this.curNum.html(this.currentIndex+1);this.allNum.html(this.stepsCount);if(this.options.autoHeight) {if(initial) {this.slidesHolder.css({height: this.slides.eq(this.currentIndex).outerHeight(true) });} else {this.slidesHolder.stop().animate({height: this.slides.eq(this.currentIndex).outerHeight(true)}, {duration: this.options.animSpeed});}}if(!this.options.circularRotation) {this.btnPrev.add(this.btnNext).removeClass(this.options.disabledClass);if(this.currentIndex === 0) this.btnPrev.addClass(this.options.disabledClass);if(this.currentIndex === this.stepsCount - 1) this.btnNext.addClass(this.options.disabledClass);}this.gallery.toggleClass('not-enough-slides', this.stepsCount === 1);},startRotation: function() {this.options.autoRotation = true;this.galleryHover = false;this.autoRotationStopped = false;this.resumeRotation();},stopRotation: function() {this.galleryHover = true;this.autoRotationStopped = true;this.pauseRotation();},pauseRotation: function() {this.gallery.addClass(this.options.autorotationDisabledClass);this.gallery.removeClass(this.options.autorotationActiveClass);clearTimeout(this.timer);},resumeRotation: function() {if(!this.autoRotationStopped) {this.gallery.addClass(this.options.autorotationActiveClass);this.gallery.removeClass(this.options.autorotationDisabledClass);this.autoRotate();}},autoRotate: function() {var self = this;clearTimeout(this.timer);if(this.options.autoRotation && !this.galleryHover && !this.autoRotationStopped) {this.gallery.addClass(this.options.autorotationActiveClass);this.timer = setTimeout(function(){self.nextSlide(true);}, this.options.switchTime);} else {this.pauseRotation();}},makeCallback: function(name) {if(typeof this.options[name] === 'function') {var args = Array.prototype.slice.call(arguments);args.shift();this.options[name].apply(this, args);}}};var isTouchDevice = /Windows Phone/.test(navigator.userAgent) || ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;$.fn.fadeGallery = function(opt){return this.each(function(){$(this).data('FadeGallery', new FadeGallery($.extend(opt,{holder:this})));});};}(jQuery));
3210
3211
3212
3213/*!
3214
3215 * JavaScript Custom Forms
3216
3217 *
3218
3219 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
3220
3221 * Released under the MIT license (LICENSE.txt)
3222
3223 *
3224
3225 * Version: 1.1.3
3226
3227 */
3228
3229;(function(root, factory) {
3230
3231	'use strict';
3232
3233	if (typeof define === 'function' && define.amd) {
3234
3235		define(['jquery'], factory);
3236
3237	} else if (typeof exports === 'object') {
3238
3239		module.exports = factory(require('jquery'));
3240
3241	} else {
3242
3243		root.jcf = factory(jQuery);
3244
3245	}
3246
3247}
3248
3249(this, function($) {
3250
3251	'use strict';
3252
3253
3254
3255	// define version
3256
3257	var version = '1.1.3';
3258
3259
3260
3261	// private variables
3262
3263	var customInstances = [];
3264
3265
3266
3267	// default global options
3268
3269	var commonOptions = {
3270
3271		optionsKey: 'jcf',
3272
3273		dataKey: 'jcf-instance',
3274
3275		rtlClass: 'jcf-rtl',
3276
3277		focusClass: 'jcf-focus',
3278
3279		pressedClass: 'jcf-pressed',
3280
3281		disabledClass: 'jcf-disabled',
3282
3283		hiddenClass: 'jcf-hidden',
3284
3285		resetAppearanceClass: 'jcf-reset-appearance',
3286
3287		unselectableClass: 'jcf-unselectable'
3288
3289	};
3290
3291
3292
3293	// detect device type
3294
3295	var isTouchDevice = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch,
3296
3297		isWinPhoneDevice = /Windows Phone/.test(navigator.userAgent);
3298
3299	commonOptions.isMobileDevice = !!(isTouchDevice || isWinPhoneDevice);
3300
3301
3302
3303	// create global stylesheet if custom forms are used
3304
3305	var createStyleSheet = function() {
3306
3307		var styleTag = $('<style>').appendTo('head'),
3308
3309			styleSheet = styleTag.prop('sheet') || styleTag.prop('styleSheet');
3310
3311
3312
3313		// crossbrowser style handling
3314
3315		var addCSSRule = function(selector, rules, index) {
3316
3317			if (styleSheet.insertRule) {
3318
3319				styleSheet.insertRule(selector + '{' + rules + '}', index);
3320
3321			} else {
3322
3323				styleSheet.addRule(selector, rules, index);
3324
3325			}
3326
3327		};
3328
3329
3330
3331		// add special rules
3332
3333		addCSSRule('.' + commonOptions.hiddenClass, 'position:absolute !important;left:-9999px !important;height:1px !important;width:1px !important;margin:0 !important;border-width:0 !important;-webkit-appearance:none;-moz-appearance:none;appearance:none');
3334
3335		addCSSRule('.' + commonOptions.rtlClass + ' .' + commonOptions.hiddenClass, 'right:-9999px !important; left: auto !important');
3336
3337		addCSSRule('.' + commonOptions.unselectableClass, '-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0);');
3338
3339		addCSSRule('.' + commonOptions.resetAppearanceClass, 'background: none; border: none; -webkit-appearance: none; appearance: none; opacity: 0; filter: alpha(opacity=0);');
3340
3341
3342
3343		// detect rtl pages
3344
3345		var html = $('html'), body = $('body');
3346
3347		if (html.css('direction') === 'rtl' || body.css('direction') === 'rtl') {
3348
3349			html.addClass(commonOptions.rtlClass);
3350
3351		}
3352
3353
3354
3355		// handle form reset event
3356
3357		html.on('reset', function() {
3358
3359			setTimeout(function() {
3360
3361				api.refreshAll();
3362
3363			}, 0);
3364
3365		});
3366
3367
3368
3369		// mark stylesheet as created
3370
3371		commonOptions.styleSheetCreated = true;
3372
3373	};
3374
3375
3376
3377	// simplified pointer events handler
3378
3379	(function() {
3380
3381		var pointerEventsSupported = navigator.pointerEnabled || navigator.msPointerEnabled,
3382
3383			touchEventsSupported = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch,
3384
3385			eventList, eventMap = {}, eventPrefix = 'jcf-';
3386
3387
3388
3389		// detect events to attach
3390
3391		if (pointerEventsSupported) {
3392
3393			eventList = {
3394
3395				pointerover: navigator.pointerEnabled ? 'pointerover' : 'MSPointerOver',
3396
3397				pointerdown: navigator.pointerEnabled ? 'pointerdown' : 'MSPointerDown',
3398
3399				pointermove: navigator.pointerEnabled ? 'pointermove' : 'MSPointerMove',
3400
3401				pointerup: navigator.pointerEnabled ? 'pointerup' : 'MSPointerUp'
3402
3403			};
3404
3405		} else {
3406
3407			eventList = {
3408
3409				pointerover: 'mouseover',
3410
3411				pointerdown: 'mousedown' + (touchEventsSupported ? ' touchstart' : ''),
3412
3413				pointermove: 'mousemove' + (touchEventsSupported ? ' touchmove' : ''),
3414
3415				pointerup: 'mouseup' + (touchEventsSupported ? ' touchend' : '')
3416
3417			};
3418
3419		}
3420
3421
3422
3423		// create event map
3424
3425		$.each(eventList, function(targetEventName, fakeEventList) {
3426
3427			$.each(fakeEventList.split(' '), function(index, fakeEventName) {
3428
3429				eventMap[fakeEventName] = targetEventName;
3430
3431			});
3432
3433		});
3434
3435
3436
3437		// jQuery event hooks
3438
3439		$.each(eventList, function(eventName, eventHandlers) {
3440
3441			eventHandlers = eventHandlers.split(' ');
3442
3443			$.event.special[eventPrefix + eventName] = {
3444
3445				setup: function() {
3446
3447					var self = this;
3448
3449					$.each(eventHandlers, function(index, fallbackEvent) {
3450
3451						if (self.addEventListener) self.addEventListener(fallbackEvent, fixEvent, false);
3452
3453						else self['on' + fallbackEvent] = fixEvent;
3454
3455					});
3456
3457				},
3458
3459				teardown: function() {
3460
3461					var self = this;
3462
3463					$.each(eventHandlers, function(index, fallbackEvent) {
3464
3465						if (self.addEventListener) self.removeEventListener(fallbackEvent, fixEvent, false);
3466
3467						else self['on' + fallbackEvent] = null;
3468
3469					});
3470
3471				}
3472
3473			};
3474
3475		});
3476
3477
3478
3479		// check that mouse event are not simulated by mobile browsers
3480
3481		var lastTouch = null;
3482
3483		var mouseEventSimulated = function(e) {
3484
3485			var dx = Math.abs(e.pageX - lastTouch.x),
3486
3487				dy = Math.abs(e.pageY - lastTouch.y),
3488
3489				rangeDistance = 25;
3490
3491
3492
3493			if (dx <= rangeDistance && dy <= rangeDistance) {
3494
3495				return true;
3496
3497			}
3498
3499		};
3500
3501
3502
3503		// normalize event
3504
3505		var fixEvent = function(e) {
3506
3507			var origEvent = e || window.event,
3508
3509				touchEventData = null,
3510
3511				targetEventName = eventMap[origEvent.type];
3512
3513
3514
3515			e = $.event.fix(origEvent);
3516
3517			e.type = eventPrefix + targetEventName;
3518
3519
3520
3521			if (origEvent.pointerType) {
3522
3523				switch (origEvent.pointerType) {
3524
3525					case 2: e.pointerType = 'touch'; break;
3526
3527					case 3: e.pointerType = 'pen'; break;
3528
3529					case 4: e.pointerType = 'mouse'; break;
3530
3531					default: e.pointerType = origEvent.pointerType;
3532
3533				}
3534
3535			} else {
3536
3537				e.pointerType = origEvent.type.substr(0, 5); // "mouse" or "touch" word length
3538
3539			}
3540
3541
3542
3543			if (!e.pageX && !e.pageY) {
3544
3545				touchEventData = origEvent.changedTouches ? origEvent.changedTouches[0] : origEvent;
3546
3547				e.pageX = touchEventData.pageX;
3548
3549				e.pageY = touchEventData.pageY;
3550
3551			}
3552
3553
3554
3555			if (origEvent.type === 'touchend') {
3556
3557				lastTouch = { x: e.pageX, y: e.pageY };
3558
3559			}
3560
3561			if (e.pointerType === 'mouse' && lastTouch && mouseEventSimulated(e)) {
3562
3563				return;
3564
3565			} else {
3566
3567				return ($.event.dispatch || $.event.handle).call(this, e);
3568
3569			}
3570
3571		};
3572
3573	}());
3574
3575
3576
3577	// custom mousewheel/trackpad handler
3578
3579	(function() {
3580
3581		var wheelEvents = ('onwheel' in document || document.documentMode >= 9 ? 'wheel' : 'mousewheel DOMMouseScroll').split(' '),
3582
3583			shimEventName = 'jcf-mousewheel';
3584
3585
3586
3587		$.event.special[shimEventName] = {
3588
3589			setup: function() {
3590
3591				var self = this;
3592
3593				$.each(wheelEvents, function(index, fallbackEvent) {
3594
3595					if (self.addEventListener) self.addEventListener(fallbackEvent, fixEvent, false);
3596
3597					else self['on' + fallbackEvent] = fixEvent;
3598
3599				});
3600
3601			},
3602
3603			teardown: function() {
3604
3605				var self = this;
3606
3607				$.each(wheelEvents, function(index, fallbackEvent) {
3608
3609					if (self.addEventListener) self.removeEventListener(fallbackEvent, fixEvent, false);
3610
3611					else self['on' + fallbackEvent] = null;
3612
3613				});
3614
3615			}
3616
3617		};
3618
3619
3620
3621		var fixEvent = function(e) {
3622
3623			var origEvent = e || window.event;
3624
3625			e = $.event.fix(origEvent);
3626
3627			e.type = shimEventName;
3628
3629
3630
3631			// old wheel events handler
3632
3633			if ('detail'      in origEvent) { e.deltaY = -origEvent.detail;      }
3634
3635			if ('wheelDelta'  in origEvent) { e.deltaY = -origEvent.wheelDelta;  }
3636
3637			if ('wheelDeltaY' in origEvent) { e.deltaY = -origEvent.wheelDeltaY; }
3638
3639			if ('wheelDeltaX' in origEvent) { e.deltaX = -origEvent.wheelDeltaX; }
3640
3641
3642
3643			// modern wheel event handler
3644
3645			if ('deltaY' in origEvent) {
3646
3647				e.deltaY = origEvent.deltaY;
3648
3649			}
3650
3651			if ('deltaX' in origEvent) {
3652
3653				e.deltaX = origEvent.deltaX;
3654
3655			}
3656
3657
3658
3659			// handle deltaMode for mouse wheel
3660
3661			e.delta = e.deltaY || e.deltaX;
3662
3663			if (origEvent.deltaMode === 1) {
3664
3665				var lineHeight = 16;
3666
3667				e.delta *= lineHeight;
3668
3669				e.deltaY *= lineHeight;
3670
3671				e.deltaX *= lineHeight;
3672
3673			}
3674
3675
3676
3677			return ($.event.dispatch || $.event.handle).call(this, e);
3678
3679		};
3680
3681	}());
3682
3683
3684
3685	// extra module methods
3686
3687	var moduleMixin = {
3688
3689		// provide function for firing native events
3690
3691		fireNativeEvent: function(elements, eventName) {
3692
3693			$(elements).each(function() {
3694
3695				var element = this, eventObject;
3696
3697				if (element.dispatchEvent) {
3698
3699					eventObject = document.createEvent('HTMLEvents');
3700
3701					eventObject.initEvent(eventName, true, true);
3702
3703					element.dispatchEvent(eventObject);
3704
3705				} else if (document.createEventObject) {
3706
3707					eventObject = document.createEventObject();
3708
3709					eventObject.target = element;
3710
3711					element.fireEvent('on' + eventName, eventObject);
3712
3713				}
3714
3715			});
3716
3717		},
3718
3719		// bind event handlers for module instance (functions beggining with "on")
3720
3721		bindHandlers: function() {
3722
3723			var self = this;
3724
3725			$.each(self, function(propName, propValue) {
3726
3727				if (propName.indexOf('on') === 0 && $.isFunction(propValue)) {
3728
3729					// dont use $.proxy here because it doesn't create unique handler
3730
3731					self[propName] = function() {
3732
3733						return propValue.apply(self, arguments);
3734
3735					};
3736
3737				}
3738
3739			});
3740
3741		}
3742
3743	};
3744
3745
3746
3747	// public API
3748
3749	var api = {
3750
3751		version: version,
3752
3753		modules: {},
3754
3755		getOptions: function() {
3756
3757			return $.extend({}, commonOptions);
3758
3759		},
3760
3761		setOptions: function(moduleName, moduleOptions) {
3762
3763			if (arguments.length > 1) {
3764
3765				// set module options
3766
3767				if (this.modules[moduleName]) {
3768
3769					$.extend(this.modules[moduleName].prototype.options, moduleOptions);
3770
3771				}
3772
3773			} else {
3774
3775				// set common options
3776
3777				$.extend(commonOptions, moduleName);
3778
3779			}
3780
3781		},
3782
3783		addModule: function(proto) {
3784
3785			// add module to list
3786
3787			var Module = function(options) {
3788
3789				// save instance to collection
3790
3791				if (!options.element.data(commonOptions.dataKey)) {
3792
3793					options.element.data(commonOptions.dataKey, this);
3794
3795				}
3796
3797				customInstances.push(this);
3798
3799
3800
3801				// save options
3802
3803				this.options = $.extend({}, commonOptions, this.options, getInlineOptions(options.element), options);
3804
3805
3806
3807				// bind event handlers to instance
3808
3809				this.bindHandlers();
3810
3811
3812
3813				// call constructor
3814
3815				this.init.apply(this, arguments);
3816
3817			};
3818
3819
3820
3821			// parse options from HTML attribute
3822
3823			var getInlineOptions = function(element) {
3824
3825				var dataOptions = element.data(commonOptions.optionsKey),
3826
3827					attrOptions = element.attr(commonOptions.optionsKey);
3828
3829
3830
3831				if (dataOptions) {
3832
3833					return dataOptions;
3834
3835				} else if (attrOptions) {
3836
3837					try {
3838
3839						return $.parseJSON(attrOptions);
3840
3841					} catch (e) {
3842
3843						// ignore invalid attributes
3844
3845					}
3846
3847				}
3848
3849			};
3850
3851
3852
3853			// set proto as prototype for new module
3854
3855			Module.prototype = proto;
3856
3857
3858
3859			// add mixin methods to module proto
3860
3861			$.extend(proto, moduleMixin);
3862
3863			if (proto.plugins) {
3864
3865				$.each(proto.plugins, function(pluginName, plugin) {
3866
3867					$.extend(plugin.prototype, moduleMixin);
3868
3869				});
3870
3871			}
3872
3873
3874
3875			// override destroy method
3876
3877			var originalDestroy = Module.prototype.destroy;
3878
3879			Module.prototype.destroy = function() {
3880
3881				this.options.element.removeData(this.options.dataKey);
3882
3883
3884
3885				for (var i = customInstances.length - 1; i >= 0; i--) {
3886
3887					if (customInstances[i] === this) {
3888
3889						customInstances.splice(i, 1);
3890
3891						break;
3892
3893					}
3894
3895				}
3896
3897
3898
3899				if (originalDestroy) {
3900
3901					originalDestroy.apply(this, arguments);
3902
3903				}
3904
3905			};
3906
3907
3908
3909			// save module to list
3910
3911			this.modules[proto.name] = Module;
3912
3913		},
3914
3915		getInstance: function(element) {
3916
3917			return $(element).data(commonOptions.dataKey);
3918
3919		},
3920
3921		replace: function(elements, moduleName, customOptions) {
3922
3923			var self = this,
3924
3925				instance;
3926
3927
3928
3929			if (!commonOptions.styleSheetCreated) {
3930
3931				createStyleSheet();
3932
3933			}
3934
3935
3936
3937			$(elements).each(function() {
3938
3939				var moduleOptions,
3940
3941					element = $(this);
3942
3943
3944
3945				instance = element.data(commonOptions.dataKey);
3946
3947				if (instance) {
3948
3949					instance.refresh();
3950
3951				} else {
3952
3953					if (!moduleName) {
3954
3955						$.each(self.modules, function(currentModuleName, module) {
3956
3957							if (module.prototype.matchElement.call(module.prototype, element)) {
3958
3959								moduleName = currentModuleName;
3960
3961								return false;
3962
3963							}
3964
3965						});
3966
3967					}
3968
3969					if (moduleName) {
3970
3971						moduleOptions = $.extend({ element: element }, customOptions);
3972
3973						instance = new self.modules[moduleName](moduleOptions);
3974
3975					}
3976
3977				}
3978
3979			});
3980
3981			return instance;
3982
3983		},
3984
3985		refresh: function(elements) {
3986
3987			$(elements).each(function() {
3988
3989				var instance = $(this).data(commonOptions.dataKey);
3990
3991				if (instance) {
3992
3993					instance.refresh();
3994
3995				}
3996
3997			});
3998
3999		},
4000
4001		destroy: function(elements) {
4002
4003			$(elements).each(function() {
4004
4005				var instance = $(this).data(commonOptions.dataKey);
4006
4007				if (instance) {
4008
4009					instance.destroy();
4010
4011				}
4012
4013			});
4014
4015		},
4016
4017		replaceAll: function(context) {
4018
4019			var self = this;
4020
4021			$.each(this.modules, function(moduleName, module) {
4022
4023				$(module.prototype.selector, context).each(function() {
4024
4025					if (this.className.indexOf('jcf-ignore') < 0) {
4026
4027						self.replace(this, moduleName);
4028
4029					}
4030
4031				});
4032
4033			});
4034
4035		},
4036
4037		refreshAll: function(context) {
4038
4039			if (context) {
4040
4041				$.each(this.modules, function(moduleName, module) {
4042
4043					$(module.prototype.selector, context).each(function() {
4044
4045						var instance = $(this).data(commonOptions.dataKey);
4046
4047						if (instance) {
4048
4049							instance.refresh();
4050
4051						}
4052
4053					});
4054
4055				});
4056
4057			} else {
4058
4059				for (var i = customInstances.length - 1; i >= 0; i--) {
4060
4061					customInstances[i].refresh();
4062
4063				}
4064
4065			}
4066
4067		},
4068
4069		destroyAll: function(context) {
4070
4071			if (context) {
4072
4073				$.each(this.modules, function(moduleName, module) {
4074
4075					$(module.prototype.selector, context).each(function(index, element) {
4076
4077						var instance = $(element).data(commonOptions.dataKey);
4078
4079						if (instance) {
4080
4081							instance.destroy();
4082
4083						}
4084
4085					});
4086
4087				});
4088
4089			} else {
4090
4091				while (customInstances.length) {
4092
4093					customInstances[0].destroy();
4094
4095				}
4096
4097			}
4098
4099		}
4100
4101	};
4102
4103
4104
4105	// always export API to the global window object
4106
4107	window.jcf = api;
4108
4109
4110
4111	return api;
4112
4113}));
4114
4115
4116
4117/*!
4118
4119 * JavaScript Custom Forms : Scrollbar Module
4120
4121 *
4122
4123 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
4124
4125 * Released under the MIT license (LICENSE.txt)
4126
4127 *
4128
4129 * Version: 1.1.3
4130
4131 */
4132
4133;(function($, window) {
4134
4135	'use strict';
4136
4137
4138
4139	jcf.addModule({
4140
4141		name: 'Scrollable',
4142
4143		selector: '.jcf-scrollable',
4144
4145		plugins: {
4146
4147			ScrollBar: ScrollBar
4148
4149		},
4150
4151		options: {
4152
4153			mouseWheelStep: 150,
4154
4155			handleResize: true,
4156
4157			alwaysShowScrollbars: false,
4158
4159			alwaysPreventMouseWheel: false,
4160
4161			scrollAreaStructure: '<div class="jcf-scrollable-wrapper"></div>'
4162
4163		},
4164
4165		matchElement: function(element) {
4166
4167			return element.is('.jcf-scrollable');
4168
4169		},
4170
4171		init: function() {
4172
4173			this.initStructure();
4174
4175			this.attachEvents();
4176
4177			this.rebuildScrollbars();
4178
4179		},
4180
4181		initStructure: function() {
4182
4183			// prepare structure
4184
4185			this.doc = $(document);
4186
4187			this.win = $(window);
4188
4189			this.realElement = $(this.options.element);
4190
4191			this.scrollWrapper = $(this.options.scrollAreaStructure).insertAfter(this.realElement);
4192
4193
4194
4195			// set initial styles
4196
4197			this.scrollWrapper.css('position', 'relative');
4198
4199			this.realElement.css('overflow', 'hidden');
4200
4201			this.vBarEdge = 0;
4202
4203		},
4204
4205		attachEvents: function() {
4206
4207			// create scrollbars
4208
4209			var self = this;
4210
4211			this.vBar = new ScrollBar({
4212
4213				holder: this.scrollWrapper,
4214
4215				vertical: true,
4216
4217				onScroll: function(scrollTop) {
4218
4219					self.realElement.scrollTop(scrollTop);
4220
4221				}
4222
4223			});
4224
4225			this.hBar = new ScrollBar({
4226
4227				holder: this.scrollWrapper,
4228
4229				vertical: false,
4230
4231				onScroll: function(scrollLeft) {
4232
4233					self.realElement.scrollLeft(scrollLeft);
4234
4235				}
4236
4237			});
4238
4239
4240
4241			// add event handlers
4242
4243			this.realElement.on('scroll', this.onScroll);
4244
4245			if (this.options.handleResize) {
4246
4247				this.win.on('resize orientationchange load', this.onResize);
4248
4249			}
4250
4251
4252
4253			// add pointer/wheel event handlers
4254
4255			this.realElement.on('jcf-mousewheel', this.onMouseWheel);
4256
4257			this.realElement.on('jcf-pointerdown', this.onTouchBody);
4258
4259		},
4260
4261		onScroll: function() {
4262
4263			this.redrawScrollbars();
4264
4265		},
4266
4267		onResize: function() {
4268
4269			// do not rebuild scrollbars if form field is in focus
4270
4271			if (!$(document.activeElement).is(':input')) {
4272
4273				this.rebuildScrollbars();
4274
4275			}
4276
4277		},
4278
4279		onTouchBody: function(e) {
4280
4281			if (e.pointerType === 'touch') {
4282
4283				this.touchData = {
4284
4285					scrollTop: this.realElement.scrollTop(),
4286
4287					scrollLeft: this.realElement.scrollLeft(),
4288
4289					left: e.pageX,
4290
4291					top: e.pageY
4292
4293				};
4294
4295				this.doc.on({
4296
4297					'jcf-pointermove': this.onMoveBody,
4298
4299					'jcf-pointerup': this.onReleaseBody
4300
4301				});
4302
4303			}
4304
4305		},
4306
4307		onMoveBody: function(e) {
4308
4309			var targetScrollTop,
4310
4311				targetScrollLeft,
4312
4313				verticalScrollAllowed = this.verticalScrollActive,
4314
4315				horizontalScrollAllowed = this.horizontalScrollActive;
4316
4317
4318
4319			if (e.pointerType === 'touch') {
4320
4321				targetScrollTop = this.touchData.scrollTop - e.pageY + this.touchData.top;
4322
4323				targetScrollLeft = this.touchData.scrollLeft - e.pageX + this.touchData.left;
4324
4325
4326
4327				// check that scrolling is ended and release outer scrolling
4328
4329				if (this.verticalScrollActive && (targetScrollTop < 0 || targetScrollTop > this.vBar.maxValue)) {
4330
4331					verticalScrollAllowed = false;
4332
4333				}
4334
4335				if (this.horizontalScrollActive && (targetScrollLeft < 0 || targetScrollLeft > this.hBar.maxValue)) {
4336
4337					horizontalScrollAllowed = false;
4338
4339				}
4340
4341
4342
4343				this.realElement.scrollTop(targetScrollTop);
4344
4345				this.realElement.scrollLeft(targetScrollLeft);
4346
4347
4348
4349				if (verticalScrollAllowed || horizontalScrollAllowed) {
4350
4351					e.preventDefault();
4352
4353				} else {
4354
4355					this.onReleaseBody(e);
4356
4357				}
4358
4359			}
4360
4361		},
4362
4363		onReleaseBody: function(e) {
4364
4365			if (e.pointerType === 'touch') {
4366
4367				delete this.touchData;
4368
4369				this.doc.off({
4370
4371					'jcf-pointermove': this.onMoveBody,
4372
4373					'jcf-pointerup': this.onReleaseBody
4374
4375				});
4376
4377			}
4378
4379		},
4380
4381		onMouseWheel: function(e) {
4382
4383			var currentScrollTop = this.realElement.scrollTop(),
4384
4385				currentScrollLeft = this.realElement.scrollLeft(),
4386
4387				maxScrollTop = this.realElement.prop('scrollHeight') - this.embeddedDimensions.innerHeight,
4388
4389				maxScrollLeft = this.realElement.prop('scrollWidth') - this.embeddedDimensions.innerWidth,
4390
4391				extraLeft, extraTop, preventFlag;
4392
4393
4394
4395			// check edge cases
4396
4397			if (!this.options.alwaysPreventMouseWheel) {
4398
4399				if (this.verticalScrollActive && e.deltaY) {
4400
4401					if (!(currentScrollTop <= 0 && e.deltaY < 0) && !(currentScrollTop >= maxScrollTop && e.deltaY > 0)) {
4402
4403						preventFlag = true;
4404
4405					}
4406
4407				}
4408
4409				if (this.horizontalScrollActive && e.deltaX) {
4410
4411					if (!(currentScrollLeft <= 0 && e.deltaX < 0) && !(currentScrollLeft >= maxScrollLeft && e.deltaX > 0)) {
4412
4413						preventFlag = true;
4414
4415					}
4416
4417				}
4418
4419				if (!this.verticalScrollActive && !this.horizontalScrollActive) {
4420
4421					return;
4422
4423				}
4424
4425			}
4426
4427
4428
4429			// prevent default action and scroll item
4430
4431			if (preventFlag || this.options.alwaysPreventMouseWheel) {
4432
4433				e.preventDefault();
4434
4435			} else {
4436
4437				return;
4438
4439			}
4440
4441
4442
4443			extraLeft = e.deltaX / 100 * this.options.mouseWheelStep;
4444
4445			extraTop = e.deltaY / 100 * this.options.mouseWheelStep;
4446
4447
4448
4449			this.realElement.scrollTop(currentScrollTop + extraTop);
4450
4451			this.realElement.scrollLeft(currentScrollLeft + extraLeft);
4452
4453		},
4454
4455		setScrollBarEdge: function(edgeSize) {
4456
4457			this.vBarEdge = edgeSize || 0;
4458
4459			this.redrawScrollbars();
4460
4461		},
4462
4463		saveElementDimensions: function() {
4464
4465			this.savedDimensions = {
4466
4467				top: this.realElement.width(),
4468
4469				left: this.realElement.height()
4470
4471			};
4472
4473			return this;
4474
4475		},
4476
4477		restoreElementDimensions: function() {
4478
4479			if (this.savedDimensions) {
4480
4481				this.realElement.css({
4482
4483					width: this.savedDimensions.width,
4484
4485					height: this.savedDimensions.height
4486
4487				});
4488
4489			}
4490
4491			return this;
4492
4493		},
4494
4495		saveScrollOffsets: function() {
4496
4497			this.savedOffsets = {
4498
4499				top: this.realElement.scrollTop(),
4500
4501				left: this.realElement.scrollLeft()
4502
4503			};
4504
4505			return this;
4506
4507		},
4508
4509		restoreScrollOffsets: function() {
4510
4511			if (this.savedOffsets) {
4512
4513				this.realElement.scrollTop(this.savedOffsets.top);
4514
4515				this.realElement.scrollLeft(this.savedOffsets.left);
4516
4517			}
4518
4519			return this;
4520
4521		},
4522
4523		getContainerDimensions: function() {
4524
4525			// save current styles
4526
4527			var desiredDimensions,
4528
4529				currentStyles,
4530
4531				currentHeight,
4532
4533				currentWidth;
4534
4535
4536
4537			if (this.isModifiedStyles) {
4538
4539				desiredDimensions = {
4540
4541					width: this.realElement.innerWidth() + this.vBar.getThickness(),
4542
4543					height: this.realElement.innerHeight() + this.hBar.getThickness()
4544
4545				};
4546
4547			} else {
4548
4549				// unwrap real element and measure it according to CSS
4550
4551				this.saveElementDimensions().saveScrollOffsets();
4552
4553				this.realElement.insertAfter(this.scrollWrapper);
4554
4555				this.scrollWrapper.detach();
4556
4557
4558
4559				// measure element
4560
4561				currentStyles = this.realElement.prop('style');
4562
4563				currentWidth = parseFloat(currentStyles.width);
4564
4565				currentHeight = parseFloat(currentStyles.height);
4566
4567
4568
4569				// reset styles if needed
4570
4571				if (this.embeddedDimensions && currentWidth && currentHeight) {
4572
4573					this.isModifiedStyles |= (currentWidth !== this.embeddedDimensions.width || currentHeight !== this.embeddedDimensions.height);
4574
4575					this.realElement.css({
4576
4577						overflow: '',
4578
4579						width: '',
4580
4581						height: ''
4582
4583					});
4584
4585				}
4586
4587
4588
4589				// calculate desired dimensions for real element
4590
4591				desiredDimensions = {
4592
4593					width: this.realElement.outerWidth(),
4594
4595					height: this.realElement.outerHeight()
4596
4597				};
4598
4599
4600
4601				// restore structure and original scroll offsets
4602
4603				this.scrollWrapper.insertAfter(this.realElement);
4604
4605				this.realElement.css('overflow', 'hidden').prependTo(this.scrollWrapper);
4606
4607				this.restoreElementDimensions().restoreScrollOffsets();
4608
4609			}
4610
4611
4612
4613			return desiredDimensions;
4614
4615		},
4616
4617		getEmbeddedDimensions: function(dimensions) {
4618
4619			// handle scrollbars cropping
4620
4621			var fakeBarWidth = this.vBar.getThickness(),
4622
4623				fakeBarHeight = this.hBar.getThickness(),
4624
4625				paddingWidth = this.realElement.outerWidth() - this.realElement.width(),
4626
4627				paddingHeight = this.realElement.outerHeight() - this.realElement.height(),
4628
4629				resultDimensions;
4630
4631
4632
4633			if (this.options.alwaysShowScrollbars) {
4634
4635				// simply return dimensions without custom scrollbars
4636
4637				this.verticalScrollActive = true;
4638
4639				this.horizontalScrollActive = true;
4640
4641				resultDimensions = {
4642
4643					innerWidth: dimensions.width - fakeBarWidth,
4644
4645					innerHeight: dimensions.height - fakeBarHeight
4646
4647				};
4648
4649			} else {
4650
4651				// detect when to display each scrollbar
4652
4653				this.saveElementDimensions();
4654
4655				this.verticalScrollActive = false;
4656
4657				this.horizontalScrollActive = false;
4658
4659
4660
4661				// fill container with full size
4662
4663				this.realElement.css({
4664
4665					width: dimensions.width - paddingWidth,
4666
4667					height: dimensions.height - paddingHeight
4668
4669				});
4670
4671
4672
4673				this.horizontalScrollActive = this.realElement.prop('scrollWidth') > this.containerDimensions.width;
4674
4675				this.verticalScrollActive = this.realElement.prop('scrollHeight') > this.containerDimensions.height;
4676
4677
4678
4679				this.restoreElementDimensions();
4680
4681				resultDimensions = {
4682
4683					innerWidth: dimensions.width - (this.verticalScrollActive ? fakeBarWidth : 0),
4684
4685					innerHeight: dimensions.height - (this.horizontalScrollActive ? fakeBarHeight : 0)
4686
4687				};
4688
4689			}
4690
4691			$.extend(resultDimensions, {
4692
4693				width: resultDimensions.innerWidth - paddingWidth,
4694
4695				height: resultDimensions.innerHeight - paddingHeight
4696
4697			});
4698
4699			return resultDimensions;
4700
4701		},
4702
4703		rebuildScrollbars: function() {
4704
4705			// resize wrapper according to real element styles
4706
4707			this.containerDimensions = this.getContainerDimensions();
4708
4709			this.embeddedDimensions = this.getEmbeddedDimensions(this.containerDimensions);
4710
4711
4712
4713			// resize wrapper to desired dimensions
4714
4715			this.scrollWrapper.css({
4716
4717				width: this.containerDimensions.width,
4718
4719				height: this.containerDimensions.height
4720
4721			});
4722
4723
4724
4725			// resize element inside wrapper excluding scrollbar size
4726
4727			this.realElement.css({
4728
4729				overflow: 'hidden',
4730
4731				width: this.embeddedDimensions.width,
4732
4733				height: this.embeddedDimensions.height
4734
4735			});
4736
4737
4738
4739			// redraw scrollbar offset
4740
4741			this.redrawScrollbars();
4742
4743		},
4744
4745		redrawScrollbars: function() {
4746
4747			var viewSize, maxScrollValue;
4748
4749
4750
4751			// redraw vertical scrollbar
4752
4753			if (this.verticalScrollActive) {
4754
4755				viewSize = this.vBarEdge ? this.containerDimensions.height - this.vBarEdge : this.embeddedDimensions.innerHeight;
4756
4757				maxScrollValue = Math.max(this.realElement.prop('offsetHeight'), this.realElement.prop('scrollHeight')) - this.vBarEdge;
4758
4759
4760
4761				this.vBar.show().setMaxValue(maxScrollValue - viewSize).setRatio(viewSize / maxScrollValue).setSize(viewSize);
4762
4763				this.vBar.setValue(this.realElement.scrollTop());
4764
4765			} else {
4766
4767				this.vBar.hide();
4768
4769			}
4770
4771
4772
4773			// redraw horizontal scrollbar
4774
4775			if (this.horizontalScrollActive) {
4776
4777				viewSize = this.embeddedDimensions.innerWidth;
4778
4779				maxScrollValue = this.realElement.prop('scrollWidth');
4780
4781
4782
4783				if (maxScrollValue === viewSize) {
4784
4785					this.horizontalScrollActive = false;
4786
4787				}
4788
4789				this.hBar.show().setMaxValue(maxScrollValue - viewSize).setRatio(viewSize / maxScrollValue).setSize(viewSize);
4790
4791				this.hBar.setValue(this.realElement.scrollLeft());
4792
4793			} else {
4794
4795				this.hBar.hide();
4796
4797			}
4798
4799
4800
4801			// set "touch-action" style rule
4802
4803			var touchAction = '';
4804
4805			if (this.verticalScrollActive && this.horizontalScrollActive) {
4806
4807				touchAction = 'none';
4808
4809			} else if (this.verticalScrollActive) {
4810
4811				touchAction = 'pan-x';
4812
4813			} else if (this.horizontalScrollActive) {
4814
4815				touchAction = 'pan-y';
4816
4817			}
4818
4819			this.realElement.css('touchAction', touchAction);
4820
4821		},
4822
4823		refresh: function() {
4824
4825			this.rebuildScrollbars();
4826
4827		},
4828
4829		destroy: function() {
4830
4831			// remove event listeners
4832
4833			this.win.off('resize orientationchange load', this.onResize);
4834
4835			this.realElement.off({
4836
4837				'jcf-mousewheel': this.onMouseWheel,
4838
4839				'jcf-pointerdown': this.onTouchBody
4840
4841			});
4842
4843			this.doc.off({
4844
4845				'jcf-pointermove': this.onMoveBody,
4846
4847				'jcf-pointerup': this.onReleaseBody
4848
4849			});
4850
4851
4852
4853			// restore structure
4854
4855			this.saveScrollOffsets();
4856
4857			this.vBar.destroy();
4858
4859			this.hBar.destroy();
4860
4861			this.realElement.insertAfter(this.scrollWrapper).css({
4862
4863				touchAction: '',
4864
4865				overflow: '',
4866
4867				width: '',
4868
4869				height: ''
4870
4871			});
4872
4873			this.scrollWrapper.remove();
4874
4875			this.restoreScrollOffsets();
4876
4877		}
4878
4879	});
4880
4881
4882
4883	// custom scrollbar
4884
4885	function ScrollBar(options) {
4886
4887		this.options = $.extend({
4888
4889			holder: null,
4890
4891			vertical: true,
4892
4893			inactiveClass: 'jcf-inactive',
4894
4895			verticalClass: 'jcf-scrollbar-vertical',
4896
4897			horizontalClass: 'jcf-scrollbar-horizontal',
4898
4899			scrollbarStructure: '<div class="jcf-scrollbar"><div class="jcf-scrollbar-dec"></div><div class="jcf-scrollbar-slider"><div class="jcf-scrollbar-handle"></div></div><div class="jcf-scrollbar-inc"></div></div>',
4900
4901			btnDecSelector: '.jcf-scrollbar-dec',
4902
4903			btnIncSelector: '.jcf-scrollbar-inc',
4904
4905			sliderSelector: '.jcf-scrollbar-slider',
4906
4907			handleSelector: '.jcf-scrollbar-handle',
4908
4909			scrollInterval: 300,
4910
4911			scrollStep: 400 // px/sec
4912
4913		}, options);
4914
4915		this.init();
4916
4917	}
4918
4919	$.extend(ScrollBar.prototype, {
4920
4921		init: function() {
4922
4923			this.initStructure();
4924
4925			this.attachEvents();
4926
4927		},
4928
4929		initStructure: function() {
4930
4931			// define proporties
4932
4933			this.doc = $(document);
4934
4935			this.isVertical = !!this.options.vertical;
4936
4937			this.sizeProperty = this.isVertical ? 'height' : 'width';
4938
4939			this.fullSizeProperty = this.isVertical ? 'outerHeight' : 'outerWidth';
4940
4941			this.invertedSizeProperty = this.isVertical ? 'width' : 'height';
4942
4943			this.thicknessMeasureMethod = 'outer' + this.invertedSizeProperty.charAt(0).toUpperCase() + this.invertedSizeProperty.substr(1);
4944
4945			this.offsetProperty = this.isVertical ? 'top' : 'left';
4946
4947			this.offsetEventProperty = this.isVertical ? 'pageY' : 'pageX';
4948
4949
4950
4951			// initialize variables
4952
4953			this.value = this.options.value || 0;
4954
4955			this.maxValue = this.options.maxValue || 0;
4956
4957			this.currentSliderSize = 0;
4958
4959			this.handleSize = 0;
4960
4961
4962
4963			// find elements
4964
4965			this.holder = $(this.options.holder);
4966
4967			this.scrollbar = $(this.options.scrollbarStructure).appendTo(this.holder);
4968
4969			this.btnDec = this.scrollbar.find(this.options.btnDecSelector);
4970
4971			this.btnInc = this.scrollbar.find(this.options.btnIncSelector);
4972
4973			this.slider = this.scrollbar.find(this.options.sliderSelector);
4974
4975			this.handle = this.slider.find(this.options.handleSelector);
4976
4977
4978
4979			// set initial styles
4980
4981			this.scrollbar.addClass(this.isVertical ? this.options.verticalClass : this.options.horizontalClass).css({
4982
4983				touchAction: this.isVertical ? 'pan-x' : 'pan-y',
4984
4985				position: 'absolute'
4986
4987			});
4988
4989			this.slider.css({
4990
4991				position: 'relative'
4992
4993			});
4994
4995			this.handle.css({
4996
4997				touchAction: 'none',
4998
4999				position: 'absolute'
5000
5001			});
5002
5003		},
5004
5005		attachEvents: function() {
5006
5007			this.bindHandlers();
5008
5009			this.handle.on('jcf-pointerdown', this.onHandlePress);
5010
5011			this.slider.add(this.btnDec).add(this.btnInc).on('jcf-pointerdown', this.onButtonPress);
5012
5013		},
5014
5015		onHandlePress: function(e) {
5016
5017			if (e.pointerType === 'mouse' && e.button > 1) {
5018
5019				return;
5020
5021			} else {
5022
5023				e.preventDefault();
5024
5025				this.handleDragActive = true;
5026
5027				this.sliderOffset = this.slider.offset()[this.offsetProperty];
5028
5029				this.innerHandleOffset = e[this.offsetEventProperty] - this.handle.offset()[this.offsetProperty];
5030
5031
5032
5033				this.doc.on('jcf-pointermove', this.onHandleDrag);
5034
5035				this.doc.on('jcf-pointerup', this.onHandleRelease);
5036
5037			}
5038
5039		},
5040
5041		onHandleDrag: function(e) {
5042
5043			e.preventDefault();
5044
5045			this.calcOffset = e[this.offsetEventProperty] - this.sliderOffset - this.innerHandleOffset;
5046
5047			this.setValue(this.calcOffset / (this.currentSliderSize - this.handleSize) * this.maxValue);
5048
5049			this.triggerScrollEvent(this.value);
5050
5051		},
5052
5053		onHandleRelease: function() {
5054
5055			this.handleDragActive = false;
5056
5057			this.doc.off('jcf-pointermove', this.onHandleDrag);
5058
5059			this.doc.off('jcf-pointerup', this.onHandleRelease);
5060
5061		},
5062
5063		onButtonPress: function(e) {
5064
5065			var direction, clickOffset;
5066
5067			if (e.pointerType === 'mouse' && e.button > 1) {
5068
5069				return;
5070
5071			} else {
5072
5073				e.preventDefault();
5074
5075				if (!this.handleDragActive) {
5076
5077					if (this.slider.is(e.currentTarget)) {
5078
5079						// slider pressed
5080
5081						direction = this.handle.offset()[this.offsetProperty] > e[this.offsetEventProperty] ? -1 : 1;
5082
5083						clickOffset = e[this.offsetEventProperty] - this.slider.offset()[this.offsetProperty];
5084
5085						this.startPageScrolling(direction, clickOffset);
5086
5087					} else {
5088
5089						// scrollbar buttons pressed
5090
5091						direction = this.btnDec.is(e.currentTarget) ? -1 : 1;
5092
5093						this.startSmoothScrolling(direction);
5094
5095					}
5096
5097					this.doc.on('jcf-pointerup', this.onButtonRelease);
5098
5099				}
5100
5101			}
5102
5103		},
5104
5105		onButtonRelease: function() {
5106
5107			this.stopPageScrolling();
5108
5109			this.stopSmoothScrolling();
5110
5111			this.doc.off('jcf-pointerup', this.onButtonRelease);
5112
5113		},
5114
5115		startPageScrolling: function(direction, clickOffset) {
5116
5117			var self = this,
5118
5119				stepValue = direction * self.currentSize;
5120
5121
5122
5123			// limit checker
5124
5125			var isFinishedScrolling = function() {
5126
5127				var handleTop = (self.value / self.maxValue) * (self.currentSliderSize - self.handleSize);
5128
5129
5130
5131				if (direction > 0) {
5132
5133					return handleTop + self.handleSize >= clickOffset;
5134
5135				} else {
5136
5137					return handleTop <= clickOffset;
5138
5139				}
5140
5141			};
5142
5143
5144
5145			// scroll by page when track is pressed
5146
5147			var doPageScroll = function() {
5148
5149				self.value += stepValue;
5150
5151				self.setValue(self.value);
5152
5153				self.triggerScrollEvent(self.value);
5154
5155
5156
5157				if (isFinishedScrolling()) {
5158
5159					clearInterval(self.pageScrollTimer);
5160
5161				}
5162
5163			};
5164
5165
5166
5167			// start scrolling
5168
5169			this.pageScrollTimer = setInterval(doPageScroll, this.options.scrollInterval);
5170
5171			doPageScroll();
5172
5173		},
5174
5175		stopPageScrolling: function() {
5176
5177			clearInterval(this.pageScrollTimer);
5178
5179		},
5180
5181		startSmoothScrolling: function(direction) {
5182
5183			var self = this, dt;
5184
5185			this.stopSmoothScrolling();
5186
5187
5188
5189			// simple animation functions
5190
5191			var raf = window.requestAnimationFrame || function(func) {
5192
5193				setTimeout(func, 16);
5194
5195			};
5196
5197			var getTimestamp = function() {
5198
5199				return Date.now ? Date.now() : new Date().getTime();
5200
5201			};
5202
5203
5204
5205			// set animation limit
5206
5207			var isFinishedScrolling = function() {
5208
5209				if (direction > 0) {
5210
5211					return self.value >= self.maxValue;
5212
5213				} else {
5214
5215					return self.value <= 0;
5216
5217				}
5218
5219			};
5220
5221
5222
5223			// animation step
5224
5225			var doScrollAnimation = function() {
5226
5227				var stepValue = (getTimestamp() - dt) / 1000 * self.options.scrollStep;
5228
5229
5230
5231				if (self.smoothScrollActive) {
5232
5233					self.value += stepValue * direction;
5234
5235					self.setValue(self.value);
5236
5237					self.triggerScrollEvent(self.value);
5238
5239
5240
5241					if (!isFinishedScrolling()) {
5242
5243						dt = getTimestamp();
5244
5245						raf(doScrollAnimation);
5246
5247					}
5248
5249				}
5250
5251			};
5252
5253
5254
5255			// start animation
5256
5257			self.smoothScrollActive = true;
5258
5259			dt = getTimestamp();
5260
5261			raf(doScrollAnimation);
5262
5263		},
5264
5265		stopSmoothScrolling: function() {
5266
5267			this.smoothScrollActive = false;
5268
5269		},
5270
5271		triggerScrollEvent: function(scrollValue) {
5272
5273			if (this.options.onScroll) {
5274
5275				this.options.onScroll(scrollValue);
5276
5277			}
5278
5279		},
5280
5281		getThickness: function() {
5282
5283			return this.scrollbar[this.thicknessMeasureMethod]();
5284
5285		},
5286
5287		setSize: function(size) {
5288
5289			// resize scrollbar
5290
5291			var btnDecSize = this.btnDec[this.fullSizeProperty](),
5292
5293				btnIncSize = this.btnInc[this.fullSizeProperty]();
5294
5295
5296
5297			// resize slider
5298
5299			this.currentSize = size;
5300
5301			this.currentSliderSize = size - btnDecSize - btnIncSize;
5302
5303			this.scrollbar.css(this.sizeProperty, size);
5304
5305			this.slider.css(this.sizeProperty, this.currentSliderSize);
5306
5307			this.currentSliderSize = this.slider[this.sizeProperty]();
5308
5309
5310
5311			// resize handle
5312
5313			this.handleSize = Math.round(this.currentSliderSize * this.ratio);
5314
5315			this.handle.css(this.sizeProperty, this.handleSize);
5316
5317			this.handleSize = this.handle[this.fullSizeProperty]();
5318
5319
5320
5321			return this;
5322
5323		},
5324
5325		setRatio: function(ratio) {
5326
5327			this.ratio = ratio;
5328
5329			return this;
5330
5331		},
5332
5333		setMaxValue: function(maxValue) {
5334
5335			this.maxValue = maxValue;
5336
5337			this.setValue(Math.min(this.value, this.maxValue));
5338
5339			return this;
5340
5341		},
5342
5343		setValue: function(value) {
5344
5345			this.value = value;
5346
5347			if (this.value < 0) {
5348
5349				this.value = 0;
5350
5351			} else if (this.value > this.maxValue) {
5352
5353				this.value = this.maxValue;
5354
5355			}
5356
5357			this.refresh();
5358
5359		},
5360
5361		setPosition: function(styles) {
5362
5363			this.scrollbar.css(styles);
5364
5365			return this;
5366
5367		},
5368
5369		hide: function() {
5370
5371			this.scrollbar.detach();
5372
5373			return this;
5374
5375		},
5376
5377		show: function() {
5378
5379			this.scrollbar.appendTo(this.holder);
5380
5381			return this;
5382
5383		},
5384
5385		refresh: function() {
5386
5387			// recalculate handle position
5388
5389			if (this.value === 0 || this.maxValue === 0) {
5390
5391				this.calcOffset = 0;
5392
5393			} else {
5394
5395				this.calcOffset = (this.value / this.maxValue) * (this.currentSliderSize - this.handleSize);
5396
5397			}
5398
5399			this.handle.css(this.offsetProperty, this.calcOffset);
5400
5401
5402
5403			// toggle inactive classes
5404
5405			this.btnDec.toggleClass(this.options.inactiveClass, this.value === 0);
5406
5407			this.btnInc.toggleClass(this.options.inactiveClass, this.value === this.maxValue);
5408
5409			this.scrollbar.toggleClass(this.options.inactiveClass, this.maxValue === 0);
5410
5411		},
5412
5413		destroy: function() {
5414
5415			// remove event handlers and scrollbar block itself
5416
5417			this.btnDec.add(this.btnInc).off('jcf-pointerdown', this.onButtonPress);
5418
5419			this.handle.off('jcf-pointerdown', this.onHandlePress);
5420
5421			this.doc.off('jcf-pointermove', this.onHandleDrag);
5422
5423			this.doc.off('jcf-pointerup', this.onHandleRelease);
5424
5425			this.doc.off('jcf-pointerup', this.onButtonRelease);
5426
5427			this.stopSmoothScrolling();
5428
5429			this.stopPageScrolling();
5430
5431			this.scrollbar.remove();
5432
5433		}
5434
5435	});
5436
5437
5438
5439}(jQuery, this));
5440
5441
5442
5443/*!
5444
5445 * JavaScript Custom Forms : Number Module
5446
5447 *
5448
5449 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
5450
5451 * Released under the MIT license (LICENSE.txt)
5452
5453 *
5454
5455 * Version: 1.1.3
5456
5457 */
5458
5459;(function($) {
5460
5461	'use strict';
5462
5463
5464
5465	jcf.addModule({
5466
5467		name: 'Number',
5468
5469		selector: 'input[type="number"]',
5470
5471		options: {
5472
5473			realElementClass: 'jcf-real-element',
5474
5475			fakeStructure: '<span class="jcf-number"><span class="jcf-btn-inc"></span><span class="jcf-btn-dec"></span></span>',
5476
5477			btnIncSelector: '.jcf-btn-inc',
5478
5479			btnDecSelector: '.jcf-btn-dec',
5480
5481			pressInterval: 150
5482
5483		},
5484
5485		matchElement: function(element) {
5486
5487			return element.is(this.selector);
5488
5489		},
5490
5491		init: function() {
5492
5493			this.initStructure();
5494
5495			this.attachEvents();
5496
5497			this.refresh();
5498
5499		},
5500
5501		initStructure: function() {
5502
5503			this.page = $('html');
5504
5505			this.realElement = $(this.options.element).addClass(this.options.realElementClass);
5506
5507			this.fakeElement = $(this.options.fakeStructure).insertBefore(this.realElement).prepend(this.realElement);
5508
5509			this.btnDec = this.fakeElement.find(this.options.btnDecSelector);
5510
5511			this.btnInc = this.fakeElement.find(this.options.btnIncSelector);
5512
5513
5514
5515			// set initial values
5516
5517			this.initialValue = parseFloat(this.realElement.val()) || 0;
5518
5519			this.minValue = parseFloat(this.realElement.attr('min'));
5520
5521			this.maxValue = parseFloat(this.realElement.attr('max'));
5522
5523			this.stepValue = parseFloat(this.realElement.attr('step')) || 1;
5524
5525
5526
5527			// check attribute values
5528
5529			this.minValue = isNaN(this.minValue) ? -Infinity : this.minValue;
5530
5531			this.maxValue = isNaN(this.maxValue) ? Infinity : this.maxValue;
5532
5533
5534
5535			// handle range
5536
5537			if (isFinite(this.maxValue)) {
5538
5539				this.maxValue -= (this.maxValue - this.minValue) % this.stepValue;
5540
5541			}
5542
5543		},
5544
5545		attachEvents: function() {
5546
5547			this.realElement.on({
5548
5549				focus: this.onFocus
5550
5551			});
5552
5553			this.btnDec.add(this.btnInc).on('jcf-pointerdown', this.onBtnPress);
5554
5555		},
5556
5557		onBtnPress: function(e) {
5558
5559			var self = this,
5560
5561				increment;
5562
5563
5564
5565			if (!this.realElement.is(':disabled')) {
5566
5567				increment = this.btnInc.is(e.currentTarget);
5568
5569
5570
5571				self.step(increment);
5572
5573				clearInterval(this.stepTimer);
5574
5575				this.stepTimer = setInterval(function() {
5576
5577					self.step(increment);
5578
5579				}, this.options.pressInterval);
5580
5581
5582
5583				this.page.on('jcf-pointerup', this.onBtnRelease);
5584
5585			}
5586
5587		},
5588
5589		onBtnRelease: function() {
5590
5591			clearInterval(this.stepTimer);
5592
5593			this.page.off('jcf-pointerup', this.onBtnRelease);
5594
5595		},
5596
5597		onFocus: function() {
5598
5599			this.fakeElement.addClass(this.options.focusClass);
5600
5601			this.realElement.on({
5602
5603				blur: this.onBlur,
5604
5605				keydown: this.onKeyPress
5606
5607			});
5608
5609		},
5610
5611		onBlur: function() {
5612
5613			this.fakeElement.removeClass(this.options.focusClass);
5614
5615			this.realElement.off({
5616
5617				blur: this.onBlur,
5618
5619				keydown: this.onKeyPress
5620
5621			});
5622
5623		},
5624
5625		onKeyPress: function(e) {
5626
5627			if (e.which === 38 || e.which === 40) {
5628
5629				e.preventDefault();
5630
5631				this.step(e.which === 38);
5632
5633			}
5634
5635		},
5636
5637		step: function(increment) {
5638
5639			var originalValue = parseFloat(this.realElement.val()),
5640
5641				newValue = originalValue || 0,
5642
5643				addValue = this.stepValue * (increment ? 1 : -1),
5644
5645				edgeNumber = isFinite(this.minValue) ? this.minValue : this.initialValue - Math.abs(newValue * this.stepValue),
5646
5647				diff = Math.abs(edgeNumber - newValue) % this.stepValue;
5648
5649
5650
5651			// handle step diff
5652
5653			if (diff) {
5654
5655				if (increment) {
5656
5657					newValue += addValue - diff;
5658
5659				} else {
5660
5661					newValue -= diff;
5662
5663				}
5664
5665			} else {
5666
5667				newValue += addValue;
5668
5669			}
5670
5671
5672
5673			// handle min/max limits
5674
5675			if (newValue < this.minValue) {
5676
5677				newValue = this.minValue;
5678
5679			} else if (newValue > this.maxValue) {
5680
5681				newValue = this.maxValue;
5682
5683			}
5684
5685
5686
5687			// update value in real input if its changed
5688
5689			if (newValue !== originalValue) {
5690
5691				this.realElement.val(newValue).trigger('change');
5692
5693				this.refresh();
5694
5695			}
5696
5697		},
5698
5699		refresh: function() {
5700
5701			var isDisabled = this.realElement.is(':disabled'),
5702
5703				currentValue = parseFloat(this.realElement.val());
5704
5705
5706
5707			// handle disabled state
5708
5709			this.fakeElement.toggleClass(this.options.disabledClass, isDisabled);
5710
5711
5712
5713			// refresh button classes
5714
5715			this.btnDec.toggleClass(this.options.disabledClass, currentValue === this.minValue);
5716
5717			this.btnInc.toggleClass(this.options.disabledClass, currentValue === this.maxValue);
5718
5719		},
5720
5721		destroy: function() {
5722
5723			// restore original structure
5724
5725			this.realElement.removeClass(this.options.realElementClass).insertBefore(this.fakeElement);
5726
5727			this.fakeElement.remove();
5728
5729			clearInterval(this.stepTimer);
5730
5731
5732
5733			// remove event handlers
5734
5735			this.page.off('jcf-pointerup', this.onBtnRelease);
5736
5737			this.realElement.off({
5738
5739				keydown: this.onKeyPress,
5740
5741				focus: this.onFocus,
5742
5743				blur: this.onBlur
5744
5745			});
5746
5747		}
5748
5749	});
5750
5751
5752
5753}(jQuery));
5754
5755
5756
5757/*!
5758
5759 * JavaScript Custom Forms : Range Module
5760
5761 *
5762
5763 * Copyright 2014-2015 PSD2HTML - http://psd2html.com/jcf
5764
5765 * Released under the MIT license (LICENSE.txt)
5766
5767 *
5768
5769 * Version: 1.1.3
5770
5771 */
5772
5773;(function($) {
5774
5775	'use strict';
5776
5777
5778
5779	jcf.addModule({
5780
5781		name: 'Range',
5782
5783		selector: 'input[type="range"]',
5784
5785		options: {
5786
5787			realElementClass: 'jcf-real-element',
5788
5789			fakeStructure: '<span class="jcf-range"><span class="jcf-range-wrapper"><span class="jcf-range-track"><span class="jcf-range-handle"></span></span></span></span>',
5790
5791			dataListMark: '<span class="jcf-range-mark"></span>',
5792
5793			rangeDisplayWrapper: '<span class="jcf-range-display-wrapper"></span>',
5794
5795			rangeDisplay: '<span class="jcf-range-display"></span>',
5796
5797			handleSelector: '.jcf-range-handle',
5798
5799			trackSelector: '.jcf-range-track',
5800
5801			activeHandleClass: 'jcf-active-handle',
5802
5803			verticalClass: 'jcf-vertical',
5804
5805			orientation: 'horizontal',
5806
5807			range: false, // or "min", "max", "all"
5808
5809			dragHandleCenter: true,
5810
5811			snapToMarks: true,
5812
5813			snapRadius: 5
5814
5815		},
5816
5817		matchElement: function(element) {
5818
5819			return element.is(this.selector);
5820
5821		},
5822
5823		init: function() {
5824
5825			this.initStructure();
5826
5827			this.attachEvents();
5828
5829			this.refresh();
5830
5831		},
5832
5833		initStructure: function() {
5834
5835			this.page = $('html');
5836
5837			this.realElement = $(this.options.element).addClass(this.options.hiddenClass);
5838
5839			this.fakeElement = $(this.options.fakeStructure).insertBefore(this.realElement).prepend(this.realElement);
5840
5841			this.track = this.fakeElement.find(this.options.trackSelector);
5842
5843			this.trackHolder = this.track.parent();
5844
5845			this.handle = this.fakeElement.find(this.options.handleSelector);
5846
5847			this.createdHandleCount = 0;
5848
5849			this.activeDragHandleIndex = 0;
5850
5851			this.isMultiple = this.realElement.prop('multiple') || typeof this.realElement.attr('multiple') === 'string';
5852
5853			this.values = this.isMultiple ? this.realElement.attr('value').split(',') : [this.realElement.val()];
5854
5855			this.handleCount = this.isMultiple ? this.values.length : 1;
5856
5857
5858
5859			// create range display
5860
5861			this.rangeDisplayWrapper = $(this.options.rangeDisplayWrapper).insertBefore(this.track);
5862
5863			if (this.options.range === 'min' || this.options.range === 'all') {
5864
5865				this.rangeMin = $(this.options.rangeDisplay).addClass('jcf-range-min').prependTo(this.rangeDisplayWrapper);
5866
5867			}
5868
5869			if (this.options.range === 'max' || this.options.range === 'all') {
5870
5871				this.rangeMax = $(this.options.rangeDisplay).addClass('jcf-range-max').prependTo(this.rangeDisplayWrapper);
5872
5873			}
5874
5875
5876
5877			// clone handles if needed
5878
5879			while (this.createdHandleCount < this.handleCount) {
5880
5881				this.createdHandleCount++;
5882
5883				this.handle.clone().addClass('jcf-index-' + this.createdHandleCount).insertBefore(this.handle);
5884
5885
5886
5887				// create mid ranges
5888
5889				if (this.createdHandleCount > 1) {
5890
5891					if (!this.rangeMid) {
5892
5893						this.rangeMid = $();
5894
5895					}
5896
5897					this.rangeMid = this.rangeMid.add($(this.options.rangeDisplay).addClass('jcf-range-mid').prependTo(this.rangeDisplayWrapper));
5898
5899				}
5900
5901			}
5902
5903
5904
5905			// grab all handles
5906
5907			this.handle.detach();
5908
5909			this.handle = null;
5910
5911			this.handles = this.fakeElement.find(this.options.handleSelector);
5912
5913			this.handles.eq(0).addClass(this.options.activeHandleClass);
5914
5915
5916
5917			// handle orientation
5918
5919			this.isVertical = (this.options.orientation === 'vertical');
5920
5921			this.directionProperty = this.isVertical ? 'top' : 'left';
5922
5923			this.offsetProperty = this.isVertical ? 'bottom' : 'left';
5924
5925			this.eventProperty = this.isVertical ? 'pageY' : 'pageX';
5926
5927			this.sizeProperty = this.isVertical ? 'height' : 'width';
5928
5929			this.sizeMethod = this.isVertical ? 'innerHeight' : 'innerWidth';
5930
5931			this.fakeElement.css('touchAction', this.isVertical ? 'pan-x' : 'pan-y');
5932
5933			if (this.isVertical) {
5934
5935				this.fakeElement.addClass(this.options.verticalClass);
5936
5937			}
5938
5939
5940
5941			// set initial values
5942
5943			this.minValue = parseFloat(this.realElement.attr('min'));
5944
5945			this.maxValue = parseFloat(this.realElement.attr('max'));
5946
5947			this.stepValue = parseFloat(this.realElement.attr('step')) || 1;
5948
5949
5950
5951			// check attribute values
5952
5953			this.minValue = isNaN(this.minValue) ? 0 : this.minValue;
5954
5955			this.maxValue = isNaN(this.maxValue) ? 100 : this.maxValue;
5956
5957
5958
5959			// handle range
5960
5961			if (this.stepValue !== 1) {
5962
5963				this.maxValue -= (this.maxValue - this.minValue) % this.stepValue;
5964
5965			}
5966
5967			this.stepsCount = (this.maxValue - this.minValue) / this.stepValue;
5968
5969			this.createDataList();
5970
5971		},
5972
5973		attachEvents: function() {
5974
5975			this.realElement.on({
5976
5977				focus: this.onFocus
5978
5979			});
5980
5981			this.trackHolder.on('jcf-pointerdown', this.onTrackPress);
5982
5983			this.handles.on('jcf-pointerdown', this.onHandlePress);
5984
5985		},
5986
5987		createDataList: function() {
5988
5989			var self = this,
5990
5991				dataValues = [],
5992
5993				dataListId = this.realElement.attr('list');
5994
5995
5996
5997			if (dataListId) {
5998
5999				$('#' + dataListId).find('option').each(function() {
6000
6001					var itemValue = parseFloat(this.value || this.innerHTML),
6002
6003						mark, markOffset;
6004
6005
6006
6007					if (!isNaN(itemValue)) {
6008
6009						markOffset = self.valueToOffset(itemValue);
6010
6011						dataValues.push({
6012
6013							value: itemValue,
6014
6015							offset: markOffset
6016
6017						});
6018
6019						mark = $(self.options.dataListMark).text(itemValue).attr({
6020
6021							'data-mark-value': itemValue
6022
6023						}).css(self.offsetProperty, markOffset + '%').appendTo(self.track);
6024
6025					}
6026
6027				});
6028
6029				if (dataValues.length) {
6030
6031					self.dataValues = dataValues;
6032
6033				}
6034
6035			}
6036
6037		},
6038
6039		getDragHandleRange: function(handleIndex) {
6040
6041			// calculate range for slider with multiple handles
6042
6043			var minStep = -Infinity,
6044
6045				maxStep = Infinity;
6046
6047
6048
6049			if (handleIndex > 0) {
6050
6051				minStep = this.valueToStepIndex(this.values[handleIndex - 1]);
6052
6053			}
6054
6055			if (handleIndex < this.handleCount - 1) {
6056
6057				maxStep = this.valueToStepIndex(this.values[handleIndex + 1]);
6058
6059			}
6060
6061
6062
6063			return {
6064
6065				minStepIndex: minStep,
6066
6067				maxStepIndex: maxStep
6068
6069			};
6070
6071		},
6072
6073		getNearestHandle: function(percent) {
6074
6075			// handle vertical sliders
6076
6077			if (this.isVertical) {
6078
6079				percent = 1 - percent;
6080
6081			}
6082
6083
6084
6085			// detect closest handle when track is pressed
6086
6087			var closestHandle = this.handles.eq(0),
6088
6089				closestDistance = Infinity,
6090
6091				self = this;
6092
6093
6094
6095			if (this.handleCount > 1) {
6096
6097				this.handles.each(function() {
6098
6099					var handleOffset = parseFloat(this.style[self.offsetProperty]) / 100,
6100
6101						handleDistance = Math.abs(handleOffset - percent);
6102
6103
6104
6105					if (handleDistance < closestDistance) {
6106
6107						closestDistance = handleDistance;
6108
6109						closestHandle = $(this);
6110
6111					}
6112
6113				});
6114
6115			}
6116
6117			return closestHandle;
6118
6119		},
6120
6121		onTrackPress: function(e) {
6122
6123			var trackSize, trackOffset, innerOffset;
6124
6125
6126
6127			e.preventDefault();
6128
6129			if (!this.realElement.is(':disabled') && !this.activeDragHandle) {
6130
6131				trackSize = this.track[this.sizeMethod]();
6132
6133				trackOffset = this.track.offset()[this.directionProperty];
6134
6135				this.activeDragHandle = this.getNearestHandle((e[this.eventProperty] - trackOffset) / this.trackHolder[this.sizeMethod]());
6136
6137				this.activeDragHandleIndex = this.handles.index(this.activeDragHandle);
6138
6139				this.handles.removeClass(this.options.activeHandleClass).eq(this.activeDragHandleIndex).addClass(this.options.activeHandleClass);
6140
6141				innerOffset = this.activeDragHandle[this.sizeMethod]() / 2;
6142
6143
6144
6145				this.dragData = {
6146
6147					trackSize: trackSize,
6148
6149					innerOffset: innerOffset,
6150
6151					trackOffset: trackOffset,
6152
6153					min: trackOffset,
6154
6155					max: trackOffset + trackSize
6156
6157				};
6158
6159				this.page.on({
6160
6161					'jcf-pointermove': this.onHandleMove,
6162
6163					'jcf-pointerup': this.onHandleRelease
6164
6165				});
6166
6167
6168
6169				if (e.pointerType === 'mouse') {
6170
6171					this.realElement.focus();
6172
6173				}
6174
6175
6176
6177				this.onHandleMove(e);
6178
6179			}
6180
6181		},
6182
6183		onHandlePress: function(e) {
6184
6185			var trackSize, trackOffset, innerOffset;
6186
6187
6188
6189			e.preventDefault();
6190
6191			if (!this.realElement.is(':disabled') && !this.activeDragHandle) {
6192
6193				this.activeDragHandle = $(e.currentTarget);
6194
6195				this.activeDragHandleIndex = this.handles.index(this.activeDragHandle);
6196
6197				this.handles.removeClass(this.options.activeHandleClass).eq(this.activeDragHandleIndex).addClass(this.options.activeHandleClass);
6198
6199				trackSize = this.track[this.sizeMethod]();
6200
6201				trackOffset = this.track.offset()[this.directionProperty];
6202
6203				innerOffset = this.options.dragHandleCenter ? this.activeDragHandle[this.sizeMethod]() / 2 : e[this.eventProperty] - this.handle.offset()[this.directionProperty];
6204
6205
6206
6207				this.dragData = {
6208
6209					trackSize: trackSize,
6210
6211					innerOffset: innerOffset,
6212
6213					trackOffset: trackOffset,
6214
6215					min: trackOffset,
6216
6217					max: trackOffset + trackSize
6218
6219				};
6220
6221				this.page.on({
6222
6223					'jcf-pointermove': this.onHandleMove,
6224
6225					'jcf-pointerup': this.onHandleRelease
6226
6227				});
6228
6229
6230
6231				if (e.pointerType === 'mouse') {
6232
6233					this.realElement.focus();
6234
6235				}
6236
6237			}
6238
6239		},
6240
6241		onHandleMove: function(e) {
6242
6243			var self = this,
6244
6245				newOffset, dragPercent, stepIndex, valuePercent, handleDragRange;
6246
6247
6248
6249			// calculate offset
6250
6251			if (this.isVertical) {
6252
6253				newOffset = this.dragData.max + (this.dragData.min - e[this.eventProperty]) - this.dragData.innerOffset;
6254
6255			} else {
6256
6257				newOffset = e[this.eventProperty] - this.dragData.innerOffset;
6258
6259			}
6260
6261
6262
6263			// fit in range
6264
6265			if (newOffset < this.dragData.min) {
6266
6267				newOffset = this.dragData.min;
6268
6269			} else if (newOffset > this.dragData.max) {
6270
6271				newOffset = this.dragData.max;
6272
6273			}
6274
6275
6276
6277			e.preventDefault();
6278
6279			if (this.options.snapToMarks && this.dataValues) {
6280
6281				// snap handle to marks
6282
6283				var dragOffset = newOffset - this.dragData.trackOffset;
6284
6285				dragPercent = (newOffset - this.dragData.trackOffset) / this.dragData.trackSize * 100;
6286
6287
6288
6289				$.each(this.dataValues, function(index, item) {
6290
6291					var markOffset = item.offset / 100 * self.dragData.trackSize,
6292
6293						markMin = markOffset - self.options.snapRadius,
6294
6295						markMax = markOffset + self.options.snapRadius;
6296
6297
6298
6299					if (dragOffset >= markMin && dragOffset <= markMax) {
6300
6301						dragPercent = item.offset;
6302
6303						return false;
6304
6305					}
6306
6307				});
6308
6309			} else {
6310
6311				// snap handle to steps
6312
6313				dragPercent = (newOffset - this.dragData.trackOffset) / this.dragData.trackSize * 100;
6314
6315			}
6316
6317
6318
6319			// move handle only in range
6320
6321			stepIndex = Math.round(dragPercent * this.stepsCount / 100);
6322
6323			if (this.handleCount > 1) {
6324
6325				handleDragRange = this.getDragHandleRange(this.activeDragHandleIndex);
6326
6327				if (stepIndex < handleDragRange.minStepIndex) {
6328
6329					stepIndex = Math.max(handleDragRange.minStepIndex, stepIndex);
6330
6331				} else if (stepIndex > handleDragRange.maxStepIndex) {
6332
6333					stepIndex = Math.min(handleDragRange.maxStepIndex, stepIndex);
6334
6335				}
6336
6337			}
6338
6339			valuePercent = stepIndex * (100 / this.stepsCount);
6340
6341
6342
6343			if (this.dragData.stepIndex !== stepIndex) {
6344
6345				this.dragData.stepIndex = stepIndex;
6346
6347				this.dragData.offset = valuePercent;
6348
6349				this.activeDragHandle.css(this.offsetProperty, this.dragData.offset + '%');
6350
6351
6352
6353				// update value(s) and trigger "input" event
6354
6355				this.values[this.activeDragHandleIndex] = '' + this.stepIndexToValue(stepIndex);
6356
6357				this.updateValues();
6358
6359				this.realElement.trigger('input');
6360
6361			}
6362
6363		},
6364
6365		onHandleRelease: function() {
6366
6367			var newValue;
6368
6369			if (typeof this.dragData.offset === 'number') {
6370
6371				newValue = this.stepIndexToValue(this.dragData.stepIndex);
6372
6373				this.realElement.val(newValue).trigger('change');
6374
6375			}
6376
6377
6378
6379			this.page.off({
6380
6381				'jcf-pointermove': this.onHandleMove,
6382
6383				'jcf-pointerup': this.onHandleRelease
6384
6385			});
6386
6387			delete this.activeDragHandle;
6388
6389			delete this.dragData;
6390
6391		},
6392
6393		onFocus: function() {
6394
6395			if (!this.fakeElement.hasClass(this.options.focusClass)) {
6396
6397				this.fakeElement.addClass(this.options.focusClass);
6398
6399				this.realElement.on({
6400
6401					blur: this.onBlur,
6402
6403					keydown: this.onKeyPress
6404
6405				});
6406
6407			}
6408
6409		},
6410
6411		onBlur: function() {
6412
6413			this.fakeElement.removeClass(this.options.focusClass);
6414
6415			this.realElement.off({
6416
6417				blur: this.onBlur,
6418
6419				keydown: this.onKeyPress
6420
6421			});
6422
6423		},
6424
6425		onKeyPress: function(e) {
6426
6427			var incValue = (e.which === 38 || e.which === 39),
6428
6429				decValue = (e.which === 37 || e.which === 40);
6430
6431
6432
6433			// handle TAB key in slider with multiple handles
6434
6435			if (e.which === 9 && this.handleCount > 1) {
6436
6437				if (e.shiftKey && this.activeDragHandleIndex > 0) {
6438
6439					this.activeDragHandleIndex--;
6440
6441				} else if (!e.shiftKey && this.activeDragHandleIndex < this.handleCount - 1) {
6442
6443					this.activeDragHandleIndex++;
6444
6445				} else {
6446
6447					return;
6448
6449				}
6450
6451				e.preventDefault();
6452
6453				this.handles.removeClass(this.options.activeHandleClass).eq(this.activeDragHandleIndex).addClass(this.options.activeHandleClass);
6454
6455			}
6456
6457
6458
6459			// handle cursor keys
6460
6461			if (decValue || incValue) {
6462
6463				e.preventDefault();
6464
6465				this.step(incValue ? this.stepValue : -this.stepValue);
6466
6467			}
6468
6469		},
6470
6471		updateValues: function() {
6472
6473			var value = this.values.join(',');
6474
6475			if (this.values.length > 1) {
6476
6477				this.realElement.prop('valueLow', this.values[0]);
6478
6479				this.realElement.prop('valueHigh', this.values[this.values.length - 1]);
6480
6481				this.realElement.val(value);
6482
6483
6484
6485				// if browser does not accept multiple values set only one
6486
6487				if (this.realElement.val() !== value) {
6488
6489					this.realElement.val(this.values[this.values.length - 1]);
6490
6491				}
6492
6493			} else {
6494
6495				this.realElement.val(value);
6496
6497			}
6498
6499
6500
6501			this.updateRanges();
6502
6503		},
6504
6505		updateRanges: function() {
6506
6507			// update display ranges
6508
6509			var self = this,
6510
6511				handle;
6512
6513
6514
6515			if (this.rangeMin) {
6516
6517				handle = this.handles[0];
6518
6519				this.rangeMin.css(this.offsetProperty, 0).css(this.sizeProperty, handle.style[this.offsetProperty]);
6520
6521			}
6522
6523			if (this.rangeMax) {
6524
6525				handle = this.handles[this.handles.length - 1];
6526
6527				this.rangeMax.css(this.offsetProperty, handle.style[this.offsetProperty]).css(this.sizeProperty, 100 - parseFloat(handle.style[this.offsetProperty]) + '%');
6528
6529			}
6530
6531			if (this.rangeMid) {
6532
6533				this.handles.each(function(index, curHandle) {
6534
6535					var prevHandle, midBox;
6536
6537					if (index > 0) {
6538
6539						prevHandle = self.handles[index - 1];
6540
6541						midBox = self.rangeMid[index - 1];
6542
6543						midBox.style[self.offsetProperty] = prevHandle.style[self.offsetProperty];
6544
6545						midBox.style[self.sizeProperty] = parseFloat(curHandle.style[self.offsetProperty]) - parseFloat(prevHandle.style[self.offsetProperty]) + '%';
6546
6547					}
6548
6549				});
6550
6551			}
6552
6553		},
6554
6555		step: function(changeValue) {
6556
6557			var originalValue = parseFloat(this.values[this.activeDragHandleIndex || 0]),
6558
6559				newValue = originalValue,
6560
6561				minValue = this.minValue,
6562
6563				maxValue = this.maxValue;
6564
6565
6566
6567			if (isNaN(originalValue)) {
6568
6569				newValue = 0;
6570
6571			}
6572
6573
6574
6575			newValue += changeValue;
6576
6577
6578
6579			if (this.handleCount > 1) {
6580
6581				if (this.activeDragHandleIndex > 0) {
6582
6583					minValue = parseFloat(this.values[this.activeDragHandleIndex - 1]);
6584
6585				}
6586
6587				if (this.activeDragHandleIndex < this.handleCount - 1) {
6588
6589					maxValue = parseFloat(this.values[this.activeDragHandleIndex + 1]);
6590
6591				}
6592
6593			}
6594
6595
6596
6597			if (newValue > maxValue) {
6598
6599				newValue = maxValue;
6600
6601			} else if (newValue < minValue) {
6602
6603				newValue = minValue;
6604
6605			}
6606
6607
6608
6609			if (newValue !== originalValue) {
6610
6611				this.values[this.activeDragHandleIndex || 0] = '' + newValue;
6612
6613				this.updateValues();
6614
6615				this.realElement.trigger('input').trigger('change');
6616
6617				this.setSliderValue(this.values);
6618
6619			}
6620
6621		},
6622
6623		valueToStepIndex: function(value) {
6624
6625			return (value - this.minValue) / this.stepValue;
6626
6627		},
6628
6629		stepIndexToValue: function(stepIndex) {
6630
6631			return this.minValue + this.stepValue * stepIndex;
6632
6633		},
6634
6635		valueToOffset: function(value) {
6636
6637			var range = this.maxValue - this.minValue,
6638
6639				percent = (value - this.minValue) / range;
6640
6641
6642
6643			return percent * 100;
6644
6645		},
6646
6647		getSliderValue: function() {
6648
6649			return $.map(this.values, function(value) {
6650
6651				return parseFloat(value) || 0;
6652
6653			});
6654
6655		},
6656
6657		setSliderValue: function(values) {
6658
6659			// set handle position accordion according to value
6660
6661			var self = this;
6662
6663			this.handles.each(function(index, handle) {
6664
6665				handle.style[self.offsetProperty] = self.valueToOffset(values[index]) + '%';
6666
6667			});
6668
6669		},
6670
6671		refresh: function() {
6672
6673			// handle disabled state
6674
6675			var isDisabled = this.realElement.is(':disabled');
6676
6677			this.fakeElement.toggleClass(this.options.disabledClass, isDisabled);
6678
6679
6680
6681			// refresh handle position according to current value
6682
6683			this.setSliderValue(this.getSliderValue());
6684
6685			this.updateRanges();
6686
6687		},
6688
6689		destroy: function() {
6690
6691			this.realElement.removeClass(this.options.hiddenClass).insertBefore(this.fakeElement);
6692
6693			this.fakeElement.remove();
6694
6695
6696
6697			this.realElement.off({
6698
6699				keydown: this.onKeyPress,
6700
6701				focus: this.onFocus,
6702
6703				blur: this.onBlur
6704
6705			});
6706
6707		}
6708
6709	});
6710
6711
6712
6713}(jQuery));
6714
6715
6716
6717
6718
6719/*
6720
6721 * jQuery SlideMenu plugin
6722
6723 */
6724
6725;(function($){
6726
6727	function AjaxPopup(options){
6728
6729		this.options = $.extend({
6730
6731			holder: null,
6732
6733			button: '.btn-more',
6734
6735			holderBox: 'body',
6736
6737			ajaxHold: '#ajax-holder',
6738
6739			appendToBody: false,
6740
6741			attr: 'href',
6742
6743			animSpeed: 500
6744
6745		}, options);
6746
6747
6748
6749		this.init();
6750
6751	}
6752
6753	AjaxPopup.prototype = {
6754
6755		init: function(){
6756
6757			this.findElements();
6758
6759			this.makeCallback('onInit', this);
6760
6761			this.attachEvents();
6762
6763		},
6764
6765		findElements: function(){
6766
6767			this.holder = jQuery(this.options.holder);
6768
6769			this.button = this.holder.find(this.options.button);
6770
6771			this.ajaxHold = this.holder.find(this.options.ajaxHold);
6772
6773
6774
6775		},
6776
6777		attachEvents: function(){
6778
6779			var self = this;
6780
6781			this.clickHandler = function(e){
6782
6783				e.preventDefault();
6784
6785				var attr = self.button.attr(self.options.attr);
6786
6787				if(attr != '#'){
6788
6789					e.preventDefault();
6790
6791					self.ajaxLoad(attr).done(function(data){
6792
6793						var content = jQuery(data).filter('.blogs-block').css({opacity: 0});
6794
6795						var btnAjax = jQuery(data).filter('.btn-load');
6796
6797
6798
6799						if(self.options.appendToBody) content.appendTo(jQuery(self.options.holderBox));
6800
6801						else content.appendTo(self.ajaxHold);
6802
6803
6804
6805						if(btnAjax.length) self.button.attr('href', btnAjax.attr('href'));
6806
6807						else self.button.hide();
6808
6809
6810
6811						content.stop().animate({opacity: 1}, self.options.animSpeed);
6812
6813						self.makeCallback('onChange', self);
6814
6815					});
6816
6817				}
6818
6819			};
6820
6821			this.button.on('click', this.clickHandler);
6822
6823		},
6824
6825		ajaxLoad: function(url){
6826
6827			var d = jQuery.Deferred();
6828
6829			jQuery.ajax({
6830
6831				url: url,
6832
6833				type: 'get',
6834
6835				cache: false,
6836
6837				dataType: "html",
6838
6839				success: function(data){
6840
6841					d.resolve(data);
6842
6843				},
6844
6845				error: function(jqXHR, textStatus, errorThrown){
6846
6847					d.reject(jqXHR, textStatus, errorThrown);
6848
6849				}
6850
6851			});
6852
6853			return d;
6854
6855		},
6856
6857		makeCallback: function(name) {
6858
6859			if(typeof this.options[name] === 'function') {
6860
6861				var args = Array.prototype.slice.call(arguments);
6862
6863					args.shift();
6864
6865					this.options[name].apply(this, args);
6866
6867				}
6868
6869			}
6870
6871		};
6872
6873
6874
6875	$.fn.ajaxPopup = function(options){
6876
6877		return this.each(function(){
6878
6879			$(this).data('AjaxPopup', new AjaxPopup($.extend(options, {holder:this})));
6880
6881		});
6882
6883	};
6884
6885})(jQuery);
6886
6887
6888
6889/*
6890
6891 * jQuery Accordion plugin
6892
6893 */
6894
6895;(function($){
6896
6897	$.fn.slideAccordion = function(opt){
6898
6899		// default options
6900
6901		var options = $.extend({
6902
6903			addClassBeforeAnimation: false,
6904
6905			allowClickWhenExpanded: false,
6906
6907			activeClass:'active',
6908
6909			opener:'.opener',
6910
6911			slider:'.slide',
6912
6913			animSpeed: 300,
6914
6915			collapsible:true,
6916
6917			event:'click'
6918
6919		},opt);
6920
6921
6922
6923		return this.each(function(){
6924
6925			// options
6926
6927			var accordion = $(this);
6928
6929			var items = accordion.find(':has('+options.slider+')');
6930
6931
6932
6933			items.each(function(){
6934
6935				var item = $(this);
6936
6937				var opener = item.find(options.opener);
6938
6939				var slider = item.find(options.slider);
6940
6941				opener.bind(options.event, function(e){
6942
6943					if(!slider.is(':animated')) {
6944
6945						if(item.hasClass(options.activeClass)) {
6946
6947							if(options.allowClickWhenExpanded) {
6948
6949								return;
6950
6951							} else if(options.collapsible) {
6952
6953								slider.slideUp(options.animSpeed, function(){
6954
6955									hideSlide(slider);
6956
6957									item.removeClass(options.activeClass);
6958
6959								});
6960
6961							}
6962
6963						} else {
6964
6965							// show active
6966
6967							var levelItems = item.siblings('.'+options.activeClass);
6968
6969							var sliderElements = levelItems.find(options.slider);
6970
6971							item.addClass(options.activeClass);
6972
6973							showSlide(slider).hide().slideDown(options.animSpeed);
6974
6975
6976
6977							// collapse others
6978
6979							sliderElements.slideUp(options.animSpeed, function(){
6980
6981								levelItems.removeClass(options.activeClass);
6982
6983								hideSlide(sliderElements);
6984
6985							});
6986
6987						}
6988
6989					}
6990
6991					e.preventDefault();
6992
6993				});
6994
6995				if(item.hasClass(options.activeClass)) showSlide(slider); else hideSlide(slider);
6996
6997			});
6998
6999		});
7000
7001	};
7002
7003
7004
7005	// accordion slide visibility
7006
7007	var showSlide = function(slide) {
7008
7009		return slide.css({position:'', top: '', left: '', width: '' });
7010
7011	};
7012
7013	var hideSlide = function(slide) {
7014
7015		return slide.show().css({position:'absolute', top: -9999, left: -9999, width: slide.width() });
7016
7017	};
7018
7019}(jQuery));
7020
7021
7022
7023/*
7024
7025 * jQuery <marquee> plugin
7026
7027 */
7028
7029;(function($){
7030
7031	function Marquee(options) {
7032
7033		this.options = $.extend({
7034
7035			holder: null,
7036
7037			handleFlexible: true,
7038
7039			pauseOnHover: true,
7040
7041			hoverClass: 'hover',
7042
7043			direction: 'left',
7044
7045			cloneClass: 'cloned',
7046
7047			mask: null,
7048
7049			line: '>*',
7050
7051			items: '>*',
7052
7053			animSpeed: 10, // px per second
7054
7055			initialDelay: 0
7056
7057		}, options);
7058
7059		this.init();
7060
7061	}
7062
7063	Marquee.prototype = {
7064
7065		init: function() {
7066
7067			if(this.options.holder) {
7068
7069				this.initStructure();
7070
7071				this.attachEvents();
7072
7073			}
7074
7075		},
7076
7077		initStructure: function() {
7078
7079			// find elements
7080
7081			this.holder = $(this.options.holder);
7082
7083			this.mask = this.options.mask ? this.holder.find(this.options.mask) : this.holder,
7084
7085			this.line = this.mask.find(this.options.line),
7086
7087			this.items = this.line.find(this.options.items).css({'float':'left'});
7088
7089			this.direction = (this.options.direction === 'left') ? -1 : 1;
7090
7091			this.recalculateDimensions();
7092
7093
7094
7095			// prepare structure
7096
7097			this.cloneItems = this.items.clone().addClass(this.options.cloneClass).appendTo(this.line);
7098
7099			if(this.itemWidth >= this.maskWidth) {
7100
7101				this.activeLine = true;
7102
7103				this.offset = (this.direction === -1 ? 0 : this.maxOffset);
7104
7105			} else {
7106
7107				this.activeLine = false;
7108
7109				this.cloneItems.hide();
7110
7111				this.offset = 0;
7112
7113			}
7114
7115			this.line.css({
7116
7117				width: this.itemWidth * 2,
7118
7119				marginLeft: this.offset
7120
7121			});
7122
7123		},
7124
7125		attachEvents: function() {
7126
7127			// flexible layout handling
7128
7129			var self = this;
7130
7131			if(this.options.handleFlexible) {
7132
7133				this.resizeHandler = function() {
7134
7135					self.recalculateDimensions();
7136
7137					if(self.itemWidth < self.maskWidth) {
7138
7139						self.activeLine = false;
7140
7141						self.cloneItems.hide();
7142
7143						self.stopMoving();
7144
7145						self.offset = 0;
7146
7147						self.line.css({marginLeft: self.offset});
7148
7149					} else {
7150
7151						self.activeLine = true;
7152
7153						self.cloneItems.show();
7154
7155						self.startMoving();
7156
7157					}
7158
7159				};
7160
7161				$(window).bind('resize orientationchange', this.resizeHandler);
7162
7163			}
7164
7165
7166
7167			// pause on hover
7168
7169			if(this.options.pauseOnHover) {
7170
7171				this.hoverHandler = function() {
7172
7173					self.stopMoving();
7174
7175					self.holder.addClass(self.options.hoverClass);
7176
7177				};
7178
7179				this.leaveHandler = function() {
7180
7181					self.startMoving();
7182
7183					self.holder.removeClass(self.options.hoverClass);
7184
7185				};
7186
7187				this.holder.bind({ mouseenter: this.hoverHandler, mouseleave: this.leaveHandler });
7188
7189			}
7190
7191
7192
7193			// initial delay
7194
7195			setTimeout(function(){
7196
7197				self.initialFlag = true;
7198
7199				self.startMoving();
7200
7201			}, self.options.initialDelay || 1);
7202
7203		},
7204
7205		recalculateDimensions: function() {
7206
7207			// calculate block dimensions
7208
7209			var self = this;
7210
7211			this.maskWidth = this.mask.width();
7212
7213			this.itemWidth = 1;
7214
7215			this.items.each(function(){
7216
7217				self.itemWidth += $(this).outerWidth(true);
7218
7219			});
7220
7221			this.maxOffset = -this.itemWidth;
7222
7223		},
7224
7225		startMoving: function() {
7226
7227			// start animation
7228
7229			var self = this;
7230
7231			if(self.activeLine && self.initialFlag) {
7232
7233				var targetOffset = (self.direction < 0 ? self.maxOffset : 0);
7234
7235
7236
7237				self.offset = parseInt(self.line.css('marginLeft'), 10) || 0;
7238
7239				self.line.stop().animate({
7240
7241					marginLeft: targetOffset
7242
7243				}, {
7244
7245					duration: Math.abs(1000 * (self.offset - targetOffset) / self.options.animSpeed),
7246
7247					easing: 'linear',
7248
7249					complete: function() {
7250
7251						self.offset = (self.direction < 0 ? 0 : self.maxOffset);
7252
7253						self.line.css({marginLeft: self.offset});
7254
7255						self.startMoving();
7256
7257					}
7258
7259				});
7260
7261			}
7262
7263		},
7264
7265		stopMoving: function() {
7266
7267			// stop animation
7268
7269			this.line.stop();
7270
7271		},
7272
7273		destroy: function() {
7274
7275			this.stopMoving();
7276
7277			this.cloneItems.remove();
7278
7279			this.items.css({'float':''});
7280
7281			this.line.css({marginLeft:'',width:''});
7282
7283			this.holder.removeClass(this.options.hoverClass);
7284
7285			this.holder.unbind('mouseenter', this.hoverHandler);
7286
7287			this.holder.unbind('mouseleave', this.leaveHandler);
7288
7289			$(window).unbind('resize orientationchange', this.resizeHandler);
7290
7291		}
7292
7293	};
7294
7295
7296
7297	// jQuery plugin interface
7298
7299	$.fn.marquee = function(opt) {
7300
7301		return this.each(function() {
7302
7303			jQuery(this).data('Marquee', new Marquee($.extend(opt, {holder: this})));
7304
7305		});
7306
7307	};
7308
7309}(jQuery));
7310
7311
7312
7313// set same height for blocks
7314
7315function setSameHeight(opt) {
7316
7317	// default options
7318
7319	var options = {
7320
7321		holder: null,
7322
7323		skipClass: 'same-height-ignore',
7324
7325		leftEdgeClass: 'same-height-left',
7326
7327		rightEdgeClass: 'same-height-right',
7328
7329		elements: '>*',
7330
7331		flexible: false,
7332
7333		multiLine: false,
7334
7335		useMinHeight: false,
7336
7337		biggestHeight: false
7338
7339	};
7340
7341	for(var p in opt) {
7342
7343		if(opt.hasOwnProperty(p)) {
7344
7345			options[p] = opt[p];
7346
7347		}
7348
7349	}
7350
7351
7352
7353	// init script
7354
7355	if(options.holder) {
7356
7357		var holders = lib.queryElementsBySelector(options.holder);
7358
7359		lib.each(holders, function(ind, curHolder){
7360
7361			var curElements = [], resizeTimer, postResizeTimer;
7362
7363			var tmpElements = lib.queryElementsBySelector(options.elements, curHolder);
7364
7365
7366
7367			// get resize elements
7368
7369			for(var i = 0; i < tmpElements.length; i++) {
7370
7371				if(!lib.hasClass(tmpElements[i], options.skipClass)) {
7372
7373					curElements.push(tmpElements[i]);
7374
7375				}
7376
7377			}
7378
7379			if(!curElements.length) return;
7380
7381
7382
7383			// resize handler
7384
7385			function doResize() {
7386
7387				for(var i = 0; i < curElements.length; i++) {
7388
7389					curElements[i].style[options.useMinHeight && SameHeight.supportMinHeight ? 'minHeight' : 'height'] = '';
7390
7391				}
7392
7393
7394
7395				if(options.multiLine) {
7396
7397					// resize elements row by row
7398
7399					SameHeight.resizeElementsByRows(curElements, options);
7400
7401				} else {
7402
7403					// resize elements by holder
7404
7405					SameHeight.setSize(curElements, curHolder, options);
7406
7407				}
7408
7409			}
7410
7411			doResize();
7412
7413
7414
7415			// handle flexible layout / font resize
7416
7417			function flexibleResizeHandler() {
7418
7419				clearTimeout(resizeTimer);
7420
7421				resizeTimer = setTimeout(function(){
7422
7423					doResize();
7424
7425					clearTimeout(postResizeTimer);
7426
7427					postResizeTimer = setTimeout(doResize, 100);
7428
7429				},1);
7430
7431			}
7432
7433			if(options.flexible) {
7434
7435				addEvent(window, 'resize', flexibleResizeHandler);
7436
7437				addEvent(window, 'orientationchange', flexibleResizeHandler);
7438
7439				FontResizeEvent.onChange(flexibleResizeHandler);
7440
7441			}
7442
7443			// handle complete page load including images and fonts
7444
7445			addEvent(window, 'load', flexibleResizeHandler);
7446
7447		});
7448
7449	}
7450
7451
7452
7453	// event handler helper functions
7454
7455	function addEvent(object, event, handler) {
7456
7457		if(object.addEventListener) object.addEventListener(event, handler, false);
7458
7459		else if(object.attachEvent) object.attachEvent('on'+event, handler);
7460
7461	}
7462
7463}
7464
7465
7466
7467/*
7468
7469 * SameHeight helper module
7470
7471 */
7472
7473SameHeight = {
7474
7475	supportMinHeight: typeof document.documentElement.style.maxHeight !== 'undefined', // detect css min-height support
7476
7477	setSize: function(boxes, parent, options) {
7478
7479		var calcHeight, holderHeight = typeof parent === 'number' ? parent : this.getHeight(parent);
7480
7481
7482
7483		for(var i = 0; i < boxes.length; i++) {
7484
7485			var box = boxes[i];
7486
7487			var depthDiffHeight = 0;
7488
7489			var isBorderBox = this.isBorderBox(box);
7490
7491			lib.removeClass(box, options.leftEdgeClass);
7492
7493			lib.removeClass(box, options.rightEdgeClass);
7494
7495
7496
7497			if(typeof parent != 'number') {
7498
7499				var tmpParent = box.parentNode;
7500
7501				while(tmpParent != parent) {
7502
7503					depthDiffHeight += this.getOuterHeight(tmpParent) - this.getHeight(tmpParent);
7504
7505					tmpParent = tmpParent.parentNode;
7506
7507				}
7508
7509			}
7510
7511			calcHeight = holderHeight - depthDiffHeight;
7512
7513			calcHeight -= isBorderBox ? 0 : this.getOuterHeight(box) - this.getHeight(box);
7514
7515			if(calcHeight > 0) {
7516
7517				box.style[options.useMinHeight && this.supportMinHeight ? 'minHeight' : 'height'] = calcHeight + 'px';
7518
7519			}
7520
7521		}
7522
7523
7524
7525		lib.addClass(boxes[0], options.leftEdgeClass);
7526
7527		lib.addClass(boxes[boxes.length - 1], options.rightEdgeClass);
7528
7529		return calcHeight;
7530
7531	},
7532
7533	getOffset: function(obj) {
7534
7535		if (obj.getBoundingClientRect) {
7536
7537			var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
7538
7539			var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
7540
7541			var clientLeft = document.documentElement.clientLeft || document.body.clientLeft || 0;
7542
7543			var clientTop = document.documentElement.clientTop || document.body.clientTop || 0;
7544
7545			return {
7546
7547				top:Math.round(obj.getBoundingClientRect().top + scrollTop - clientTop),
7548
7549				left:Math.round(obj.getBoundingClientRect().left + scrollLeft - clientLeft)
7550
7551			};
7552
7553		} else {
7554
7555			var posLeft = 0, posTop = 0;
7556
7557			while (obj.offsetParent) {posLeft += obj.offsetLeft; posTop += obj.offsetTop; obj = obj.offsetParent;}
7558
7559			return {top:posTop,left:posLeft};
7560
7561		}
7562
7563	},
7564
7565	getStyle: function(el, prop) {
7566
7567		if (document.defaultView && document.defaultView.getComputedStyle) {
7568
7569			return document.defaultView.getComputedStyle(el, null)[prop];
7570
7571		} else if (el.currentStyle) {
7572
7573			return el.currentStyle[prop];
7574
7575		} else {
7576
7577			return el.style[prop];
7578
7579		}
7580
7581	},
7582
7583	getStylesTotal: function(obj) {
7584
7585		var sum = 0;
7586
7587		for(var i = 1; i < arguments.length; i++) {
7588
7589			var val = parseFloat(this.getStyle(obj, arguments[i]));
7590
7591			if(!isNaN(val)) {
7592
7593				sum += val;
7594
7595			}
7596
7597		}
7598
7599		return sum;
7600
7601	},
7602
7603	getHeight: function(obj) {
7604
7605		return obj.offsetHeight - this.getStylesTotal(obj, 'borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom');
7606
7607	},
7608
7609	getOuterHeight: function(obj) {
7610
7611		return obj.offsetHeight;
7612
7613	},
7614
7615	isBorderBox: function(obj) {
7616
7617		var f = this.getStyle, styleValue = f(obj, 'boxSizing') || f(obj, 'WebkitBoxSizing') || f(obj, 'MozBoxSizing');
7618
7619		return styleValue === 'border-box';
7620
7621	},
7622
7623	resizeElementsByRows: function(boxes, options) {
7624
7625		var currentRow = [], maxHeight, maxCalcHeight = 0, firstOffset = this.getOffset(boxes[0]).top;
7626
7627		for(var i = 0; i < boxes.length; i++) {
7628
7629			if(this.getOffset(boxes[i]).top === firstOffset) {
7630
7631				currentRow.push(boxes[i]);
7632
7633			} else {
7634
7635				maxHeight = this.getMaxHeight(currentRow);
7636
7637				maxCalcHeight = Math.max(maxCalcHeight, this.setSize(currentRow, maxHeight, options));
7638
7639				firstOffset = this.getOffset(boxes[i]).top;
7640
7641				currentRow = [boxes[i]];
7642
7643			}
7644
7645		}
7646
7647		if(currentRow.length) {
7648
7649			maxHeight = this.getMaxHeight(currentRow);
7650
7651			maxCalcHeight = Math.max(maxCalcHeight, this.setSize(currentRow, maxHeight, options));
7652
7653		}
7654
7655		if(options.biggestHeight) {
7656
7657			for(i = 0; i < boxes.length; i++) {
7658
7659				boxes[i].style[options.useMinHeight && this.supportMinHeight ? 'minHeight' : 'height'] = maxCalcHeight + 'px';
7660
7661			}
7662
7663		}
7664
7665	},
7666
7667	getMaxHeight: function(boxes) {
7668
7669		var maxHeight = 0;
7670
7671		for(var i = 0; i < boxes.length; i++) {
7672
7673			maxHeight = Math.max(maxHeight, this.getOuterHeight(boxes[i]));
7674
7675		}
7676
7677		return maxHeight;
7678
7679	}
7680
7681};
7682
7683
7684
7685/*
7686
7687 * FontResize Event
7688
7689 */
7690
7691FontResizeEvent = (function(window,document){
7692
7693	var randomID = 'font-resize-frame-' + Math.floor(Math.random() * 1000);
7694
7695	var resizeFrame = document.createElement('iframe');
7696
7697	resizeFrame.id = randomID; resizeFrame.className = 'font-resize-helper';
7698
7699	resizeFrame.style.cssText = 'position:absolute;width:100em;height:10px;top:-9999px;left:-9999px;border-width:0';
7700
7701
7702
7703	// wait for page load
7704
7705	function onPageReady() {
7706
7707		document.body.appendChild(resizeFrame);
7708
7709
7710
7711		// use native IE resize event if possible
7712
7713		if (/MSIE (6|7|8)/.test(navigator.userAgent)) {
7714
7715			resizeFrame.onresize = function() {
7716
7717				window.FontResizeEvent.trigger(resizeFrame.offsetWidth / 100);
7718
7719			};
7720
7721		}
7722
7723		// use script inside the iframe to detect resize for other browsers
7724
7725		else {
7726
7727			var doc = resizeFrame.contentWindow.document;
7728
7729			doc.open();
7730
7731			doc.write('<scri' + 'pt>window.onload = function(){var em = parent.document.getElementById("' + randomID + '");window.onresize = function(){if(parent.FontResizeEvent){parent.FontResizeEvent.trigger(em.offsetWidth / 100);}}};</scri' + 'pt>');
7732
7733			doc.close();
7734
7735		}
7736
7737	}
7738
7739	if(window.addEventListener) window.addEventListener('load', onPageReady, false);
7740
7741	else if(window.attachEvent) window.attachEvent('onload', onPageReady);
7742
7743
7744
7745	// public interface
7746
7747	var callbacks = [];
7748
7749	return {
7750
7751		onChange: function(f) {
7752
7753			if(typeof f === 'function') {
7754
7755				callbacks.push(f);
7756
7757			}
7758
7759		},
7760
7761		trigger: function(em) {
7762
7763			for(var i = 0; i < callbacks.length; i++) {
7764
7765				callbacks[i](em);
7766
7767			}
7768
7769		}
7770
7771	};
7772
7773}(this, document));
7774
7775
7776
7777/*
7778
7779 * Utility module
7780
7781 */
7782
7783lib = {
7784
7785	hasClass: function(el,cls) {
7786
7787		return el && el.className ? el.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)')) : false;
7788
7789	},
7790
7791	addClass: function(el,cls) {
7792
7793		if (el && !this.hasClass(el,cls)) el.className += " "+cls;
7794
7795	},
7796
7797	removeClass: function(el,cls) {
7798
7799		if (el && this.hasClass(el,cls)) {el.className=el.className.replace(new RegExp('(\\s|^)'+cls+'(\\s|$)'),' ');}
7800
7801	},
7802
7803	extend: function(obj) {
7804
7805		for(var i = 1; i < arguments.length; i++) {
7806
7807			for(var p in arguments[i]) {
7808
7809				if(arguments[i].hasOwnProperty(p)) {
7810
7811					obj[p] = arguments[i][p];
7812
7813				}
7814
7815			}
7816
7817		}
7818
7819		return obj;
7820
7821	},
7822
7823	each: function(obj, callback) {
7824
7825		var property, len;
7826
7827		if(typeof obj.length === 'number') {
7828
7829			for(property = 0, len = obj.length; property < len; property++) {
7830
7831				if(callback.call(obj[property], property, obj[property]) === false) {
7832
7833					break;
7834
7835				}
7836
7837			}
7838
7839		} else {
7840
7841			for(property in obj) {
7842
7843				if(obj.hasOwnProperty(property)) {
7844
7845					if(callback.call(obj[property], property, obj[property]) === false) {
7846
7847						break;
7848
7849					}
7850
7851				}
7852
7853			}
7854
7855		}
7856
7857	},
7858
7859	event: (function() {
7860
7861		var fixEvent = function(e) {
7862
7863			e = e || window.event;
7864
7865			if(e.isFixed) return e; else e.isFixed = true;
7866
7867			if(!e.target) e.target = e.srcElement;
7868
7869			e.preventDefault = e.preventDefault || function() {this.returnValue = false;};
7870
7871			e.stopPropagation = e.stopPropagation || function() {this.cancelBubble = true;};
7872
7873			return e;
7874
7875		};
7876
7877		return {
7878
7879			add: function(elem, event, handler) {
7880
7881				if(!elem.events) {
7882
7883					elem.events = {};
7884
7885					elem.handle = function(e) {
7886
7887						var ret, handlers = elem.events[e.type];
7888
7889						e = fixEvent(e);
7890
7891						for(var i = 0, len = handlers.length; i < len; i++) {
7892
7893							if(handlers[i]) {
7894
7895								ret = handlers[i].call(elem, e);
7896
7897								if(ret === false) {
7898
7899									e.preventDefault();
7900
7901									e.stopPropagation();
7902
7903								}
7904
7905							}
7906
7907						}
7908
7909					};
7910
7911				}
7912
7913				if(!elem.events[event]) {
7914
7915					elem.events[event] = [];
7916
7917					if(elem.addEventListener) elem.addEventListener(event, elem.handle, false);
7918
7919					else if(elem.attachEvent) elem.attachEvent('on'+event, elem.handle);
7920
7921				}
7922
7923				elem.events[event].push(handler);
7924
7925			},
7926
7927			remove: function(elem, event, handler) {
7928
7929				var handlers = elem.events[event];
7930
7931				for(var i = handlers.length - 1; i >= 0; i--) {
7932
7933					if(handlers[i] === handler) {
7934
7935						handlers.splice(i,1);
7936
7937					}
7938
7939				}
7940
7941				if(!handlers.length) {
7942
7943					delete elem.events[event];
7944
7945					if(elem.removeEventListener) elem.removeEventListener(event, elem.handle, false);
7946
7947					else if(elem.detachEvent) elem.detachEvent('on'+event, elem.handle);
7948
7949				}
7950
7951			}
7952
7953		};
7954
7955	}()),
7956
7957	queryElementsBySelector: function(selector, scope) {
7958
7959		scope = scope || document;
7960
7961		if(!selector) return [];
7962
7963		if(selector === '>*') return scope.children;
7964
7965		if(typeof document.querySelectorAll === 'function') {
7966
7967			return scope.querySelectorAll(selector);
7968
7969		}
7970
7971		var selectors = selector.split(',');
7972
7973		var resultList = [];
7974
7975		for(var s = 0; s < selectors.length; s++) {
7976
7977			var currentContext = [scope || document];
7978
7979			var tokens = selectors[s].replace(/^\s+/,'').replace(/\s+$/,'').split(' ');
7980
7981			for (var i = 0; i < tokens.length; i++) {
7982
7983				token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');
7984
7985				if (token.indexOf('#') > -1) {
7986
7987					var bits = token.split('#'), tagName = bits[0], id = bits[1];
7988
7989					var element = document.getElementById(id);
7990
7991					if (element && tagName && element.nodeName.toLowerCase() != tagName) {
7992
7993						return [];
7994
7995					}
7996
7997					currentContext = element ? [element] : [];
7998
7999					continue;
8000
8001				}
8002
8003				if (token.indexOf('.') > -1) {
8004
8005					var bits = token.split('.'), tagName = bits[0] || '*', className = bits[1], found = [], foundCount = 0;
8006
8007					for (var h = 0; h < currentContext.length; h++) {
8008
8009						var elements;
8010
8011						if (tagName == '*') {
8012
8013							elements = currentContext[h].getElementsByTagName('*');
8014
8015						} else {
8016
8017							elements = currentContext[h].getElementsByTagName(tagName);
8018
8019						}
8020
8021						for (var j = 0; j < elements.length; j++) {
8022
8023							found[foundCount++] = elements[j];
8024
8025						}
8026
8027					}
8028
8029					currentContext = [];
8030
8031					var currentContextIndex = 0;
8032
8033					for (var k = 0; k < found.length; k++) {
8034
8035						if (found[k].className && found[k].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))) {
8036
8037							currentContext[currentContextIndex++] = found[k];
8038
8039						}
8040
8041					}
8042
8043					continue;
8044
8045				}
8046
8047				if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
8048
8049					var tagName = RegExp.$1 || '*', attrName = RegExp.$2, attrOperator = RegExp.$3, attrValue = RegExp.$4;
8050
8051					if(attrName.toLowerCase() == 'for' && this.browser.msie && this.browser.version < 8) {
8052
8053						attrName = 'htmlFor';
8054
8055					}
8056
8057					var found = [], foundCount = 0;
8058
8059					for (var h = 0; h < currentContext.length; h++) {
8060
8061						var elements;
8062
8063						if (tagName == '*') {
8064
8065							elements = currentContext[h].getElementsByTagName('*');
8066
8067						} else {
8068
8069							elements = currentContext[h].getElementsByTagName(tagName);
8070
8071						}
8072
8073						for (var j = 0; elements[j]; j++) {
8074
8075							found[foundCount++] = elements[j];
8076
8077						}
8078
8079					}
8080
8081					currentContext = [];
8082
8083					var currentContextIndex = 0, checkFunction;
8084
8085					switch (attrOperator) {
8086
8087						case '=': checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue) }; break;
8088
8089						case '~': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('(\\s|^)'+attrValue+'(\\s|$)'))) }; break;
8090
8091						case '|': checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))) }; break;
8092
8093						case '^': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0) }; break;
8094
8095						case '$': checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length) }; break;
8096
8097						case '*': checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1) }; break;
8098
8099						default : checkFunction = function(e) { return e.getAttribute(attrName) };
8100
8101					}
8102
8103					currentContext = [];
8104
8105					var currentContextIndex = 0;
8106
8107					for (var k = 0; k < found.length; k++) {
8108
8109						if (checkFunction(found[k])) {
8110
8111							currentContext[currentContextIndex++] = found[k];
8112
8113						}
8114
8115					}
8116
8117					continue;
8118
8119				}
8120
8121				tagName = token;
8122
8123				var found = [], foundCount = 0;
8124
8125				for (var h = 0; h < currentContext.length; h++) {
8126
8127					var elements = currentContext[h].getElementsByTagName(tagName);
8128
8129					for (var j = 0; j < elements.length; j++) {
8130
8131						found[foundCount++] = elements[j];
8132
8133					}
8134
8135				}
8136
8137				currentContext = found;
8138
8139			}
8140
8141			resultList = [].concat(resultList,currentContext);
8142
8143		}
8144
8145		return resultList;
8146
8147	},
8148
8149	trim: function (str) {
8150
8151		return str.replace(/^\s+/, '').replace(/\s+$/, '');
8152
8153	},
8154
8155	bind: function(f, scope, forceArgs){
8156
8157		return function() {return f.apply(scope, typeof forceArgs !== 'undefined' ? [forceArgs] : arguments);};
8158
8159	}
8160
8161};
8162
8163
8164
8165// DOM ready handler
8166
8167function bindReady(handler){
8168
8169	var called = false;
8170
8171	var ready = function() {
8172
8173		if (called) return;
8174
8175		called = true;
8176
8177		handler();
8178
8179	};
8180
8181	if (document.addEventListener) {
8182
8183		document.addEventListener('DOMContentLoaded', ready, false);
8184
8185	} else if (document.attachEvent) {
8186
8187		if (document.documentElement.doScroll && window == window.top) {
8188
8189			var tryScroll = function(){
8190
8191				if (called) return;
8192
8193				if (!document.body) return;
8194
8195				try {
8196
8197					document.documentElement.doScroll('left');
8198
8199					ready();
8200
8201				} catch(e) {
8202
8203					setTimeout(tryScroll, 0);
8204
8205				}
8206
8207			};
8208
8209			tryScroll();
8210
8211		}
8212
8213		document.attachEvent('onreadystatechange', function(){
8214
8215			if (document.readyState === 'complete') {
8216
8217				ready();
8218
8219			}
8220
8221		});
8222
8223	}
8224
8225	if (window.addEventListener) window.addEventListener('load', ready, false);
8226
8227	else if (window.attachEvent) window.attachEvent('onload', ready);
8228
8229}
8230
8231
8232
8233
8234
8235/*
8236
8237 * jQuery Tabs plugin
8238
8239 */
8240
8241;(function($){
8242
8243	$.fn.contentTabs = function(o){
8244
8245		// default options
8246
8247		var options = $.extend({
8248
8249			activeClass:'active',
8250
8251			addToParent:false,
8252
8253			autoHeight:false,
8254
8255			autoRotate:false,
8256
8257			checkHash:false,
8258
8259			animSpeed:400,
8260
8261			switchTime:3000,
8262
8263			effect: 'none', // "fade", "slide"
8264
8265			tabLinks:'a',
8266
8267			attrib:'href',
8268
8269			event:'click'
8270
8271		},o);
8272
8273
8274
8275		return this.each(function(){
8276
8277			var tabset = $(this), tabs = $();
8278
8279			var tabLinks = tabset.find(options.tabLinks);
8280
8281			var tabLinksParents = tabLinks.parent();
8282
8283			var prevActiveLink = tabLinks.eq(0), currentTab, animating;
8284
8285			var tabHolder;
8286
8287
8288
8289			// handle location hash
8290
8291			if(options.checkHash && tabLinks.filter('[' + options.attrib + '="' + location.hash + '"]').length) {
8292
8293				(options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass);
8294
8295				setTimeout(function() {
8296
8297					window.scrollTo(0,0);
8298
8299				},1);
8300
8301			}
8302
8303
8304
8305			// init tabLinks
8306
8307			tabLinks.each(function(){
8308
8309				var link = $(this);
8310
8311				var href = link.attr(options.attrib);
8312
8313				var parent = link.parent();
8314
8315				href = href.substr(href.lastIndexOf('#'));
8316
8317
8318
8319				// get elements
8320
8321				var tab = $(href).hide().addClass(tabHiddenClass);
8322
8323				tabs = tabs.add(tab);
8324
8325				link.data('cparent', parent);
8326
8327				link.data('ctab', tab);
8328
8329
8330
8331				// find tab holder
8332
8333				if(!tabHolder && tab.length) {
8334
8335					tabHolder = tab.parent();
8336
8337				}
8338
8339
8340
8341				// show only active tab
8342
8343				var classOwner = options.addToParent ? parent : link;
8344
8345				if(classOwner.hasClass(options.activeClass) || (options.checkHash && location.hash === href)) {
8346
8347					classOwner.addClass(options.activeClass);
8348
8349					prevActiveLink = link; currentTab = tab;
8350
8351					tab.removeClass(tabHiddenClass).width('');
8352
8353					contentTabsEffect[options.effect].show({tab:tab, fast:true});
8354
8355				} else {
8356
8357					var tabWidth = tab.width();
8358
8359					if(tabWidth) {
8360
8361						tab.width(tabWidth);
8362
8363					}
8364
8365					tab.addClass(tabHiddenClass);
8366
8367				}
8368
8369
8370
8371				// event handler
8372
8373				link.bind(options.event, function(e){
8374
8375					if(link != prevActiveLink && !animating) {
8376
8377						switchTab(prevActiveLink, link);
8378
8379						prevActiveLink = link;
8380
8381					}
8382
8383				});
8384
8385				if(options.attrib === 'href') {
8386
8387					link.bind('click', function(e){
8388
8389						e.preventDefault();
8390
8391					});
8392
8393				}
8394
8395			});
8396
8397
8398
8399			// tab switch function
8400
8401			function switchTab(oldLink, newLink) {
8402
8403				animating = true;
8404
8405				var oldTab = oldLink.data('ctab');
8406
8407				var newTab = newLink.data('ctab');
8408
8409				prevActiveLink = newLink;
8410
8411				currentTab = newTab;
8412
8413
8414
8415				// refresh pagination links
8416
8417				(options.addToParent ? tabLinksParents : tabLinks).removeClass(options.activeClass);
8418
8419				(options.addToParent ? newLink.data('cparent') : newLink).addClass(options.activeClass);
8420
8421
8422
8423				// hide old tab
8424
8425				resizeHolder(oldTab, true);
8426
8427				contentTabsEffect[options.effect].hide({
8428
8429					speed: options.animSpeed,
8430
8431					tab:oldTab,
8432
8433					complete: function() {
8434
8435						// show current tab
8436
8437						resizeHolder(newTab.removeClass(tabHiddenClass).width(''));
8438
8439						contentTabsEffect[options.effect].show({
8440
8441							speed: options.animSpeed,
8442
8443							tab:newTab,
8444
8445							complete: function() {
8446
8447								if(!oldTab.is(newTab)) {
8448
8449									oldTab.width(oldTab.width()).addClass(tabHiddenClass);
8450
8451								}
8452
8453								animating = false;
8454
8455								resizeHolder(newTab, false);
8456
8457								autoRotate();
8458
8459								$(window).trigger('resize');
8460
8461							}
8462
8463						});
8464
8465					}
8466
8467				});
8468
8469			}
8470
8471
8472
8473			// holder auto height
8474
8475			function resizeHolder(block, state) {
8476
8477				var curBlock = block && block.length ? block : currentTab;
8478
8479				if(options.autoHeight && curBlock) {
8480
8481					tabHolder.stop();
8482
8483					if(state === false) {
8484
8485						tabHolder.css({height:''});
8486
8487					} else {
8488
8489						var origStyles = curBlock.attr('style');
8490
8491						curBlock.show().css({width:curBlock.width()});
8492
8493						var tabHeight = curBlock.outerHeight(true);
8494
8495						if(!origStyles) curBlock.removeAttr('style'); else curBlock.attr('style', origStyles);
8496
8497						if(state === true) {
8498
8499							tabHolder.css({height: tabHeight});
8500
8501						} else {
8502
8503							tabHolder.animate({height: tabHeight}, {duration: options.animSpeed});
8504
8505						}
8506
8507					}
8508
8509				}
8510
8511			}
8512
8513			if(options.autoHeight) {
8514
8515				$(window).bind('resize orientationchange', function(){
8516
8517					tabs.not(currentTab).removeClass(tabHiddenClass).show().each(function(){
8518
8519						var tab = jQuery(this), tabWidth = tab.css({width:''}).width();
8520
8521						if(tabWidth) {
8522
8523							tab.width(tabWidth);
8524
8525						}
8526
8527					}).hide().addClass(tabHiddenClass);
8528
8529
8530
8531					resizeHolder(currentTab, false);
8532
8533				});
8534
8535			}
8536
8537
8538
8539			// autorotation handling
8540
8541			var rotationTimer;
8542
8543			function nextTab() {
8544
8545				var activeItem = (options.addToParent ? tabLinksParents : tabLinks).filter('.' + options.activeClass);
8546
8547				var activeIndex = (options.addToParent ? tabLinksParents : tabLinks).index(activeItem);
8548
8549				var newLink = tabLinks.eq(activeIndex < tabLinks.length - 1 ? activeIndex + 1 : 0);
8550
8551				prevActiveLink = tabLinks.eq(activeIndex);
8552
8553				switchTab(prevActiveLink, newLink);
8554
8555			}
8556
8557			function autoRotate() {
8558
8559				if(options.autoRotate && tabLinks.length > 1) {
8560
8561					clearTimeout(rotationTimer);
8562
8563					rotationTimer = setTimeout(function() {
8564
8565						if(!animating) {
8566
8567							nextTab();
8568
8569						} else {
8570
8571							autoRotate();
8572
8573						}
8574
8575					}, options.switchTime);
8576
8577				}
8578
8579			}
8580
8581			autoRotate();
8582
8583		});
8584
8585	};
8586
8587
8588
8589	// add stylesheet for tabs on DOMReady
8590
8591	var tabHiddenClass = 'js-tab-hidden';
8592
8593	(function() {
8594
8595		var tabStyleSheet = $('<style type="text/css">')[0];
8596
8597		var tabStyleRule = '.'+tabHiddenClass;
8598
8599		tabStyleRule += '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important}';
8600
8601		if (tabStyleSheet.styleSheet) {
8602
8603			tabStyleSheet.styleSheet.cssText = tabStyleRule;
8604
8605		} else {
8606
8607			tabStyleSheet.appendChild(document.createTextNode(tabStyleRule));
8608
8609		}
8610
8611		$('head').append(tabStyleSheet);
8612
8613	}());
8614
8615
8616
8617	// tab switch effects
8618
8619	var contentTabsEffect = {
8620
8621		none: {
8622
8623			show: function(o) {
8624
8625				o.tab.css({display:'block'});
8626
8627				if(o.complete) o.complete();
8628
8629			},
8630
8631			hide: function(o) {
8632
8633				o.tab.css({display:'none'});
8634
8635				if(o.complete) o.complete();
8636
8637			}
8638
8639		},
8640
8641		fade: {
8642
8643			show: function(o) {
8644
8645				if(o.fast) o.speed = 1;
8646
8647				o.tab.fadeIn(o.speed);
8648
8649				if(o.complete) setTimeout(o.complete, o.speed);
8650
8651			},
8652
8653			hide: function(o) {
8654
8655				if(o.fast) o.speed = 1;
8656
8657				o.tab.fadeOut(o.speed);
8658
8659				if(o.complete) setTimeout(o.complete, o.speed);
8660
8661			}
8662
8663		},
8664
8665		slide: {
8666
8667			show: function(o) {
8668
8669				var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true);
8670
8671				var tmpWrap = $('<div class="effect-div">').insertBefore(o.tab).append(o.tab);
8672
8673				tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'}); o.tab.css({marginTop:-tabHeight,display:'block'});
8674
8675				if(o.fast) o.speed = 1;
8676
8677				o.tab.animate({marginTop: 0}, {duration: o.speed, complete: function(){
8678
8679					o.tab.css({marginTop: '', width: ''}).insertBefore(tmpWrap);
8680
8681					tmpWrap.remove();
8682
8683					if(o.complete) o.complete();
8684
8685				}});
8686
8687			},
8688
8689			hide: function(o) {
8690
8691				var tabHeight = o.tab.show().css({width:o.tab.width()}).outerHeight(true);
8692
8693				var tmpWrap = $('<div class="effect-div">').insertBefore(o.tab).append(o.tab);
8694
8695				tmpWrap.css({width:'100%', overflow:'hidden', position:'relative'});
8696
8697
8698
8699				if(o.fast) o.speed = 1;
8700
8701				o.tab.animate({marginTop: -tabHeight}, {duration: o.speed, complete: function(){
8702
8703					o.tab.css({display:'none', marginTop:'', width:''}).insertBefore(tmpWrap);
8704
8705					tmpWrap.remove();
8706
8707					if(o.complete) o.complete();
8708
8709				}});
8710
8711			}
8712
8713		}
8714
8715	};
8716
8717}(jQuery));
8718
8719
8720
8721
8722
8723/*!
8724
8725 * JavaScript Custom Forms : Select Module
8726
8727 *
8728
8729 * Copyright 2014 PSD2HTML (http://psd2html.com)
8730
8731 * Released under the MIT license (LICENSE.txt)
8732
8733 *
8734
8735 * Version: 1.0.0
8736
8737 */
8738
8739;(function($, window) {
8740
8741	'use strict';
8742
8743
8744
8745	jcf.addModule({
8746
8747		name: 'Select',
8748
8749		selector: 'select',
8750
8751		options: {
8752
8753			element: null
8754
8755		},
8756
8757		plugins: {
8758
8759			ListBox: ListBox,
8760
8761			ComboBox: ComboBox,
8762
8763			SelectList: SelectList
8764
8765		},
8766
8767		matchElement: function(element) {
8768
8769			return element.is('select');
8770
8771		},
8772
8773		init: function() {
8774
8775			this.element = $(this.options.element);
8776
8777			this.createInstance();
8778
8779		},
8780
8781		isListBox: function() {
8782
8783			return this.element.is('[size]:not([jcf-size]), [multiple]');
8784
8785		},
8786
8787		createInstance: function() {
8788
8789			if(this.instance) {
8790
8791				this.instance.destroy();
8792
8793			}
8794
8795			if(this.isListBox()) {
8796
8797				this.instance = new ListBox(this.options);
8798
8799			} else {
8800
8801				this.instance = new ComboBox(this.options);
8802
8803			}
8804
8805		},
8806
8807		refresh: function() {
8808
8809			var typeMismatch = (this.isListBox() && this.instance instanceof ComboBox) ||
8810
8811								(!this.isListBox() && this.instance instanceof ListBox);
8812
8813
8814
8815			if(typeMismatch) {
8816
8817				this.createInstance();
8818
8819			} else {
8820
8821				this.instance.refresh();
8822
8823			}
8824
8825		},
8826
8827		destroy: function() {
8828
8829			this.instance.destroy();
8830
8831		}
8832
8833	});
8834
8835
8836
8837	// combobox module
8838
8839	function ComboBox(options) {
8840
8841		this.options = $.extend({
8842
8843			wrapNative: true,
8844
8845			wrapNativeOnMobile: true,
8846
8847			fakeDropInBody: true,
8848
8849			useCustomScroll: true,
8850
8851			flipDropToFit: true,
8852
8853			maxVisibleItems: 10,
8854
8855			fakeAreaStructure: '<span class="jcf-select"><span class="jcf-select-text"></span><span class="jcf-select-opener"></span></span>',
8856
8857			fakeDropStructure: '<div class="jcf-select-drop"><div class="jcf-select-drop-content"></div></div>',
8858
8859			optionClassPrefix: 'jcf-option-',
8860
8861			selectClassPrefix: 'jcf-select-',
8862
8863			dropContentSelector: '.jcf-select-drop-content',
8864
8865			selectTextSelector: '.jcf-select-text',
8866
8867			dropActiveClass: 'jcf-drop-active',
8868
8869			flipDropClass: 'jcf-drop-flipped'
8870
8871		}, options);
8872
8873		this.init();
8874
8875	}
8876
8877	$.extend(ComboBox.prototype, {
8878
8879		init: function(options) {
8880
8881			this.initStructure();
8882
8883			this.bindHandlers();
8884
8885			this.attachEvents();
8886
8887			this.refresh();
8888
8889		},
8890
8891		initStructure: function() {
8892
8893			// prepare structure
8894
8895			this.win = $(window);
8896
8897			this.doc = $(document);
8898
8899			this.realElement = $(this.options.element);
8900
8901			this.fakeElement = $(this.options.fakeAreaStructure).insertAfter(this.realElement);
8902
8903			this.selectTextContainer = this.fakeElement.find(this.options.selectTextSelector);
8904
8905			this.selectText = $('<span></span>').appendTo(this.selectTextContainer);
8906
8907			makeUnselectable(this.fakeElement);
8908
8909
8910
8911			// copy classes from original select
8912
8913			this.fakeElement.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix));
8914
8915
8916
8917			// detect device type and dropdown behavior
8918
8919			if(this.options.isMobileDevice && this.options.wrapNativeOnMobile && !this.options.wrapNative) {
8920
8921				this.options.wrapNative = true;
8922
8923			}
8924
8925
8926
8927			if(this.options.wrapNative) {
8928
8929				// wrap native select inside fake block
8930
8931				this.realElement.prependTo(this.fakeElement).css({
8932
8933					position: 'absolute',
8934
8935					height: '100%',
8936
8937					width: '100%'
8938
8939				}).addClass(this.options.resetAppearanceClass);
8940
8941			} else {
8942
8943				// just hide native select
8944
8945				this.realElement.addClass(this.options.hiddenClass);
8946
8947				this.fakeElement.attr('title', this.realElement.attr('title'));
8948
8949				this.fakeDropTarget = this.options.fakeDropInBody ? $('body') : this.fakeElement;
8950
8951			}
8952
8953		},
8954
8955		attachEvents: function() {
8956
8957			// delayed refresh handler
8958
8959			var self = this;
8960
8961			this.delayedRefresh = function() {
8962
8963				setTimeout(function() {
8964
8965					self.refresh();
8966
8967					if(self.list) {
8968
8969						self.list.refresh();
8970
8971					}
8972
8973				}, 1);
8974
8975			};
8976
8977
8978
8979			// native dropdown event handlers
8980
8981			if(this.options.wrapNative) {
8982
8983				this.realElement.on({
8984
8985					focus: this.onFocus,
8986
8987					change: this.onChange,
8988
8989					click: this.onChange,
8990
8991					keydown: this.onChange
8992
8993				});
8994
8995			} else {
8996
8997				// custom dropdown event handlers
8998
8999				this.realElement.on({
9000
9001					focus: this.onFocus,
9002
9003					change: this.onChange,
9004
9005					keydown: this.onKeyDown
9006
9007				});
9008
9009				this.fakeElement.on({
9010
9011					'jcf-pointerdown': this.onSelectAreaPress
9012
9013				});
9014
9015			}
9016
9017		},
9018
9019		onKeyDown: function(e) {
9020
9021			if(e.which === 13) {
9022
9023				this.toggleDropdown();
9024
9025			} else {
9026
9027				this.delayedRefresh();
9028
9029			}
9030
9031		},
9032
9033		onChange: function() {
9034
9035			this.refresh();
9036
9037		},
9038
9039		onFocus: function() {
9040
9041			if(!this.pressedFlag || !this.focusedFlag) {
9042
9043				this.fakeElement.addClass(this.options.focusClass);
9044
9045				this.realElement.on('blur', this.onBlur);
9046
9047				this.toggleListMode(true);
9048
9049				this.focusedFlag = true;
9050
9051			}
9052
9053		},
9054
9055		onBlur: function() {
9056
9057			if(!this.pressedFlag) {
9058
9059				this.fakeElement.removeClass(this.options.focusClass);
9060
9061				this.realElement.off('blur', this.onBlur);
9062
9063				this.toggleListMode(false);
9064
9065				this.focusedFlag = false;
9066
9067			}
9068
9069		},
9070
9071		onResize: function() {
9072
9073			if(this.dropActive) {
9074
9075				this.hideDropdown();
9076
9077			}
9078
9079		},
9080
9081		onSelectDropPress: function() {
9082
9083			this.pressedFlag = true;
9084
9085		},
9086
9087		onSelectDropRelease: function(e, pointerEvent) {
9088
9089			this.pressedFlag = false;
9090
9091			if(pointerEvent.pointerType === 'mouse') {
9092
9093				this.realElement.focus();
9094
9095			}
9096
9097		},
9098
9099		onSelectAreaPress: function(e) {
9100
9101			// skip click if drop inside fake element or real select is disabled
9102
9103			var dropClickedInsideFakeElement = !this.options.fakeDropInBody && $(e.target).closest(this.dropdown).length;
9104
9105			if(dropClickedInsideFakeElement || e.button > 1 || this.realElement.is(':disabled')) {
9106
9107				return;
9108
9109			}
9110
9111
9112
9113			// toggle dropdown visibility
9114
9115			this.toggleDropdown();
9116
9117
9118
9119			// misc handlers
9120
9121			if(!this.focusedFlag) {
9122
9123				if(e.pointerType === 'mouse') {
9124
9125					this.realElement.focus();
9126
9127				} else {
9128
9129					this.onFocus(e);
9130
9131				}
9132
9133			}
9134
9135			this.pressedFlag = true;
9136
9137			this.fakeElement.addClass(this.options.pressedClass);
9138
9139			this.doc.on('jcf-pointerup', this.onSelectAreaRelease);
9140
9141		},
9142
9143		onSelectAreaRelease: function(e) {
9144
9145			if(this.focusedFlag && e.pointerType === 'mouse') {
9146
9147				this.realElement.focus();
9148
9149			}
9150
9151			this.pressedFlag = false;
9152
9153			this.fakeElement.removeClass(this.options.pressedClass);
9154
9155			this.doc.off('jcf-pointerup', this.onSelectAreaRelease);
9156
9157		},
9158
9159		onOutsideClick: function(e) {
9160
9161			var target = $(e.target),
9162
9163				clickedInsideSelect = target.closest(this.fakeElement).length || target.closest(this.dropdown).length;
9164
9165
9166
9167			if(!clickedInsideSelect) {
9168
9169				this.hideDropdown();
9170
9171			}
9172
9173		},
9174
9175		onSelect: function() {
9176
9177			this.hideDropdown();
9178
9179			this.refresh();
9180
9181			this.fireNativeEvent(this.realElement, 'change');
9182
9183		},
9184
9185		toggleListMode: function(state) {
9186
9187			if(!this.options.wrapNative) {
9188
9189				if(state) {
9190
9191					// temporary change select to list to avoid appearing of native dropdown
9192
9193					this.realElement.attr({
9194
9195						size: 4,
9196
9197						'jcf-size': ''
9198
9199					});
9200
9201				} else {
9202
9203					// restore select from list mode to dropdown select
9204
9205					if(!this.options.wrapNative) {
9206
9207						this.realElement.removeAttr('size jcf-size');
9208
9209					}
9210
9211				}
9212
9213			}
9214
9215		},
9216
9217		createDropdown: function() {
9218
9219			// destroy previous dropdown if needed
9220
9221			if(this.dropdown) {
9222
9223				this.list.destroy();
9224
9225				this.dropdown.remove();
9226
9227			}
9228
9229
9230
9231			// create new drop container
9232
9233			this.dropdown = $(this.options.fakeDropStructure).appendTo(this.fakeDropTarget);
9234
9235			this.dropdown.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix));
9236
9237			makeUnselectable(this.dropdown);
9238
9239
9240
9241			// set initial styles for dropdown in body
9242
9243			if(this.options.fakeDropInBody) {
9244
9245				this.dropdown.css({
9246
9247					position: 'absolute',
9248
9249					top: -9999
9250
9251				});
9252
9253			}
9254
9255
9256
9257			// create new select list instance
9258
9259			this.list = new SelectList({
9260
9261				useHoverClass: true,
9262
9263				handleResize: false,
9264
9265				alwaysPreventMouseWheel: true,
9266
9267				maxVisibleItems: this.options.maxVisibleItems,
9268
9269				useCustomScroll: this.options.useCustomScroll,
9270
9271				holder: this.dropdown.find(this.options.dropContentSelector),
9272
9273				element: this.realElement
9274
9275			});
9276
9277			$(this.list).on({
9278
9279				select: this.onSelect,
9280
9281				press: this.onSelectDropPress,
9282
9283				release: this.onSelectDropRelease
9284
9285			});
9286
9287		},
9288
9289		repositionDropdown: function() {
9290
9291			var selectOffset = this.fakeElement.offset(),
9292
9293				selectWidth = this.fakeElement.outerWidth(),
9294
9295				selectHeight = this.fakeElement.outerHeight(),
9296
9297				dropHeight = this.dropdown.outerHeight(),
9298
9299				winScrollTop = this.win.scrollTop(),
9300
9301				winHeight = this.win.height(),
9302
9303				calcTop, calcLeft, bodyOffset, needFlipDrop = false;
9304
9305
9306
9307			// check flip drop position
9308
9309			if(selectOffset.top + selectHeight + dropHeight > winScrollTop + winHeight && selectOffset.top - dropHeight > winScrollTop) {
9310
9311				needFlipDrop = true;
9312
9313			}
9314
9315
9316
9317			if(this.options.fakeDropInBody) {
9318
9319				bodyOffset = this.fakeDropTarget.css('position') !== 'static' ? this.fakeDropTarget.offset().top : 0;
9320
9321				if(this.options.flipDropToFit && needFlipDrop) {
9322
9323					// calculate flipped dropdown position
9324
9325					calcLeft = selectOffset.left;
9326
9327					calcTop = selectOffset.top - dropHeight - bodyOffset;
9328
9329				} else {
9330
9331					// calculate default drop position
9332
9333					calcLeft = selectOffset.left;
9334
9335					calcTop = selectOffset.top + selectHeight - bodyOffset;
9336
9337				}
9338
9339
9340
9341				// update drop styles
9342
9343				this.dropdown.css({
9344
9345					width: selectWidth,
9346
9347					left: calcLeft,
9348
9349					top: calcTop
9350
9351				});
9352
9353			}
9354
9355
9356
9357			// refresh flipped class
9358
9359			this.dropdown.add(this.fakeElement).toggleClass(this.options.flipDropClass, this.options.flipDropToFit && needFlipDrop);
9360
9361		},
9362
9363		showDropdown: function() {
9364
9365			// create options list if not created
9366
9367			if(!this.dropdown) {
9368
9369				this.createDropdown();
9370
9371			}
9372
9373
9374
9375			// show dropdown
9376
9377			this.dropActive = true;
9378
9379			this.dropdown.appendTo(this.fakeDropTarget);
9380
9381			this.fakeElement.addClass(this.options.dropActiveClass);
9382
9383			this.refreshSelectedText();
9384
9385			this.repositionDropdown();
9386
9387			this.list.setScrollTop(this.savedScrollTop);
9388
9389			this.list.refresh();
9390
9391
9392
9393			// add temporary event handlers
9394
9395			this.win.on('resize', this.onResize);
9396
9397			this.doc.on('jcf-pointerdown', this.onOutsideClick);
9398
9399		},
9400
9401		hideDropdown: function() {
9402
9403			if(this.dropdown) {
9404
9405				this.savedScrollTop = this.list.getScrollTop();
9406
9407				this.fakeElement.removeClass(this.options.dropActiveClass + ' ' + this.options.flipDropClass);
9408
9409				this.dropdown.removeClass(this.options.flipDropClass).detach();
9410
9411				this.doc.off('jcf-pointerdown', this.onOutsideClick);
9412
9413				this.win.off('resize', this.onResize);
9414
9415				this.dropActive = false;
9416
9417			}
9418
9419		},
9420
9421		toggleDropdown: function() {
9422
9423			if(this.dropActive) {
9424
9425				this.hideDropdown();
9426
9427			} else {
9428
9429				this.showDropdown();
9430
9431			}
9432
9433		},
9434
9435		refreshSelectedText: function() {
9436
9437			// redraw selected area
9438
9439			var selectedIndex = this.realElement.prop('selectedIndex'),
9440
9441				selectedOption = this.realElement.prop('options')[selectedIndex],
9442
9443				selectedOptionImage = selectedOption.getAttribute('data-image'),
9444
9445				selectedOptionClasses,
9446
9447				selectedFakeElement;
9448
9449
9450
9451			if(this.currentSelectedText !== selectedOption.innerHTML || this.currentSelectedImage !== selectedOptionImage) {
9452
9453				selectedOptionClasses = getPrefixedClasses(selectedOption.className, this.options.optionClassPrefix);
9454
9455				this.selectText.attr('class', selectedOptionClasses).html(selectedOption.innerHTML);
9456
9457
9458
9459				if(selectedOptionImage) {
9460
9461					if(!this.selectImage) {
9462
9463						this.selectImage = $('<img>').prependTo(this.selectTextContainer).hide();
9464
9465					}
9466
9467					this.selectImage.attr('src', selectedOptionImage).show();
9468
9469				} else if(this.selectImage) {
9470
9471					this.selectImage.hide();
9472
9473				}
9474
9475
9476
9477				this.currentSelectedText = selectedOption.innerHTML;
9478
9479				this.currentSelectedImage = selectedOptionImage;
9480
9481			}
9482
9483		},
9484
9485		refresh: function() {
9486
9487			// refresh fake select visibility
9488
9489			if(this.realElement.prop('style').display === 'none') {
9490
9491				this.fakeElement.hide();
9492
9493			} else {
9494
9495				this.fakeElement.show();
9496
9497			}
9498
9499
9500
9501			// refresh selected text
9502
9503			this.refreshSelectedText();
9504
9505
9506
9507			// handle disabled state
9508
9509			this.fakeElement.toggleClass(this.options.disabledClass, this.realElement.is(':disabled'));
9510
9511		},
9512
9513		destroy: function() {
9514
9515			// restore structure
9516
9517			if(this.options.wrapNative) {
9518
9519				this.realElement.insertBefore(this.fakeElement).css({
9520
9521					position: '',
9522
9523					height: '',
9524
9525					width: ''
9526
9527				}).removeClass(this.options.resetAppearanceClass);
9528
9529			} else {
9530
9531				this.realElement.removeClass(this.options.hiddenClass);
9532
9533				if(this.realElement.is('[jcf-size]')) {
9534
9535					this.realElement.removeAttr('size jcf-size');
9536
9537				}
9538
9539			}
9540
9541
9542
9543			// removing element will also remove its event handlers
9544
9545			this.fakeElement.remove();
9546
9547
9548
9549			// remove other event handlers
9550
9551			this.doc.off('jcf-pointerup', this.onSelectAreaRelease);
9552
9553			this.realElement.off({
9554
9555				focus: this.onFocus
9556
9557			});
9558
9559		}
9560
9561	});
9562
9563
9564
9565	// listbox module
9566
9567	function ListBox(options) {
9568
9569		this.options = $.extend({
9570
9571			wrapNative: true,
9572
9573			useCustomScroll: true,
9574
9575			fakeStructure: '<span class="jcf-list-box"><span class="jcf-list-wrapper"></span></span>',
9576
9577			selectClassPrefix: 'jcf-select-',
9578
9579			listHolder: '.jcf-list-wrapper'
9580
9581		}, options);
9582
9583		this.init();
9584
9585	}
9586
9587	$.extend(ListBox.prototype, {
9588
9589		init: function(options) {
9590
9591			this.bindHandlers();
9592
9593			this.initStructure();
9594
9595			this.attachEvents();
9596
9597		},
9598
9599		initStructure: function() {
9600
9601			var self = this;
9602
9603			this.realElement = $(this.options.element);
9604
9605			this.fakeElement = $(this.options.fakeStructure).insertAfter(this.realElement);
9606
9607			this.listHolder = this.fakeElement.find(this.options.listHolder);
9608
9609			makeUnselectable(this.fakeElement);
9610
9611
9612
9613			// copy classes from original select
9614
9615			this.fakeElement.addClass(getPrefixedClasses(this.realElement.prop('className'), this.options.selectClassPrefix));
9616
9617			this.realElement.addClass(this.options.hiddenClass);
9618
9619
9620
9621			this.list = new SelectList({
9622
9623				useCustomScroll: this.options.useCustomScroll,
9624
9625				holder: this.listHolder,
9626
9627				selectOnClick: false,
9628
9629				element: this.realElement
9630
9631			});
9632
9633		},
9634
9635		attachEvents: function() {
9636
9637			// delayed refresh handler
9638
9639			var self = this;
9640
9641			this.delayedRefresh = function() {
9642
9643				clearTimeout(self.refreshTimer);
9644
9645				self.refreshTimer = setTimeout(function() {
9646
9647					self.refresh();
9648
9649				}, 1);
9650
9651			};
9652
9653
9654
9655			// other event handlers
9656
9657			this.realElement.on({
9658
9659				focus: this.onFocus,
9660
9661				click: this.delayedRefresh,
9662
9663				keydown: this.delayedRefresh
9664
9665			});
9666
9667
9668
9669			// select list event handlers
9670
9671			$(this.list).on({
9672
9673				select: this.onSelect,
9674
9675				press: this.onFakeOptionsPress,
9676
9677				release: this.onFakeOptionsRelease
9678
9679			});
9680
9681		},
9682
9683		onFakeOptionsPress: function(e, pointerEvent) {
9684
9685			this.pressedFlag = true;
9686
9687			if(pointerEvent.pointerType === 'mouse') {
9688
9689				this.realElement.focus();
9690
9691			}
9692
9693		},
9694
9695		onFakeOptionsRelease: function(e, pointerEvent) {
9696
9697			this.pressedFlag = false;
9698
9699			if(pointerEvent.pointerType === 'mouse') {
9700
9701				this.realElement.focus();
9702
9703			}
9704
9705		},
9706
9707		onSelect: function() {
9708
9709			this.fireNativeEvent(this.realElement, 'change');
9710
9711			this.fireNativeEvent(this.realElement, 'click');
9712
9713		},
9714
9715		onFocus: function() {
9716
9717			if(!this.pressedFlag || !this.focusedFlag) {
9718
9719				this.fakeElement.addClass(this.options.focusClass);
9720
9721				this.realElement.on('blur', this.onBlur);
9722
9723				this.focusedFlag = true;
9724
9725			}
9726
9727		},
9728
9729		onBlur: function() {
9730
9731			if(!this.pressedFlag) {
9732
9733				this.fakeElement.removeClass(this.options.focusClass);
9734
9735				this.realElement.off('blur', this.onBlur);
9736
9737				this.focusedFlag = false;
9738
9739			}
9740
9741		},
9742
9743		refresh: function() {
9744
9745			this.fakeElement.toggleClass(this.options.disabledClass, this.realElement.is(':disabled'));
9746
9747			this.list.refresh();
9748
9749		},
9750
9751		destroy: function() {
9752
9753			this.list.destroy();
9754
9755			this.realElement.insertBefore(this.fakeElement).removeClass(this.options.hiddenClass);
9756
9757			this.fakeElement.remove();
9758
9759		}
9760
9761	});
9762
9763
9764
9765	// options list module
9766
9767	function SelectList(options) {
9768
9769		this.options = $.extend({
9770
9771			holder: null,
9772
9773			maxVisibleItems: 10,
9774
9775			selectOnClick: true,
9776
9777			useHoverClass: false,
9778
9779			useCustomScroll: false,
9780
9781			handleResize: true,
9782
9783			alwaysPreventMouseWheel: false,
9784
9785			indexAttribute: 'data-index',
9786
9787			cloneClassPrefix: 'jcf-option-',
9788
9789			containerStructure: '<span class="jcf-list"><span class="jcf-list-content"></span></span>',
9790
9791			containerSelector: '.jcf-list-content',
9792
9793			captionClass: 'jcf-optgroup-caption',
9794
9795			disabledClass: 'jcf-disabled',
9796
9797			optionClass: 'jcf-option',
9798
9799			groupClass: 'jcf-optgroup',
9800
9801			hoverClass: 'jcf-hover',
9802
9803			selectedClass: 'jcf-selected',
9804
9805			scrollClass: 'jcf-scroll-active'
9806
9807		}, options);
9808
9809		this.init();
9810
9811	}
9812
9813	$.extend(SelectList.prototype, {
9814
9815		init: function() {
9816
9817			this.initStructure();
9818
9819			this.refreshSelectedClass();
9820
9821			this.attachEvents();
9822
9823		},
9824
9825		initStructure: function() {
9826
9827			this.element = $(this.options.element);
9828
9829			this.indexSelector = '[' + this.options.indexAttribute + ']';
9830
9831			this.container = $(this.options.containerStructure).appendTo(this.options.holder);
9832
9833			this.listHolder = this.container.find(this.options.containerSelector);
9834
9835			this.lastClickedIndex = this.element.prop('selectedIndex');
9836
9837			this.rebuildList();
9838
9839		},
9840
9841		attachEvents: function() {
9842
9843			this.bindHandlers();
9844
9845			this.listHolder.on('jcf-pointerdown', this.indexSelector, this.onItemPress);
9846
9847			this.listHolder.on('jcf-pointerdown', this.onPress);
9848
9849
9850
9851			if(this.options.useHoverClass) {
9852
9853				this.listHolder.on('jcf-pointerover', this.indexSelector, this.onHoverItem);
9854
9855			}
9856
9857		},
9858
9859		onPress: function(e) {
9860
9861			$(this).trigger('press', e);
9862
9863			this.listHolder.on('jcf-pointerup', this.onRelease);
9864
9865		},
9866
9867		onRelease: function(e) {
9868
9869			$(this).trigger('release', e);
9870
9871			this.listHolder.off('jcf-pointerup', this.onRelease);
9872
9873		},
9874
9875		onHoverItem: function(e) {
9876
9877			var hoverIndex = parseFloat(e.currentTarget.getAttribute(this.options.indexAttribute));
9878
9879			this.fakeOptions.removeClass(this.options.hoverClass).eq(hoverIndex).addClass(this.options.hoverClass);
9880
9881		},
9882
9883		onItemPress: function(e) {
9884
9885			if(e.pointerType === 'touch' || this.options.selectOnClick) {
9886
9887				// select option after "click"
9888
9889				this.tmpListOffsetTop = this.list.offset().top;
9890
9891				this.listHolder.on('jcf-pointerup', this.indexSelector, this.onItemRelease);
9892
9893			} else {
9894
9895				// select option immediately
9896
9897				this.onSelectItem(e);
9898
9899			}
9900
9901		},
9902
9903		onItemRelease: function(e) {
9904
9905			// remove event handlers and temporary data
9906
9907			this.listHolder.off('jcf-pointerup', this.indexSelector, this.onItemRelease);
9908
9909
9910
9911			// simulate item selection
9912
9913			if(this.tmpListOffsetTop === this.list.offset().top) {
9914
9915				this.listHolder.on('click', this.indexSelector, this.onSelectItem);
9916
9917			}
9918
9919			delete this.tmpListOffsetTop;
9920
9921		},
9922
9923		onSelectItem: function(e) {
9924
9925			var clickedIndex = parseFloat(e.currentTarget.getAttribute(this.options.indexAttribute)),
9926
9927				range;
9928
9929
9930
9931			// remove click event handler
9932
9933			this.listHolder.off('click', this.indexSelector, this.onSelectItem);
9934
9935
9936
9937			// ignore clicks on disabled options
9938
9939			if(e.button > 1 || this.realOptions[clickedIndex].disabled) {
9940
9941				return;
9942
9943			}
9944
9945
9946
9947			if(this.element.prop('multiple')) {
9948
9949				if(e.metaKey || e.ctrlKey || e.pointerType === 'touch') {
9950
9951					// if CTRL/CMD pressed or touch devices - toggle selected option
9952
9953					this.realOptions[clickedIndex].selected = !this.realOptions[clickedIndex].selected;
9954
9955				} else if(e.shiftKey) {
9956
9957					// if SHIFT pressed - update selection
9958
9959					range = [this.lastClickedIndex, clickedIndex].sort(function(a, b){
9960
9961						return a - b;
9962
9963					});
9964
9965					this.realOptions.each(function(index, option) {
9966
9967						option.selected = (index >= range[0] && index <= range[1]);
9968
9969					});
9970
9971				} else {
9972
9973					// set single selected index
9974
9975					this.element.prop('selectedIndex', clickedIndex);
9976
9977				}
9978
9979			} else {
9980
9981				this.element.prop('selectedIndex', clickedIndex);
9982
9983			}
9984
9985
9986
9987			// save last clicked option
9988
9989			if(!e.shiftKey) {
9990
9991				this.lastClickedIndex = clickedIndex;
9992
9993			}
9994
9995
9996
9997			// refresh classes
9998
9999			this.refreshSelectedClass();
10000
10001
10002
10003			// scroll to active item in desktop browsers
10004
10005			if(e.pointerType === 'mouse') {
10006
10007				this.scrollToActiveOption();
10008
10009			}
10010
10011
10012
10013			// make callback when item selected
10014
10015			$(this).trigger('select');
10016
10017		},
10018
10019		rebuildList: function() {
10020
10021			// rebuild options
10022
10023			var self = this,
10024
10025				rootElement = this.element[0];
10026
10027
10028
10029			// recursively create fake options
10030
10031			this.storedSelectHTML = rootElement.innerHTML;
10032
10033			this.optionIndex = 0;
10034
10035			this.list = $(this.createOptionsList(rootElement));
10036
10037			this.listHolder.empty().append(this.list);
10038
10039			this.realOptions = this.element.find('option');
10040
10041			this.fakeOptions = this.list.find(this.indexSelector);
10042
10043			this.fakeListItems = this.list.find('.' + this.options.captionClass + ',' + this.indexSelector);
10044
10045			delete this.optionIndex;
10046
10047
10048
10049			// detect max visible items
10050
10051			var maxCount = this.options.maxVisibleItems,
10052
10053				sizeValue = this.element.prop('size');
10054
10055			if(sizeValue > 1) {
10056
10057				maxCount = sizeValue;
10058
10059			}
10060
10061
10062
10063			// handle scrollbar
10064
10065			var needScrollBar = this.fakeOptions.length > maxCount;
10066
10067			this.container.toggleClass(this.options.scrollClass, needScrollBar);
10068
10069			if(needScrollBar) {
10070
10071				// change max-height
10072
10073				this.listHolder.css({
10074
10075					maxHeight: this.getOverflowHeight(maxCount),
10076
10077					overflow: 'auto'
10078
10079				});
10080
10081
10082
10083				if(this.options.useCustomScroll && jcf.modules.Scrollable) {
10084
10085					// add custom scrollbar if specified in options
10086
10087					jcf.replace(this.listHolder, 'Scrollable', {
10088
10089						handleResize: this.options.handleResize,
10090
10091						alwaysPreventMouseWheel: this.options.alwaysPreventMouseWheel
10092
10093					});
10094
10095					return;
10096
10097				}
10098
10099			}
10100
10101
10102
10103			// disable edge wheel scrolling
10104
10105			if(this.options.alwaysPreventMouseWheel) {
10106
10107				this.preventWheelHandler = function(e) {
10108
10109					var currentScrollTop = self.listHolder.scrollTop(),
10110
10111						maxScrollTop = self.listHolder.prop('scrollHeight') - self.listHolder.innerHe
10111ight(),
10112
10113						maxScrollLeft = self.listHolder.prop('scrollWidth') - self.listHolder.innerWidth();
10114
10115
10116
10117					// check edge cases
10118
10119					if((currentScrollTop <= 0 && e.deltaY < 0) || (currentScrollTop >= maxScrollTop && e.deltaY > 0)) {
10120
10121						e.preventDefault();
10122
10123					}
10124
10125				};
10126
10127				this.listHolder.on('jcf-mousewheel', this.preventWheelHandler);
10128
10129			}
10130
10131		},
10132
10133		refreshSelectedClass: function() {
10134
10135			var self = this,
10136
10137				selectedItem,
10138
10139				isMultiple = this.element.prop('multiple'),
10140
10141				selectedIndex = this.element.prop('selectedIndex');
10142
10143
10144
10145			if(isMultiple) {
10146
10147				this.realOptions.each(function(index, option) {
10148
10149					self.fakeOptions.eq(index).toggleClass(self.options.selectedClass, !!option.selected);
10150
10151				});
10152
10153			} else {
10154
10155				this.fakeOptions.removeClass(this.options.selectedClass + ' ' + this.options.hoverClass);
10156
10157				selectedItem = this.fakeOptions.eq(selectedIndex).addClass(this.options.selectedClass);
10158
10159				if(this.options.useHoverClass) {
10160
10161					selectedItem.addClass(this.options.hoverClass);
10162
10163				}
10164
10165			}
10166
10167		},
10168
10169		scrollToActiveOption: function() {
10170
10171			// scroll to target option
10172
10173			var targetOffset = this.getActiveOptionOffset();
10174
10175			this.listHolder.prop('scrollTop', targetOffset);
10176
10177		},
10178
10179		getSelectedIndexRange: function() {
10180
10181			var firstSelected = -1, lastSelected = -1;
10182
10183			this.realOptions.each(function(index, option) {
10184
10185				if(option.selected) {
10186
10187					if(firstSelected < 0) {
10188
10189						firstSelected = index;
10190
10191					}
10192
10193					lastSelected = index;
10194
10195				}
10196
10197			});
10198
10199			return [firstSelected, lastSelected];
10200
10201		},
10202
10203		getChangedSelectedIndex: function() {
10204
10205			var selectedIndex = this.element.prop('selectedIndex'),
10206
10207				targetIndex;
10208
10209
10210
10211			if(this.element.prop('multiple')) {
10212
10213				// multiple selects handling
10214
10215				if(!this.previousRange) {
10216
10217					this.previousRange = [selectedIndex, selectedIndex];
10218
10219				}
10220
10221				this.currentRange = this.getSelectedIndexRange();
10222
10223				targetIndex = this.currentRange[this.currentRange[0] !== this.previousRange[0] ? 0 : 1];
10224
10225				this.previousRange = this.currentRange;
10226
10227				return targetIndex;
10228
10229			} else {
10230
10231				// single choice selects handling
10232
10233				return selectedIndex;
10234
10235			}
10236
10237		},
10238
10239		getActiveOptionOffset: function() {
10240
10241			// calc values
10242
10243			var dropHeight = this.listHolder.height(),
10244
10245				dropScrollTop = this.listHolder.prop('scrollTop'),
10246
10247				currentIndex = this.getChangedSelectedIndex(),
10248
10249				fakeOption = this.fakeOptions.eq(currentIndex),
10250
10251				fakeOptionOffset = fakeOption.offset().top - this.list.offset().top,
10252
10253				fakeOptionHeight = fakeOption.innerHeight();
10254
10255
10256
10257			// scroll list
10258
10259			if(fakeOptionOffset + fakeOptionHeight >= dropScrollTop + dropHeight) {
10260
10261				// scroll down (always scroll to option)
10262
10263				return fakeOptionOffset - dropHeight + fakeOptionHeight;
10264
10265			} else if(fakeOptionOffset < dropScrollTop) {
10266
10267				// scroll up to option
10268
10269				return fakeOptionOffset;
10270
10271			}
10272
10273		},
10274
10275		getOverflowHeight: function(sizeValue) {
10276
10277			var item = this.fakeListItems.eq(sizeValue - 1),
10278
10279				listOffset = this.list.offset().top,
10280
10281				itemOffset = item.offset().top,
10282
10283				itemHeight = item.innerHeight();
10284
10285
10286
10287			return itemOffset + itemHeight - listOffset;
10288
10289		},
10290
10291		getScrollTop: function() {
10292
10293			return this.listHolder.scrollTop();
10294
10295		},
10296
10297		setScrollTop: function(value) {
10298
10299			this.listHolder.scrollTop(value);
10300
10301		},
10302
10303		createOption: function(option) {
10304
10305			var newOption = document.createElement('span');
10306
10307			newOption.className = this.options.optionClass;
10308
10309			newOption.innerHTML = option.innerHTML;
10310
10311			newOption.setAttribute(this.options.indexAttribute, this.optionIndex++);
10312
10313
10314
10315			var optionImage, optionImageSrc = option.getAttribute('data-image');
10316
10317			if(optionImageSrc) {
10318
10319				optionImage = document.createElement('img');
10320
10321				optionImage.src = optionImageSrc;
10322
10323				newOption.insertBefore(optionImage, newOption.childNodes[0]);
10324
10325			}
10326
10327			if(option.disabled) {
10328
10329				newOption.className += ' ' + this.options.disabledClass;
10330
10331			}
10332
10333			if(option.className) {
10334
10335				newOption.className += ' ' + getPrefixedClasses(option.className, this.options.cloneClassPrefix);
10336
10337			}
10338
10339			return newOption;
10340
10341		},
10342
10343		createOptGroup: function(optgroup) {
10344
10345			var optGroupContainer = document.createElement('span'),
10346
10347				optGroupName = optgroup.getAttribute('label'),
10348
10349				optGroupCaption, optGroupList;
10350
10351
10352
10353			// create caption
10354
10355			optGroupCaption = document.createElement('span');
10356
10357			optGroupCaption.className = this.options.captionClass;
10358
10359			optGroupCaption.innerHTML = optGroupName;
10360
10361			optGroupContainer.appendChild(optGroupCaption);
10362
10363
10364
10365			// create list of options
10366
10367			if(optgroup.children.length) {
10368
10369				optGroupList = this.createOptionsList(optgroup);
10370
10371				optGroupContainer.appendChild(optGroupList);
10372
10373			}
10374
10375
10376
10377			optGroupContainer.className = this.options.groupClass;
10378
10379			return optGroupContainer;
10380
10381		},
10382
10383		createOptionContainer: function() {
10384
10385			var optionContainer = document.createElement('li');
10386
10387			return optionContainer;
10388
10389		},
10390
10391		createOptionsList: function(container) {
10392
10393			var self = this,
10394
10395				list = document.createElement('ul');
10396
10397
10398
10399			$.each(container.children, function(index, currentNode) {
10400
10401				var item = self.createOptionContainer(currentNode),
10402
10403					newNode;
10404
10405
10406
10407				switch(currentNode.tagName.toLowerCase()) {
10408
10409					case 'option': newNode = self.createOption(currentNode); break;
10410
10411					case 'optgroup': newNode = self.createOptGroup(currentNode); break;
10412
10413				}
10414
10415				list.appendChild(item).appendChild(newNode);
10416
10417			});
10418
10419			return list;
10420
10421		},
10422
10423		refresh: function() {
10424
10425			// check for select innerHTML changes
10426
10427			if(this.storedSelectHTML !== this.element.prop('innerHTML')) {
10428
10429				this.rebuildList();
10430
10431			}
10432
10433
10434
10435			// refresh custom scrollbar
10436
10437			var scrollInstance = jcf.getInstance(this.listHolder);
10438
10439			if(scrollInstance) {
10440
10441				scrollInstance.refresh();
10442
10443			}
10444
10445
10446
10447			// scroll active option into view
10448
10449			this.scrollToActiveOption();
10450
10451
10452
10453			// refresh selectes classes
10454
10455			this.refreshSelectedClass();
10456
10457		},
10458
10459		destroy: function() {
10460
10461			this.listHolder.off('jcf-mousewheel', this.preventWheelHandler);
10462
10463			this.listHolder.off('jcf-pointerdown', this.indexSelector, this.onSelectItem);
10464
10465			this.listHolder.off('jcf-pointerover', this.indexSelector, this.onHoverItem);
10466
10467			this.listHolder.off('jcf-pointerdown', this.onPress);
10468
10469		}
10470
10471	});
10472
10473
10474
10475	// helper functions
10476
10477	var getPrefixedClasses = function(className, prefixToAdd) {
10478
10479		return className ? className.replace(/[\s]*([\S]+)+[\s]*/gi, prefixToAdd + '$1 ') : '';
10480
10481	};
10482
10483	var makeUnselectable = (function() {
10484
10485		var unselectableClass = jcf.getOptions().unselectableClass;
10486
10487		function preventHandler(e) {
10488
10489			e.preventDefault();
10490
10491		}
10492
10493		return function(node) {
10494
10495			node.addClass(unselectableClass).on('selectstart', preventHandler);
10496
10497		};
10498
10499	}());
10500
10501
10502
10503}(jQuery, this));
10504
10505
10506
10507
10508
10509/*!* SmoothScroll module*/
10510
10511
10512
10513;(function($, exports) {
10514
10515	// private variables
10516
10517	var page,
10518
10519		win = $(window),
10520
10521		activeBlock, activeWheelHandler,
10522
10523		wheelEvents = ('onwheel' in document || document.documentMode >= 9 ? 'wheel' : 'mousewheel DOMMouseScroll');
10524
10525
10526
10527	// animation handlers
10528
10529	function scrollTo(offset, options, callback) {
10530
10531		// initialize variables
10532
10533		var scrollBlock;
10534
10535		if (document.body) {
10536
10537			if (typeof options === 'number') {
10538
10539				options = { duration: options };
10540
10541			} else {
10542
10543				options = options || {};
10544
10545			}
10546
10547			page = page || $('html, body');
10548
10549			scrollBlock = options.container || page;
10550
10551		} else {
10552
10553			return;
10554
10555		}
10556
10557
10558
10559		// treat single number as scrollTop
10560
10561		if (typeof offset === 'number') {
10562
10563			offset = { top: offset };
10564
10565		}
10566
10567
10568
10569		// handle mousewheel/trackpad while animation is active
10570
10571		if (activeBlock && activeWheelHandler) {
10572
10573			activeBlock.off(wheelEvents, activeWheelHandler);
10574
10575		}
10576
10577		if (options.wheelBehavior && options.wheelBehavior !== 'none') {
10578
10579			activeWheelHandler = function(e) {
10580
10581				if (options.wheelBehavior === 'stop') {
10582
10583					scrollBlock.off(wheelEvents, activeWheelHandler);
10584
10585					scrollBlock.stop();
10586
10587				} else if (options.wheelBehavior === 'ignore') {
10588
10589					e.preventDefault();
10590
10591				}
10592
10593			};
10594
10595			activeBlock = scrollBlock.on(wheelEvents, activeWheelHandler);
10596
10597		}
10598
10599
10600
10601		// start scrolling animation
10602
10603		scrollBlock.stop().animate({
10604
10605			scrollLeft: offset.left,
10606
10607			scrollTop: offset.top
10608
10609		}, options.duration, function() {
10610
10611			if (activeWheelHandler) {
10612
10613				scrollBlock.off(wheelEvents, activeWheelHandler);
10614
10615			}
10616
10617			if ($.isFunction(callback)) {
10618
10619				callback();
10620
10621			}
10622
10623		});
10624
10625	}
10626
10627
10628
10629	// smooth scroll contstructor
10630
10631	function SmoothScroll(options) {
10632
10633		this.options = $.extend({
10634
10635			anchorLinks: 'a[href^="#"]',	// selector or jQuery object
10636
10637			container: null,		// specify container for scrolling (default - whole page)
10638
10639			extraOffset: null,		// function or fixed number
10640
10641			activeClasses: null,	// null, "link", "parent"
10642
10643			easing: 'swing',		// easing of scrolling
10644
10645			animMode: 'duration',	// or "speed" mode
10646
10647			animDuration: 800,		// total duration for scroll (any distance)
10648
10649			animSpeed: 1500,		// pixels per second
10650
10651			anchorActiveClass: 'active',
10652
10653			sectionActiveClass: 'section-active',
10654
10655			wheelBehavior: 'stop', // "stop", "ignore" or "none"
10656
10657			useNativeAnchorScrolling: false // do not handle click in devices with native smooth scrolling
10658
10659		}, options);
10660
10661		this.init();
10662
10663	}
10664
10665	SmoothScroll.prototype = {
10666
10667		init: function() {
10668
10669			this.initStructure();
10670
10671			this.attachEvents();
10672
10673		},
10674
10675		initStructure: function() {
10676
10677			this.container = this.options.container ? $(this.options.container) : $('html,body');
10678
10679			this.scrollContainer = this.options.container ? this.container : win;
10680
10681			this.anchorLinks = $(this.options.anchorLinks);
10682
10683		},
10684
10685		getAnchorTarget: function(link) {
10686
10687			// get target block from link href
10688
10689			var targetId = $(link).attr('href');
10690
10691			return $(targetId.length > 1 ? targetId : 'html');
10692
10693		},
10694
10695		getTargetOffset: function(block) {
10696
10697			// get target offset
10698
10699			var blockOffset = block.offset().top;
10700
10701			if (this.options.container) {
10702
10703				blockOffset -= this.container.offset().top - this.container.prop('scrollTop');
10704
10705			}
10706
10707
10708
10709			// handle extra offset
10710
10711			if (typeof this.options.extraOffset === 'number') {
10712
10713				blockOffset -= this.options.extraOffset;
10714
10715			} else if (typeof this.options.extraOffset === 'function') {
10716
10717				blockOffset -= this.options.extraOffset(block);
10718
10719			}
10720
10721			return { top: blockOffset };
10722
10723		},
10724
10725		attachEvents: function() {
10726
10727			var self = this;
10728
10729
10730
10731			// handle active classes
10732
10733			if (this.options.activeClasses) {
10734
10735				// cache structure
10736
10737				this.anchorData = [];
10738
10739				this.anchorLinks.each(function() {
10740
10741					var link = jQuery(this),
10742
10743						targetBlock = self.getAnchorTarget(link),
10744
10745						anchorDataItem;
10746
10747
10748
10749					$.each(self.anchorData, function(index, item) {
10750
10751						if (item.block[0] === targetBlock[0]) {
10752
10753							anchorDataItem = item;
10754
10755						}
10756
10757					});
10758
10759
10760
10761					if (anchorDataItem) {
10762
10763						anchorDataItem.link = anchorDataItem.link.add(link);
10764
10765					} else {
10766
10767						self.anchorData.push({
10768
10769							link: link,
10770
10771							block: targetBlock
10772
10773						});
10774
10775					}
10776
10777				});
10778
10779
10780
10781				// add additional event handlers
10782
10783				this.resizeHandler = function() {
10784
10785					self.recalculateOffsets();
10786
10787				};
10788
10789				this.scrollHandler = function() {
10790
10791					self.refreshActiveClass();
10792
10793				};
10794
10795
10796
10797				this.recalculateOffsets();
10798
10799				this.scrollContainer.on('scroll', this.scrollHandler);
10800
10801				win.on('resize', this.resizeHandler);
10802
10803			}
10804
10805
10806
10807			// handle click event
10808
10809			this.clickHandler = function(e) {
10810
10811				self.onClick(e);
10812
10813			};
10814
10815			if (!this.options.useNativeAnchorScrolling) {
10816
10817				this.anchorLinks.on('click', this.clickHandler);
10818
10819			}
10820
10821		},
10822
10823		recalculateOffsets: function() {
10824
10825			var self = this;
10826
10827			$.each(this.anchorData, function(index, data) {
10828
10829				data.offset = self.getTargetOffset(data.block);
10830
10831				data.height = data.block.outerHeight();
10832
10833			});
10834
10835			this.refreshActiveClass();
10836
10837		},
10838
10839		refreshActiveClass: function() {
10840
10841			var self = this,
10842
10843				foundFlag = false,
10844
10845				containerHeight = this.container.prop('scrollHeight'),
10846
10847				viewPortHeight = this.scrollContainer.height(),
10848
10849				scrollTop = this.options.container ? this.container.prop('scrollTop') : win.scrollTop();
10850
10851
10852
10853			// user function instead of default handler
10854
10855			if (this.options.customScrollHandler) {
10856
10857				this.options.customScrollHandler.call(this, scrollTop, this.anchorData);
10858
10859				return;
10860
10861			}
10862
10863
10864
10865			// sort anchor data by offsets
10866
10867			this.anchorData.sort(function(a, b) {
10868
10869				return a.offset.top - b.offset.top;
10870
10871			});
10872
10873			function toggleActiveClass(anchor, block, state) {
10874
10875				anchor.toggleClass(self.options.anchorActiveClass, state);
10876
10877				block.toggleClass(self.options.sectionActiveClass, state);
10878
10879			}
10880
10881
10882
10883			// default active class handler
10884
10885			$.each(this.anchorData, function(index) {
10886
10887				var reverseIndex = self.anchorData.length - index - 1,
10888
10889					data = self.anchorData[reverseIndex],
10890
10891					anchorElement = (self.options.activeClasses === 'parent' ? data.link.parent() : data.link);
10892
10893
10894
10895				if (scrollTop >= containerHeight - viewPortHeight) {
10896
10897					// handle last section
10898
10899					if (reverseIndex === self.anchorData.length - 1) {
10900
10901						toggleActiveClass(anchorElement, data.block, true);
10902
10903					} else {
10904
10905						toggleActiveClass(anchorElement, data.block, false);
10906
10907					}
10908
10909				} else {
10910
10911					// handle other sections
10912
10913					if (!foundFlag && (scrollTop >= data.offset.top - 1 || reverseIndex === 0)) {
10914
10915						foundFlag = true;
10916
10917						toggleActiveClass(anchorElement, data.block, true);
10918
10919					} else {
10920
10921						toggleActiveClass(anchorElement, data.block, false);
10922
10923					}
10924
10925				}
10926
10927			});
10928
10929		},
10930
10931		calculateScrollDuration: function(offset) {
10932
10933			var distance;
10934
10935			if (this.options.animMode === 'speed') {
10936
10937				distance = Math.abs(this.scrollContainer.scrollTop() - offset.top);
10938
10939				return (distance / this.options.animSpeed) * 1000;
10940
10941			} else {
10942
10943				return this.options.animDuration;
10944
10945			}
10946
10947		},
10948
10949		onClick: function(e) {
10950
10951			var targetBlock = this.getAnchorTarget(e.currentTarget),
10952
10953				targetOffset = this.getTargetOffset(targetBlock);
10954
10955
10956
10957			e.preventDefault();
10958
10959			scrollTo(targetOffset, {
10960
10961				container: this.container,
10962
10963				wheelBehavior: this.options.wheelBehavior,
10964
10965				duration: this.calculateScrollDuration(targetOffset)
10966
10967			});
10968
10969		},
10970
10971		destroy: function() {
10972
10973			if (this.options.activeClasses) {
10974
10975				win.off('resize', this.resizeHandler);
10976
10977				this.scrollContainer.off('scroll', this.scrollHandler);
10978
10979			}
10980
10981			this.anchorLinks.off('click', this.clickHandler);
10982
10983		}
10984
10985	};
10986
10987
10988
10989	// public API
10990
10991	$.extend(SmoothScroll, {
10992
10993		scrollTo: function(blockOrOffset, durationOrOptions, callback) {
10994
10995			scrollTo(blockOrOffset, durationOrOptions, callback);
10996
10997		}
10998
10999	});
11000
11001
11002
11003	// export module
11004
11005	exports.SmoothScroll = SmoothScroll;
11006
11007}(jQuery, this));
11008
11009
11010
11011/*!
11012
11013 * Google Map module
11014
11015 */
11016
11017
11018
11019;(function($) {
11020
11021	function GoogleMapAPI(options) {
11022
11023		this.options = $.extend({
11024
11025			mapTypeId: google.maps.MapTypeId.ROADMAP
11026
11027		}, options);
11028
11029		this.init();
11030
11031	}
11032
11033
11034
11035	GoogleMapAPI.prototype = {
11036
11037		init: function() {
11038
11039			this.findStructure();
11040
11041			this.getInfoWindowContent();
11042
11043			this.createMap();
11044
11045			this.createMarker();
11046
11047			this.createInfoWindow();
11048
11049		},
11050
11051
11052
11053		findStructure: function() {
11054
11055			this.container = $(this.options.container);
11056
11057			this.lat = parseFloat(this.container.attr('data-lat'));
11058
11059			this.lng = parseFloat(this.container.attr('data-lng'));
11060
11061			this.coords = new google.maps.LatLng(this.lat, this.lng);
11062
11063			this.zoom = parseInt(this.container.attr('data-zoom'));
11064
11065			this.infoWindowContent = this.container.find('.map-info');
11066
11067			this.mapOptions = {
11068
11069				mapTypeId: this.options.mapTypeId,
11070
11071				panControl: this.options.panControl,
11072
11073				zoomControl: this.options.zoomControl,
11074
11075				streetViewControl: this.options.streetViewControl,
11076
11077				mapTypeControl: this.options.mapTypeControl,
11078
11079				center: this.coords,
11080
11081				scrollwheel: this.options.scrollwheel,
11082
11083				zoom: this.zoom
11084
11085			};
11086
11087		},
11088
11089
11090
11091		getInfoWindowContent: function() {
11092
11093			this.infoWindowContent = this.container.find(this.options.mapInfoContent);
11094
11095		},
11096
11097
11098
11099		createMap: function() {
11100
11101			this.map = new google.maps.Map(this.container.get(0), this.mapOptions);
11102
11103		},
11104
11105
11106
11107		createMarker: function() {
11108
11109			this.marker = new google.maps.Marker({
11110
11111				icon: this.options.marker,
11112
11113				position: this.coords
11114
11115			});
11116
11117
11118
11119			this.marker.setMap(this.map);
11120
11121		},
11122
11123
11124
11125		createInfoWindow: function() {
11126
11127			var self = this;
11128
11129			this.infoWindow = new google.maps.InfoWindow({
11130
11131				content: this.infoWindowContent.get(0)
11132
11133			});
11134
11135			this.marker.addListener('click', function() {
11136
11137				self.infoWindow.open(self.map, self.marker);
11138
11139			})
11140
11141		}
11142
11143	};
11144
11145
11146
11147	$.fn.googleMapAPI = function(opt) {
11148
11149		return this.each(function() {
11150
11151			$(this).data('GoogleMapAPI', new GoogleMapAPI($.extend(opt, {container: this})));
11152
11153		});
11154
11155	};
11156
11157}(jQuery));
11158
11159
11160
11161/*
11162
11163 * Responsive Layout helper
11164
11165 */
11166
11167ResponsiveHelper = (function($){
11168
11169	// init variables
11170
11171	var handlers = [],
11172
11173		prevWinWidth,
11174
11175		win = $(window),
11176
11177		nativeMatchMedia = false;
11178
11179
11180
11181	// detect match media support
11182
11183	if(window.matchMedia) {
11184
11185		if(window.Window && window.matchMedia === Window.prototype.matchMedia) {
11186
11187			nativeMatchMedia = true;
11188
11189		} else if(window.matchMedia.toString().indexOf('native') > -1) {
11190
11191			nativeMatchMedia = true;
11192
11193		}
11194
11195	}
11196
11197
11198
11199	// prepare resize handler
11200
11201	function resizeHandler() {
11202
11203		var winWidth = win.width();
11204
11205		if(winWidth !== prevWinWidth) {
11206
11207			prevWinWidth = winWidth;
11208
11209
11210
11211			// loop through range groups
11212
11213			$.each(handlers, function(index, rangeObject){
11214
11215				// disable current active area if needed
11216
11217				$.each(rangeObject.data, function(property, item) {
11218
11219					if(item.currentActive && !matchRange(item.range[0], item.range[1])) {
11220
11221						item.currentActive = false;
11222
11223						if(typeof item.disableCallback === 'function') {
11224
11225							item.disableCallback();
11226
11227						}
11228
11229					}
11230
11231				});
11232
11233
11234
11235				// enable areas that match current width
11236
11237				$.each(rangeObject.data, function(property, item) {
11238
11239					if(!item.currentActive && matchRange(item.range[0], item.range[1])) {
11240
11241						// make callback
11242
11243						item.currentActive = true;
11244
11245						if(typeof item.enableCallback === 'function') {
11246
11247							item.enableCallback();
11248
11249						}
11250
11251					}
11252
11253				});
11254
11255			});
11256
11257		}
11258
11259	}
11260
11261	win.bind('load resize orientationchange', resizeHandler);
11262
11263
11264
11265	// test range
11266
11267	function matchRange(r1, r2) {
11268
11269		var mediaQueryString = '';
11270
11271		if(r1 > 0) {
11272
11273			mediaQueryString += '(min-width: ' + r1 + 'px)';
11274
11275		}
11276
11277		if(r2 < Infinity) {
11278
11279			mediaQueryString += (mediaQueryString ? ' and ' : '') + '(max-width: ' + r2 + 'px)';
11280
11281		}
11282
11283		return matchQuery(mediaQueryString, r1, r2);
11284
11285	}
11286
11287
11288
11289	// media query function
11290
11291	function matchQuery(query, r1, r2) {
11292
11293		if(window.matchMedia && nativeMatchMedia) {
11294
11295			return matchMedia(query).matches;
11296
11297		} else if(window.styleMedia) {
11298
11299			return styleMedia.matchMedium(query);
11300
11301		} else if(window.media) {
11302
11303			return media.matchMedium(query);
11304
11305		} else {
11306
11307			return prevWinWidth >= r1 && prevWinWidth <= r2;
11308
11309		}
11310
11311	}
11312
11313
11314
11315	// range parser
11316
11317	function parseRange(rangeStr) {
11318
11319		var rangeData = rangeStr.split('..');
11320
11321		var x1 = parseInt(rangeData[0], 10) || -Infinity;
11322
11323		var x2 = parseInt(rangeData[1], 10) || Infinity;
11324
11325		return [x1, x2].sort(function(a, b){
11326
11327			return a - b;
11328
11329		});
11330
11331	}
11332
11333
11334
11335	// export public functions
11336
11337	return {
11338
11339		addRange: function(ranges) {
11340
11341			// parse data and add items to collection
11342
11343			var result = {data:{}};
11344
11345			$.each(ranges, function(property, data){
11346
11347				result.data[property] = {
11348
11349					range: parseRange(property),
11350
11351					enableCallback: data.on,
11352
11353					disableCallback: data.off
11354
11355				};
11356
11357			});
11358
11359			handlers.push(result);
11360
11361
11362
11363			// call resizeHandler to recalculate all events
11364
11365			prevWinWidth = null;
11366
11367			resizeHandler();
11368
11369		}
11370
11371	};
11372
11373}(jQuery));

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.