PageSourceSearch

https://bitdo.ai/js/app.bundle.js

js bitdo.ai collected 2026-10-05 15:28:08 UTC 69,370 bytes, 2,279 lines download raw bytes

1//--------------------------------------------------------------------------
2// HEADSUP!
3// Please be sure to re-run gulp again if you do not see the config changes
4//--------------------------------------------------------------------------
5var myapp_config = {
6	/*
7	APP VERSION
8	*/
9	VERSION: '4.5.1',
10	/*
11	SAVE INSTANCE REFERENCE
12	Save a reference to the global object (window in the browser)
13	*/
14	root_: $('body'), // used for core app reference
15	root_logo: $('.page-sidebar > .page-logo'), // used for core app reference
16	/*
17	DELAY VAR FOR FIRING REPEATED EVENTS (eg., scroll & resize events)
18	Lowering the variable makes faster response time but taxing on the CPU
19	Reference: http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/
20	*/
21	throttleDelay: 450, // for window.scrolling & window.resizing
22	filterDelay: 150,   // for keyup.functions 
23	/*
24	DETECT MOBILE DEVICES
25	Description: Detects mobile device - if any of the listed device is 
26	detected a class is inserted to $.root_ and the variable thisDevice 
27	is decleard. (so far this is covering most hand held devices)
28	*/
29	thisDevice: null, // desktop or mobile
30	isMobile: (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase())), //popular device types available on the market
31	mobileMenuTrigger: null, // used by pagescrolling and appHeight script, do not change!
32	mobileResolutionTrigger: 992, //the resolution when the mobile activation fires
33	/*
34	DETECT IF WEBKIT
35	Description: this variable is used to fire the custom scroll plugin. 
36	If it is a non-webkit it will fire the plugin.
37	*/
38	isWebkit: ((!!window.chrome && !!window.chrome.webstore) === true || Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0 === true),
39	/*
40	DETECT CHROME
41	Description: this variable is used to fire the custom CSS hacks
42	*/
43	isChrome: (/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())),
44	/*
45	DETECT IE (it only detects the newer versions of IE)
46	Description: this variable is used to fire the custom CSS hacks
47	*/
48	isIE: ( (window.navigator.userAgent.indexOf('Trident/') ) > 0 === true ),
49	/*
50	DEBUGGING MODE
51	debugState = true; will spit all debuging message inside browser console.
52	*/
53	debugState: true, // outputs debug information on browser console
54	/*
55	Turn on ripple effect for buttons and touch events
56	Dependency: 
57	*/
58	rippleEffect: true, // material design effect that appears on all buttons
59	/*
60	Primary theme anchor point ID
61	This anchor is created dynamically and CSS is loaded as an override theme
62	*/
63	mythemeAnchor: '#mytheme',
64	/*
65	Activate last tab
66	Stores the last tab in localstorage and activates it
67	*/
68	activateLastTab: true,	
69	/*
70	Primary menu anchor point #js-primary-nav
71	This is the root anchor point where the menu script will begin its build
72	*/
73	navAnchor: $('#js-primary-nav'), //changing this may implicate slimscroll plugin target
74	navHooks: $('#js-nav-menu'), //changing this may implicate CSS targets
75	navAccordion: true, //nav item when one is expanded the other closes
76	navInitalized: 'js-nav-built', //nav finished class 
77	navFilterInput: $('#nav_filter_input'), //changing this may implicate CSS targets
78	navHorizontalWrapperId: 'js-nav-menu-wrapper',
79	/*
80	The rate at which the menu expands revealing child elements on click
81	Lower rate reels faster expansion of nav childs
82	*/
83	navSpeed: 500, //ms
84	/*
85	Color profile reference hook (needed for getting CSS value for theme colors in charts and various graphs)
86	*/
87	mythemeColorProfileID: $('#js-color-profile'),
88	/*
89	Nav close and open signs
90	This uses the fontawesome css class
91	*/
92	navClosedSign: 'fal fa-angle-down',
93	navOpenedSign: 'fal fa-angle-up',
94	/*
95	Application icon prefix for error messages etc
96	other options are fad, fal, fas, far, ni
97	*/
98	appIconPrefix: 'fal',
99	/*
100	App date ID
101	found inside the breadcrumb unit, displays current date to the app on pageload
102	*/
103	appDateHook: $('.js-get-date'),
104	/*
105	* SaveSettings to localStorage
106	* DOC: to store settings to a DB instead of LocalStorage see below:
107	*    initApp.pushSettings("className1 className2") //sets value
108	*    var DB_string = initApp.getSettings(); //returns setting string
109	*/
110	storeLocally: true,
111	/*
112	* Used with initApp.loadScripts
113	* DOC: Please leave it blank
114	*/
115	jsArray : []
116};
117
118 /*!
119 * jQuery app.navigation v1.0.0
120 *
121 * Copyright 2019, 2020 SmartAdmin WebApp
122 * Released under Marketplace License (see your license details for usage)
123 *
124 * Publish Date: 2018-01-01T17:42Z
125 */
126
127(function($) {
128
129	/**
130	 * Menu Plugin
131	 **/
132	$.fn.extend({
133
134		/**
135		 * pass the options variable to the function
136		 *
137		 *   $(id).navigation({ 
138		 *       accordion: true,
139		 *       animate: 'easeOutExpo',
140		 *       speed: 200,
141		 *       closedSign: '[+]',
142		 *       openedSign: '[-]',
143		 *       initClass: 'js-nav-built'
144		 *   });
145		 *
146		 **/
147	     
148	    navigation: function(options) {
149
150	        var defaults = {
151					accordion: true,
152					animate: 'easeOutExpo',
153					speed: 200,
154					closedSign: '[+]',
155					openedSign: '[-]',
156					initClass: 'js-nav-built'
157	            },
158
159	            /**
160	             * extend our default options with those provided.
161	             **/
162	            opts = $.extend(defaults, options),
163
164	            /**
165	             * assign current element to variable, in this case is UL element
166	             **/
167	            self = $(this);
168
169				if (!self.hasClass(opts.initClass)) {
170
171				    /**
172				     * confirm build to prevent rebuild error
173				     **/
174				    self.addClass(opts.initClass);
175
176				    /**
177				     * add a mark [+] to a multilevel menu
178				     **/
179				    self.find("li").each(function() {
180				        if ($(this).find("ul").length !== 0) {
181
182				            /**
183				             * add the multilevel sign next to the link
184				             **/
185				            $(this).find("a:first").append("<b class='collapse-sign'>" + opts.closedSign + "</b>");
186
187				            /**
188				             * avoid jumping to the top of the page when the href is an #
189				             **/
190				            if ($(this).find("a:first").attr('href') == "#") {
191				                $(this).find("a:first").click(function() {
192				                    return false;
193				                });
194				            }
195				        }
196				    });
197
198				    /**
199				     * add open sign to all active lists
200				     **/
201				    self.find("li.active").each(function() {
202				        $(this).parents("ul")
203				        	.parent("li")
204				        	.find("a:first")
205				        	.attr('aria-expanded', true)
206				        	.find("b:first")
207				        	.html(opts.openedSign);
208				    });
209
210				    /**
211				     * click events
212				     **/
213				    self.find("li a").on('mousedown', function(e) {
214
215				        if ($(this).parent().find("ul").length !== 0) {
216
217				            if (opts.accordion) {
218
219				                /**
220				                 * do nothing when the list is open
221				                 **/
222				                if (!$(this).parent().find("ul").is(':visible')) {
223
224				                    parents = $(this).parent().parents("ul");
225				                    visible = self.find("ul:visible");
226				                    visible.each(function(visibleIndex) {
227				                        var close = true;
228				                        parents.each(function(parentIndex) {
229
230				                            if (parents[parentIndex] == visible[visibleIndex]) {
231
232				                                close = false;
233				                                return false;
234				                            }
235				                        });
236				                        if (close) {
237
238				                            if ($(this).parent().find("ul") != visible[visibleIndex]) {
239
240				                                $(visible[visibleIndex]).slideUp(opts.speed + 300, opts.animate, function() {
241				                                    $(this).parent("li")
242				                                    	.removeClass("open")
243				                                    	.find("a:first")
244				                                    	.attr('aria-expanded', false)
245				                                    	.find("b:first")
246				                                    	.html(opts.closedSign);
247
248				                                    if (myapp_config.debugState)
249				                                        console.log("nav item closed")    
250				                                });
251				                            }
252				                        }
253				                    });
254				                }
255				            }
256
257				            /**
258				             * Add active class to open element
259				             **/
260				            if ($(this).parent().find("ul:first").is(":visible") && !$(this).parent().find("ul:first").hasClass("active")) {
261
262				                $(this).parent().find("ul:first").slideUp(opts.speed + 100, opts.animate, function() {
263				                    $(this).parent("li")
264				                    	.removeClass("open")
265				                    	.find("a:first")
266				                    	.attr('aria-expanded', false)
267				                    	.find("b:first").delay(opts.speed)
268				                    	.html(opts.closedSign);  
269
270				                    if (myapp_config.debugState)
271				                        console.log("nav item closed")
272				                });
273				            } else {
274				                $(this).parent().find("ul:first").slideDown(opts.speed, opts.animate, function() {
275
276				                    $(this).parent("li")
277				                    	.addClass("open")
278				                    	.find("a:first")
279				                    	.attr('aria-expanded', true)
280				                    	.find("b:first").delay(opts.speed)
281				                    	.html(opts.openedSign);
282
283				                    if (myapp_config.debugState)
284				                        console.log("nav item opened");
285
286				                });
287				            }
288				        }
289				    });    
290
291				} else {
292				    
293				    if (myapp_config.debugState)
294				        console.log(self.get(0) + " this menu already exists");       
295				}
296
297	    },
298
299	    /**
300	     * DOC: $(id).destroy();
301	     **/
302	    navigationDestroy: function() {
303	        
304			self = $(this);
305
306			if (self.hasClass(myapp_config.navInitalized)) {
307			    self.find("li").removeClass("active open");
308			    self.find("li a").off('mousedown').removeClass("active").removeAttr("aria-expanded").find(".collapse-sign").remove();
309			    self.removeClass(myapp_config.navInitalized).find("ul").removeAttr("style");
310
311			    if (myapp_config.debugState)
312			        console.log( self.get(0) + " destroyed");     
313
314			} else {
315			    console.log("menu does not exist")
316			}
317
318	        
319	    }
320	}); 
321
322})(jQuery, window, document);
323 /*!
324 * jQuery menuSlider v1.0.0
325 *
326 * Copyright 2019, 2020 SmartAdmin WebApp
327 * Released under Marketplace License (see your license details for usage)
328 *
329 * Publish Date: 2019-01-01T17:42Z
330 */
331
332
333;
334(function($) {
335    var pluginName = 'menuSlider';
336
337    function Plugin(element, options) {
338
339        var $el = $(element),
340             el = element;
341        options = $.extend({}, $.fn[pluginName].defaults, options);
342
343        function init() {
344
345            /* reset margin */
346            $el.css('margin-left', '0px');
347
348            /* add wrapper around navigation */
349            $el.wrap( '<div id="'+options.wrapperId+'" class="nav-menu-wrapper d-flex flex-grow-1 width-0 overflow-hidden"></div>' );
350
351            /* add buttons for scroller */
352            $('#' + options.wrapperId).before('<a href="#" id="' + options.wrapperId + '-left-btn" class="d-flex align-items-center justify-content-center width-4 btn mt-1 mb-1 mr-2 ml-1 p-0 fs-xxl text-primary"><i class="fal fa-angle-left"></i></a>');
353            $('#' + options.wrapperId).after('<a href="#" id="' + options.wrapperId + '-right-btn" class="d-flex align-items-center justify-content-center width-4 btn mt-1 mb-1 mr-1 ml-2 p-0 fs-xxl text-primary"><i class="fal fa-angle-right"></i></a>');
354
355            var getListWidth = $.map($el.children('li:not(.nav-title)'),function(val){ return $(val).outerWidth(true);}),
356                /* define variables */
357                wrapperWidth,
358                currentMarginLeft,
359                contentWidth,               
360                setMargin,
361                maxMargin,
362
363
364                /* update variables for margin calculations */
365                _getValues = function() {
366                    wrapperWidth = $('#' + options.wrapperId).outerWidth(); /* incase its changed we get it again */
367                    contentWidth = $.map( $el.children('li:not(.nav-title)'), function(val){ return $(val).outerWidth(true); }).reduce(function(a, b) { return a + b; }, 0);
368                    currentMarginLeft = parseFloat($el.css('margin-left'));
369
370                    /*console.log("got new values");
371                    console.log("wrapperWidth :" + wrapperWidth);
372                    console.log("contentWidth :" + contentWidth);
373                    console.log("currentMarginLeft :" + currentMarginLeft);*/
374                },
375
376                /* scroll right */
377                navMenuScrollRight = function() {
378
379                    _getValues();
380
381                    if (-currentMarginLeft + wrapperWidth < contentWidth) {
382                        setMargin = Math.max(currentMarginLeft - wrapperWidth, -(contentWidth - wrapperWidth) );
383                    } else {
384                        setMargin = currentMarginLeft;
385                        console.log("right end");
386                    }
387
388                    $el.css({
389                        marginLeft: setMargin
390                    });
391
392                },
393
394                /* scroll left */
395                navMenuScrollLeft = function() {
396
397                    _getValues();
398
399                    if (currentMarginLeft < 0) {
400                        setMargin = Math.min(currentMarginLeft + wrapperWidth, 0);
401                    } else {
402                        setMargin = currentMarginLeft;
403                        console.log("left end");
404                    }
405
406                    $el.css({
407                        marginLeft: setMargin
408                    });
409
410                };
411
412            /* assign buttons for right*/
413            $('#' + options.wrapperId + '-left-btn').click(function(e) {
414
415                navMenuScrollLeft();
416
417                e.preventDefault();
418            });
419
420            /* assign buttons for left */
421             $('#' + options.wrapperId + '-right-btn').click(function(e) {
422
423                navMenuScrollRight();
424
425                e.preventDefault();
426            });
427
428            hook('onInit');
429        }
430
431        function option(key, val) {
432            if (val) {
433                options[key] = val;
434            } else {
435                return options[key];
436            }
437        }
438
439        function destroy(options) {
440            $el.each(function() {
441                var el = this;
442                var $el = $(this);
443
444                // Add code to restore the element to its original state...
445
446                $el.css('margin-left', '0px');                           
447                $el.unwrap(parent);
448                $el.prev().off().remove();
449                $el.next().off().remove();
450
451                hook('onDestroy');
452                $el.removeData('plugin_' + pluginName);
453            });
454        }
455
456        function hook(hookName) {
457            if (options[hookName] !== undefined) {
458                options[hookName].call(el);
459            }
460        }
461
462        init();
463
464        return {
465            option: option,
466            destroy: destroy
467        };
468    }
469
470    $.fn[pluginName] = function(options) {
471        if (typeof arguments[0] === 'string') {
472            var methodName = arguments[0];
473            var args = Array.prototype.slice.call(arguments, 1);
474            var returnVal;
475            this.each(function() {
476                if ($.data(this, 'plugin_' + pluginName) && typeof $.data(this, 'plugin_' + pluginName)[methodName] === 'function') {
477                    returnVal = $.data(this, 'plugin_' + pluginName)[methodName].apply(this, args);
478                } else {
479                    throw new Error('Method ' + methodName + ' does not exist on jQuery.' + pluginName);
480                }
481            });
482            if (returnVal !== undefined) {
483                return returnVal;
484            } else {
485                return this;
486            }
487        } else if (typeof options === "object" || !options) {
488            return this.each(function() {
489                if (!$.data(this, 'plugin_' + pluginName)) {
490                    $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
491                }
492            });
493        }
494    };
495
496    $.fn[pluginName].defaults = {
497        onInit: function() {},
498        onDestroy: function() {},
499        element: myapp_config.navHooks,
500        wrapperId: myapp_config.navHorizontalWrapperId
501    };
502
503
504})(jQuery);
505 /*!
506 * jQuery SmartAdmin v4.0.0
507 *
508 * Copyright 2019, 2020 SmartAdmin WebApp
509 * Released under Marketplace License (see your license details for usage)
510 *
511 * Publish Date: 2019-01-01T17:42Z
512 */
513var initApp = (function(app) {
514
515	/**
516	 * List filter 
517	 * DOC: searches list items, it could be UL or DIV elements
518	 * usage: initApp.listFilter($('.list'), $('#intput-id'));
519	 *        inside the .list you will need to insert 'data-filter-tags' inside <a>
520	 * @param  list
521	 * @param  input 
522	 * @param  anchor
523	 * @return 
524	 */
525	app.listFilter = function (list, input, anchor) {
526
527		/* add class to filter hide/show */
528		if (anchor) {
529			$(anchor).addClass('js-list-filter');
530		} else {
531			$(list).addClass('js-list-filter');
532		}
533
534		/* on change keyboard */
535		$(input).change( function () {
536
537			var filter = $(this).val().toLowerCase(),
538				listPrev = $(list).next().filter('.js-filter-message');
539	
540			/* when user types more than 1 letter start search filter */
541			if(filter.length > 1) {
542
543				/* this finds all data-filter-tags in a list that contain the input val,
544				   hiding the ones not containing the input while showing the ones that do */
545				
546				/* (1) hide all that does not match */   
547				$(list).find($("[data-filter-tags]:not([data-filter-tags*='" + filter + "'])"))
548					.parentsUntil(list).removeClass('js-filter-show')
549					.addClass('js-filter-hide');
550
551				/* (2) hide all that does match */	
552				$(list).find($("[data-filter-tags*='" + filter + "']"))
553					.parentsUntil(list).removeClass('js-filter-hide')
554					.addClass('js-filter-show');
555
556				/* if element exists then print results */	
557				if (listPrev){	
558					listPrev.text("showing " + $(list).find('li.js-filter-show').length + " from " + $(list).find('[data-filter-tags]').length + " total");
559				}
560
561			} else {
562
563				/* when filter length is blank reset the classes */
564				$(list).find('[data-filter-tags]').parentsUntil(list).removeClass('js-filter-hide js-filter-show');
565
566				/* if element exists reset print results */
567				if (listPrev){
568					listPrev.text("");
569				}
570			} 
571
572			return false;
573
574		}).keyup( $.debounce( myapp_config.filterDelay, function (e) {
575
576			/* fire the above change event after every letter is typed with a delay of 250ms */
577			$(this).change();
578
579			/*if(e.keyCode == 13) {
580				console.log( $(list).find(".filter-show:not(.filter-hide) > a") );
581			}*/
582
583		}));
584	};
585
586	/**
587	 * Load scripts using lazyload method 
588	 * usage: initApp.loadScript("js/my_lovely_script.js", myFunction);
589	 * @param  {[type]}   scriptName
590	 * @param  {Function} callback  
591	 * @return {[type]}             
592	 */
593	app.loadScript = function (scriptName, callback) {
594
595		if (!myapp_config.jsArray[scriptName]) {	
596			var promise = jQuery.Deferred();
597
598			/* adding the script tag to the head as suggested before */
599			var body = document.getElementsByTagName('body')[0],
600				script = document.createElement('script');
601				script.type = 'text/javascript';
602				script.src = scriptName;
603
604			/* then bind the event to the callback function
605			   there are several events for cross browser compatibility */
606			script.onload = function() {
607				promise.resolve();
608			};
609
610			/* fire the loading */
611			body.appendChild(script);
612			myapp_config.jsArray[scriptName] = promise.promise();
613		}	
614
615		else if (myapp_config.debugState)
616			console.log("This script was already loaded: " + scriptName);
617
618		myapp_config.jsArray[scriptName].then(function () {
619			if(typeof callback === 'function') {
620				callback();
621			}
622		});
623	};
624
625	/**
626	 * Javascript Animation for save settings 
627	 * @return
628	 **/
629	app.saveSettings = function () {
630
631		/* if saveSettings function exists */		
632		if (typeof saveSettings !== 'undefined' && $.isFunction(saveSettings) && myapp_config.storeLocally) {
633
634			/* call accessIndicator animation */
635			initApp.accessIndicator();
636
637			/* call saveSettings function from myapp_config.root_ (HTML) */
638			saveSettings();
639
640			if (myapp_config.debugState)
641				console.log('Theme settings: ' + '\n' +localStorage.getItem('themeSettings'));
642
643		} else {
644			console.log("save function does not exist");
645		}
646		
647	};
648
649	/**
650	 * Load external CSS files
651	 * @return
652	 **/
653
654	app.updateTheme = function (themeName, themeSave) {
655
656		/* if theme anchor exists */
657		if ($(myapp_config.mythemeAnchor).length) {
658			$(myapp_config.mythemeAnchor).attr('href', themeName);
659		} else {
660			$('head').append($("<link>", {id: myapp_config.mythemeAnchor.replace('#', ''), "rel": "stylesheet", "href" : themeName }));
661		}
662
663		if ( themeSave != undefined ) {
664			initApp.saveSettings();
665		}
666	};
667
668	/**
669	 * Reset settings 
670	 * DOC: removes all classes from root_ then saves
671	 * @return {[type]}
672	 **/
673	app.resetSettings = function () {
674
675		/* remove all setting classes nav|header|mod|display */
676		myapp_config.root_.removeClass (function (index, className) {
677			return (className.match (/(^|\s)(nav-|header-|footer-|mod-|display-)\S+/g) || []).join(' ');
678		});
679
680		/* detach custom css skin */
681		$(myapp_config.mythemeAnchor).attr('href', "");
682
683		/* check non-conflicting plugins */
684		initApp.checkNavigationOrientation();
685
686		/* save settings if "storeLocally == true" */
687		initApp.saveSettings();
688
689		if (myapp_config.debugState)
690			console.log("App reset successful");
691	};
692
693	/**
694	 * Factory Reset 
695	 * DOC: Resets all of localstorage
696	 * @return {[type]}
697	 **/
698	app.factoryReset = function () {
699
700		//backdrop sound
701		initApp.playSound('media/sound', 'messagebox');
702		//hide settings modal to bootstrap avoid modal bug
703		$('.js-modal-settings').modal('hide');
704
705		if (typeof bootbox  != 'undefined') {
706
707			bootbox.confirm({
708				title: "<i class='" + myapp_config.appIconPrefix +  " fa-exclamation-triangle text-warning mr-2'></i> You are about to reset all of your localStorage settings",
709				message: "<span><strong>Warning:</strong> This action is not reversable. You will lose all your layout settings.</span>",
710				centerVertical: true,
711				swapButtonOrder: true,
712				buttons: {
713					confirm: {
714						label: 'Factory Reset',
715						className: 'btn-warning shadow-0'
716					},
717					cancel: {
718						label: 'Cancel',
719						className: 'btn-success'
720					}
721				},
722				className: "modal-alert",
723				closeButton: false,
724				callback: function (result) {
725					if (result == true) {
726						//close panel 
727						localStorage.clear();
728						initApp.resetSettings();
729						location.reload();
730					}
731				}
732			});
733
734		} else {
735
736			if (confirm( 'You are about to reset all of your localStorage to null state. Do you wish to continue?' )) {
737				localStorage.clear();
738				initApp.resetSettings();
739				location.reload();
740			}
741
742		}				
743
744		//e.preventDefault();
745
746		if (myapp_config.debugState)
747			console.log("App reset successful");
748	};
749
750	/**
751	 * Access Indicator
752	 * DOC: spinning icon that appears whenever you
753	 * access localstorage or change settings
754	 * @return {[type]}
755	 **/
756	app.accessIndicator = function () {
757
758		myapp_config.root_.addClass('saving').delay(600).queue(function(){
759			$(this).removeClass('saving').dequeue();
760			return true;
761		});
762
763	};
764
765	/*
766	 * usage: initApp.pushSettings("className1 className2")
767	 * save settings to localstorage: initApp.pushSettings("className1 className2", true)
768	 * DOC: pushSettings will also auto save to localStorage if "storeLocally == true" 
769	 * we will use this "pushSettings" when loading settings from a database
770	 * @param  {[type]} DB_string   
771	 * @param  {[type]} saveToLocal
772	 * @return {[type]}            
773	 */
774	app.pushSettings = function (DB_string, saveToLocal) {
775
776		/* clear localstorage variable 'themeSettings' */
777		if (saveToLocal != false)
778		localStorage.setItem("themeSettings", "");
779
780		/* replace classes from <body> with fetched DB string */
781		myapp_config.root_.addClass(DB_string); //ommited .removeClass()
782
783		/* destroy or enable slimscroll */
784		initApp.checkNavigationOrientation();
785
786		/* save settings if "storeLocally == true" && "saveToLocal is true" */
787		if (saveToLocal != false)
788		initApp.saveSettings();
789
790		/* return string */
791		return DB_string;
792	};
793
794	/*
795	 * usage: var DB_string = initApp.removeSettings();
796	 * we will use this "removeSettings" when removing certain classes from '_root'
797	 * @return {[type]}
798	 */
799	app.removeSettings = function (classToRemove) {
800
801		if (classToRemove != undefined) {
802
803			// find and remove the specific class name from existing classes
804			var settingString =  initApp.getSettings().replace(classToRemove,'');
805
806			/* remove all setting classes nav|header|mod|display */
807			myapp_config.root_.removeClass (function (index, className) {
808				return (className.match (/(^|\s)(nav-|header-|footer-|mod-|display-)\S+/g) || []).join(' ');
809			});
810
811			//push new settings
812			initApp.pushSettings( settingString )
813
814		} else {
815			console.log("ERROR: You must specify the class you need to remove")
816		}
817	
818
819		//initApp.pushSettings(layouts);
820		
821	};
822
823	/*
824	 * usage: var DB_string = initApp.getSettings();
825	 * we will use this "getSettings" when storing settings to a database
826	 * @return {[type]}
827	 */
828	app.getSettings = function () {
829
830		return myapp_config.root_.attr('class').split(/[^\w-]+/).filter(function(item) {
831			return /^(nav|header|footer|mod|display)-/i.test(item);
832		}).join(' ');
833	};
834
835	/*
836	 * Play Sounds
837	 * usage: initApp.playSound(path, sound);
838	 * @param  {[string]} path 
839	 * @param  {[string]} sound 
840	 */
841	app.playSound = function(path, sound) {
842		var audioElement = document.createElement('audio');
843		if (navigator.userAgent.match('Firefox/'))
844			audioElement.setAttribute('src', path + "/" + sound + '.ogg');
845		else
846			audioElement.setAttribute('src', path + "/" + sound + '.mp3');
847
848		//$.get();// <-- ??
849		audioElement.addEventListener("load", function () {
850			audioElement.play();
851		}, true);
852
853		audioElement.pause();
854		audioElement.play();
855	}
856
857	/*
858	 * Checks and sets active settings selections
859	 * DOC: ?
860	 */
861	/*app.indicateSelections = function () {
862
863		var classNames = initApp.getSettings()
864			.split(' ')
865			.map(function(c) {
866				return '[data-class="' +  c + '"].js-indicateSelections';
867			})
868			.join(',');
869
870		$('[data-class].active.js-indicateSelections').removeClass('active');
871		$(classNames).addClass('active');
872
873		if (myapp_config.debugState)
874			console.log(classNames);
875	}*/
876
877	/**
878	 * detect browser type
879	 * DOC: detect if browser supports webkit CSS
880	 * @return {[type]}
881	 **/
882	app.detectBrowserType = function () {
883
884		/* safari, chrome or IE detect */	
885		if(myapp_config.isChrome){
886
887			myapp_config.root_.addClass('chrome webkit');
888			return 'chrome webkit';
889
890		} else if (myapp_config.isWebkit) {
891
892			myapp_config.root_.addClass('webkit');
893			return 'webkit';
894
895		} else if (myapp_config.isIE) {
896
897			myapp_config.root_.addClass('ie');
898			return 'ie';
899		}
900
901	};
902
903	/**
904	 * Add device type
905	 * DOC: Detect if mobile or desktop
906	 **/		
907	app.addDeviceType = function() {
908		
909		if (!myapp_config.isMobile) {
910
911			/* desktop */	
912			myapp_config.root_.addClass('desktop');
913			myapp_config.thisDevice = 'desktop';
914
915		} else {
916
917			/* mobile */
918			myapp_config.root_.addClass('mobile');
919			myapp_config.thisDevice = 'mobile';
920			 
921		}
922
923		return myapp_config.thisDevice;
924		
925	};
926
927	/**
928	 * Fix logo position on .header-function-fixed & .nav-function-hidden
929	 * DOC: Counters browser bug for fixed position and overflow:hidden for the logo (firefox/IE/Safari)
930	 *      Will not fire for webkit devices or Chrome as its not needed
931	 * @return {[type]}     
932	 **/
933	 app.windowScrollEvents = function () {
934		if ( myapp_config.root_.is('.nav-function-hidden.header-function-fixed:not(.nav-function-top)') &&  myapp_config.thisDevice === 'desktop') {
935			myapp_config.root_logo.css({
936				'top': $(window).scrollTop()
937			});
938		} else if ( myapp_config.root_.is('.header-function-fixed:not(.nav-function-top):not(.nav-function-hidden
938)') &&  myapp_config.thisDevice === 'desktop') {
939			myapp_config.root_logo.attr("style", "");
940		}
941	 };
942
943	/**
944	 * checkNavigationOrientation by checking layout conditions
945	 * DOC: sometimes settings can trigger certain plugins; so we check this condition and activate accordingly
946	 * E.g: the fixed navigation activates custom scroll plugin for the navigation, but this only happens when
947	 *		it detects desktop browser and destroys the plugin when navigation is on top or if its not fixed.
948	 * @return {[type]}		
949	 **/
950	 app.checkNavigationOrientation = function() {
951
952		/**
953		 * DOC: add the plugin with the following rules: fixed navigation is selected, top navigation is not active, minify nav is not active, 
954		 * and the device is desktop. We do not need to activate the plugin when loading from a mobile phone as it is not needed for touch screens.
955		 **/
956		switch ( true ) {
957
958			case ( myapp_config.root_.hasClass('nav-function-fixed') && !myapp_config.root_.is('.nav-function-top, .nav-function-minify, .mod-main-boxed') && myapp_config.thisDevice === 'desktop' ):
959
960				/* start slimscroll on nav */
961				if ( typeof $.fn.slimScroll !== 'undefined' ) {
962					myapp_config.navAnchor.slimScroll({
963						height: '100%',
964						color: '#fff',
965						size: '4px',
966						distance: '4px',
967						railOpacity: 0.4,
968						wheelStep: 10
969					});
970
971					if ( document.getElementById(myapp_config.navHorizontalWrapperId) ) {
972						myapp_config.navHooks.menuSlider('destroy');
973						
974						if (myapp_config.debugState)
975						console.log("----top controls destroyed");
976					}
977
978					if (myapp_config.debugState)
979					console.log("slimScroll created");
980
981				} else {
982					console.log("$.fn.slimScroll...NOT FOUND");
983				}	
984
985				break;			
986
987			case ( myapp_config.navAnchor.parent().hasClass('slimScrollDiv') && myapp_config.thisDevice === 'desktop' && typeof $.fn.slimScroll !== 'undefined' ):
988
989				/* destroy the plugin if it is in violation of rules above */
990				myapp_config.navAnchor.slimScroll({ destroy: true });
991				myapp_config.navAnchor.attr('style', '');
992
993				/* clear event listners (IE bug) */
994				events = jQuery._data( myapp_config.navAnchor[0], "events" );
995
996				if (events) 
997					jQuery._removeData( myapp_config.navAnchor[0], "events" );
998
999				if (myapp_config.debugState)
1000					console.log("slimScroll destroyed");
1001
1002				break;					
1003
1004		}
1005
1006		switch ( true ) {
1007
1008
1009			/* fires when user switches to nav-function-top on desktop view */
1010			case ( $.fn.menuSlider && myapp_config.root_.hasClass('nav-function-top') && $("#js-nav-menu-wrapper").length == false && !myapp_config.root_.hasClass('mobile-view-activated') ):
1011
1012				/* build horizontal navigation */
1013				myapp_config.navHooks.menuSlider({
1014					element: myapp_config.navHooks,
1015					wrapperId: myapp_config.navHorizontalWrapperId
1016				});
1017
1018				/* build horizontal nav */
1019				if (myapp_config.debugState)
1020				console.log("----top controls created -- case 1");
1021
1022				break;
1023
1024			/* fires when user resizes screen to mobile size or app is loaded on mobile resolution */
1025			case ( myapp_config.root_.hasClass('nav-function-top') && $("#js-nav-menu-wrapper").length == true && myapp_config.root_.hasClass('mobile-view-activated') ):
1026
1027				/* destroy horizontal nav */
1028				myapp_config.navHooks.menuSlider('destroy');
1029
1030				/* build horizontal nav */
1031				if (myapp_config.debugState)
1032				console.log("----top controls destroyed -- case 2");
1033
1034				break;	
1035
1036			/* fires when users switch off nav-function-top class */
1037			case ( !myapp_config.root_.hasClass('nav-function-top') && $("#js-nav-menu-wrapper").length == true ):
1038
1039				/* destroy horizontal nav */
1040				myapp_config.navHooks.menuSlider('destroy');
1041
1042				/* build horizontal nav */
1043				if (myapp_config.debugState)
1044				console.log("----top controls destroyed -- case 3");				
1045
1046				break;	
1047
1048		}
1049
1050	};
1051	
1052	/**
1053	 * Activate Nav
1054	 * DOC: activation should not take place if top navigation is on
1055	 * @param  {[type]} id 
1056	 * @return {[type]} 
1057	 **/
1058	app.buildNavigation = function(id) {
1059		
1060		/**
1061		 * build nav
1062		 * app.navigation.js
1063		 **/
1064		if ($.fn.navigation) {
1065
1066			$(id).navigation({ 
1067
1068				accordion : myapp_config.navAccordion,
1069				speed : myapp_config.navSpeed,
1070				closedSign : '<em class="' + myapp_config.navClosedSign + '"></em>',
1071				openedSign : '<em class="' + myapp_config.navOpenedSign + '"></em>',
1072				initClass: myapp_config.navInitalized
1073
1074			});
1075
1076			return (id);
1077		} else {
1078
1079			if (myapp_config.debugState)
1080			console.log( "WARN: navigation plugin missing" );
1081
1082		}
1083	};
1084
1085	/**
1086	 * Destroy Nav
1087	 * @param  {[type]} id 
1088	 * @return {[type]} 
1089	 **/
1090	app.destroyNavigation = function(id) {
1091		
1092		/**
1093		 * destroy nav
1094		 * app.navigation.js
1095		 **/
1096		if ($.fn.navigation) {
1097
1098			$(id).navigationDestroy(); 
1099
1100			return (id);
1101		} else {
1102
1103			if (myapp_config.debugState)
1104			console.log( "WARN: navigation plugin missing" );
1105
1106		}
1107	};
1108
1109	/**
1110	 * App Forms
1111	 * DOC: detects if input is selected or blured
1112	 * @param  {[type]} parentClass
1113	 * @param  {[type]} focusClass
1114	 * @param  {[type]} disabledClass
1115	 * @return {[type]} 
1116	 **/
1117	app.appForms = function(parentClass,focusClass,disabledClass){
1118
1119		/* go through each .form-control */
1120		/*$('.form-control').each(function () {
1121			checkLength(this);
1122		});*/
1123
1124		/* if input has 'some value' add class .has-length to .form-group */
1125		/*function checkLength(e) {
1126			if (e.value.length > 0 ) {
1127				$(e).parents(parentClass).addClass(focusClass);
1128				if($(e).is('[readonly]') || $(e).is('[disabled]')) {
1129					$(e).parents(parentClass).addClass(disabledClass);
1130				}
1131			} else {
1132				$(e).parents(parentClass).removeClass(focusClass);
1133				if($(e).is('[readonly]') || $(e).is('[disabled]')) {
1134					$(e).parents(parentClass).removeClass(disabledClass);
1135				}
1136			}
1137		}*/
1138
1139		function setClass(e, parentClass, focusClass) {
1140			$(e).parents(parentClass).addClass(focusClass);
1141		}
1142
1143		function deleteClass(e, parentClass, focusClass) {
1144			/*if(e.value.length) {
1145
1146			} else {*/
1147				$(e).parents(parentClass).removeClass(focusClass);
1148			/*}*/
1149		}
1150
1151		$(parentClass).each(function () {
1152			var input = $(this).find('.form-control');
1153			input.on('focus', function(){
1154				setClass(this, parentClass, focusClass);
1155			});
1156			input.on('blur', function(){
1157				deleteClass(this, parentClass, focusClass);
1158			});
1159		});
1160	}; 
1161	
1162	/**
1163	 * Mobile Check Activate
1164	 * DOC: check on window resize if screen width is less than [value]
1165	 * @return {int}
1166	 */
1167	app.mobileCheckActivation = function(){
1168		
1169		if ( window.innerWidth < myapp_config.mobileResolutionTrigger ) {
1170
1171			myapp_config.root_.addClass('mobile-view-activated');
1172			myapp_config.mobileMenuTrigger = true;
1173
1174		} else {
1175
1176			myapp_config.root_.removeClass('mobile-view-activated');
1177			myapp_config.mobileMenuTrigger = false;
1178
1179		}
1180
1181		if (myapp_config.debugState)
1182			console.log( "mobileCheckActivation on " + $(window).width() + " | activated: " + myapp_config.mobileMenuTrigger);
1183
1184		return myapp_config.mobileMenuTrigger;
1185	}; 
1186
1187	/**
1188	 *  Toggle visibility
1189	 * 	DOC: show and hide content with a button action
1190	 *  Usage: onclick="initApp.toggleVisibility('foo');"
1191	 *  @param  {[type]} id 
1192	 *  @return {[type]}
1193	 **/
1194	app.toggleVisibility = function (id) {
1195		var e = document.getElementById(id);
1196		if (e.style.display == 'block')
1197			e.style.display = 'none';
1198		else
1199			e.style.display = 'block';
1200	};
1201
1202	/**
1203	 * Miscelaneous DOM ready functions
1204	 * DOC: start jQuery(document).ready calls
1205	 * @return {[type]}
1206	 **/
1207	app.domReadyMisc = function() {
1208
1209		/* Add file name path to input files */
1210		$('.custom-file input').change(function (e) {
1211			var files = [];
1212			for (var i = 0; i < $(this)[0].files.length; i++) {
1213				files.push($(this)[0].files[i].name);
1214			}
1215			$(this).next('.custom-file-label').html(files.join(', '));
1216		});
1217
1218		/* Give modal backdrop an extra class to make it customizable */
1219		$('.modal-backdrop-transparent').on('show.bs.modal', function (e) {
1220			setTimeout(function(){
1221				$('.modal-backdrop').addClass('modal-backdrop-transparent');
1222			});
1223		});
1224		
1225		/* Add app date to js-get-date */
1226		if ( myapp_config.appDateHook.length ) {
1227			var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
1228				day = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
1229				now = new Date(),
1230				formatted = day[now.getDay()] + ', ' +  
1231							months[now.getMonth()] + ' ' +  
1232							now.getDate() + ', ' +
1233							now.getFullYear();
1234			myapp_config.appDateHook.text(formatted);				
1235		}
1236
1237		/* Check conflicting classes to build/destroy slimscroll */
1238		initApp.checkNavigationOrientation();
1239
1240		/* Activate the last tab clicked using localStorage */
1241		if ( myapp_config.activateLastTab ) {
1242			
1243			var lastTab = localStorage.getItem('lastTab');
1244			 
1245			$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
1246				localStorage.setItem('lastTab', $(this).attr('href'));
1247			});
1248			
1249			if (lastTab) {
1250				$('[href="' + lastTab + '"]').tab('show');
1251			} 
1252		}
1253
1254		/**
1255		 * all options:
1256		 * --------------
1257			width: '300px',
1258			height: '500px',
1259			size: '10px',
1260			position: 'left',
1261			color: '#ffcc00',
1262			alwaysVisible: true,
1263			distance: '20px',
1264			start: $('#child_image_element'),
1265			railVisible: true,
1266			railColor: '#222',
1267			railOpacity: 0.3,
1268			wheelStep: 10,
1269			allowPageScroll: false,
1270			disableFadeOut: false
1271		 **/
1272		if ( typeof $.fn.slimScroll !== 'undefined' && myapp_config.thisDevice === 'desktop') {
1273
1274			$('.custom-scroll:not(.disable-slimscroll) >:first-child').slimscroll({
1275				height: $(this).data('scrollHeight') || '100%',
1276				size: $(this).data('scrollSize') || '4px',
1277				position: $(this).data('scrollPosition') || 'right',
1278				color: $(this).data('scrollColor') || 'rgba(0,0,0,0.6)',
1279				alwaysVisible: $(this).data('scrollAlwaysVisible') || false,
1280				distance: $(this).data('scrollDistance') || '4px',
1281				railVisible: $(this).data('scrollRailVisible') || false,
1282				railColor: $(this).data('scrollRailColor') || '#fafafa',
1283				allowPageScroll: false,
1284				disableFadeOut: false
1285			});
1286
1287			if (myapp_config.debugState)
1288				console.log("%c✔ SlimScroll plugin active", "color: #148f32");	
1289
1290		} else {
1291			console.log("WARN! $.fn.slimScroll not loaded or user is on desktop");
1292			myapp_config.root_.addClass("no-slimscroll");
1293		}
1294
1295		/**
1296		 * Activate listFilters
1297		 * usage: <input id="inputID" data-listfilter="listFilter" />
1298		 **/
1299		if( typeof initApp.listFilter !== 'undefined' && $.isFunction(initApp.listFilter) && $('[data-listfilter]').length ) {
1300
1301
1302			var inputID = $('[data-listfilter]').attr('id'),
1303				listFilter = $('[data-listfilter]').attr("data-listfilter");
1304
1305			/* initApp.listFilter($('.list'), $('#intput-id')); */
1306			initApp.listFilter(listFilter, '#' + inputID);
1307		}
1308
1309		/**
1310		 * Start bootstrap tooltips
1311		 **/
1312		if( typeof($.fn.tooltip) !== 'undefined' && $('[data-toggle="tooltip"]').length ){
1313			$('[data-toggle="tooltip"]').tooltip(); /*{html: true}*/
1314		} else {
1315			console.log("OOPS! bs.tooltip is not loaded");
1316		}
1317
1318		/**
1319		 * Start bootstrap popovers
1320		 **/
1321		if( typeof($.fn.popover) !== 'undefined' && $('[data-toggle="popover"]').length ){
1322
1323			/* BS4 sanatize */
1324			var myDefaultWhiteList = $.fn.tooltip.Constructor.Default.whiteList
1325
1326			/* init popover */
1327			/* data-sanitize="false" was not working so had to add this globally */
1328			/* DOC: https://getbootstrap.com/docs/4.3/getting-started/javascript/#sanitizer */
1329			$('[data-toggle="popover"]').popover({sanitize:false}); /*{trigger: "focus"}*/
1330
1331		} /*else {
1332			console.log("OOPS! bs.popover is not loaded");
1333			console.log("this")
1334		}*/
1335
1336		/* 
1337		 * Disable popper.js's forced hardware accelaration styles
1338		 */
1339		if( typeof($.fn.dropdown) !== 'undefined'){ 
1340			Popper.Defaults.modifiers.computeStyle.gpuAcceleration = false;
1341		} else {
1342			console.log("OOPS! bs.popover is not loaded");
1343		} 
1344
1345		/**
1346		 * Dropdowns will not close on click
1347		 * doc: close dropdowns on click outside hit area
1348		 **/
1349		$(document).on('click', '.dropdown-menu:not(.js-auto-close):not(.note-dropdown-menu)', function (e) {
1350			e.stopPropagation();
1351		});
1352
1353		/**
1354		 * Waves effect (plugin has issues with IE9)
1355		 * DOC: http://fian.my.id/Waves/#start 
1356		 **/
1357		if (window.Waves && myapp_config.rippleEffect) {
1358
1359			Waves.attach('.nav-menu:not(.js-waves-off) a, .btn:not(.js-waves-off):not(.btn-switch), .js-waves-on', ['waves-themed']);
1360			Waves.init();
1361
1362			if (myapp_config.debugState)
1363				console.log("%c✔ Waves plugin active", "color: #148f32");	
1364			
1365		} else {
1366			if (myapp_config.debugState)
1367				console.log("%c✘ Waves plugin inactive! ", "color: #fd3995");
1368
1369		}
1370
1371		/**
1372		 * Action buttons
1373		 **/		
1374		myapp_config.root_
1375			.on('click touchend', '[data-action]', function(e) {
1376
1377				var actiontype = $(this).data('action');
1378
1379				switch ( true ) {
1380
1381					/**
1382					 * toggle trigger
1383					 * Usage 1 (body): <a href="#" data-action="toggle" data-class="add-this-class-to-body">...</a>
1384					 * Usage 2 (target): <a href="#" data-action="toggle" data-class="add-this-class-to-target" data-target="target">...</a>
1385					 **/
1386					case ( actiontype === 'toggle' ):
1387
1388						var target = $(this).attr('data-target') || myapp_config.root_,
1389							dataClass = $(this).attr('data-class'),
1390							inputFocus = $(this).attr('data-focus');
1391
1392						/* remove previous background image if alternate is selected */
1393						if ( dataClass.indexOf('mod-bg-') !== -1 ) {
1394							$(target).removeClass (function (index, css) {
1395								return (css.match (/(^|\s)mod-bg-\S+/g) || []).join(' ');
1396							});
1397						}
1398
1399						/* trigger class change */
1400						$(target).toggleClass( dataClass );
1401
1402						/* this allows us to add active class for dropdown toggle components */
1403						if ( $(this).hasClass('dropdown-item') ) {
1404							$(this).toggleClass('active');
1405						}
1406
1407						/* focus input if available 
1408						   FAQ: We had to put a delay timer to slow it down for chrome
1409						*/
1410						if(inputFocus != undefined) {
1411							setTimeout(function(){ $('#' + inputFocus).focus(); }, 200);
1412						}
1413
1414						/* save settings */
1415						//if ( typeof classHolder != 'undefined' || classHolder != null ) {
1416						if ( typeof classHolder != 'undefined' ) {
1417
1418							/* NOTE: saveSettings function is located right after <body> tag */
1419							initApp.checkNavigationOrientation();
1420							initApp.saveSettings();
1421						}
1422
1423						break;
1424
1425					/**
1426					 * toggle swap trigger
1427					 * Usage (target): <a href="#" data-action="toggle-swap" data-class="root-text" data-target="html">...</a>
1428					 **/
1429					case ( actiontype === 'toggle-swap' ):
1430
1431						var target = $(this).attr('data-target'),
1432							dataClass = $(this).attr('data-class');
1433
1434						/* trigger class change */
1435						$(target).removeClass().addClass( dataClass );
1436
1437						/* change active for demo */
1438						if (dataClass.startsWith("root-text")) {
1439							$('[data-class]').removeClass('active');
1440							$('[data-class="' + dataClass + '"]').addClass('active');
1441						}
1442
1443						break;
1444
1445
1446					/**
1447					 * toggle replace trigger
1448					 * Usage (target): <a href="#" data-action="toggle-swap" data-replaceclass="classesToReplace" data-class="replaceWithClass" data-target="body">...</a>
1449					 **/
1450					case ( actiontype === 'toggle-replace' ):
1451
1452						var target = $(this).attr('data-target') || myapp_config.root_,
1453							replaceClass = $(this).attr('data-replaceclass')
1454							dataClass = $(this).attr('data-class') || "";
1455							savetoLocal = $(this).attr('data-savetolocal') || true;
1456
1457						/* trigger class change */
1458						$(target).removeClass( replaceClass ).addClass( dataClass );
1459						//console.log( replaceClass + " :replace these classes")
1460
1461						/* save to localStorage */
1462						if (savetoLocal === true) {
1463							initApp.saveSettings();
1464						}
1465
1466						break;
1467
1468
1469					/**
1470					 * panel 'collapse' trigger
1471					 **/
1472					case ( actiontype === 'panel-collapse' ):
1473
1474						var selectedPanel = $(this).closest('.panel');
1475
1476						selectedPanel.children('.panel-container').collapse('toggle')
1477						.on('show.bs.collapse', function() {
1478							selectedPanel.removeClass("panel-collapsed");
1479
1480							if (myapp_config.debugState)
1481								console.log( "panel id:" + selectedPanel.attr('id') + " | action: uncollapsed" );
1482
1483						}).on('hidden.bs.collapse', function(){
1484							selectedPanel.addClass("panel-collapsed");
1485
1486							if (myapp_config.debugState)
1487								console.log( "panel id:" + selectedPanel.attr('id') + " | action: collapsed" );
1488
1489						});
1490				
1491						/* return ID of panel */
1492						//return selectedPanel.attr('id');
1493
1494						break;
1495
1496					/**
1497					 * panel 'fullscreen' trigger
1498					 **/
1499					case ( actiontype === 'panel-fullscreen' ):
1500
1501						var selectedPanel = $(this).closest('.panel');
1502
1503						selectedPanel.toggleClass('panel-fullscreen');
1504						myapp_config.root_.toggleClass('panel-fullscreen');
1505
1506						if (myapp_config.debugState)
1507						console.log( "panel id:" + selectedPanel.attr('id') + " | action: fullscreen" );
1508
1509						/* return ID of panel */
1510						//return selectedPanel.attr('id');
1511
1512						break;
1513
1514					/**
1515					 * panel 'close' trigger
1516					 **/
1517					case ( actiontype === 'panel-close' ):
1518
1519						var selectedPanel = $(this).closest('.panel');
1520
1521						var killPanel = function (){
1522
1523							selectedPanel.fadeOut(500,function(){
1524								/* remove panel */
1525								$(this).remove();
1526
1527								if (myapp_config.debugState)
1528								console.log( "panel id:" + selectedPanel.attr('id') + " | action: removed" );
1529							});
1530
1531						};
1532
1533						if (typeof bootbox  != 'undefined') {
1534
1535							initApp.playSound('media/sound', 'messagebox')
1536
1537							bootbox.confirm({
1538								title: "<i class='" + myapp_config.appIconPrefix +  " fa-times-circle text-danger mr-2'></i> Do you wish to delete panel <span class='fw-500'> '" +selectedPanel.children('.panel-hdr').children('h2').text().trim()+ "' </span>?",
1539								message: "<span><strong>Warning:</strong> This action cannot be undone!</span>",
1540								centerVertical: true,
1541								swapButtonOrder: true,
1542								buttons: {
1543									confirm: {
1544										label: 'Yes',
1545										className: 'btn-danger shadow-0'
1546									},
1547									cancel: {
1548										label: 'No',
1549										className: 'btn-default'
1550									}
1551								},
1552								className: "modal-alert",
1553								closeButton: false,
1554								callback: function (result) {
1555
1556									if (result == true) {
1557										killPanel();
1558									}
1559								}
1560							});
1561
1562						} else {
1563							
1564							if (confirm( 'Do you wish to delete panel ' + selectedPanel.children('.panel-hdr').children('h2').text().trim() + '?' )) {
1565								killPanel();
1566							}
1567
1568						}
1569
1570						break;
1571
1572					/**
1573					 * update header css, 'theme-update' trigger
1574					 * eg:  data-action = "theme-update" 
1575					 *      data-theme = "css/cust-theme-1.css"
1576					 **/
1577					case ( actiontype === 'theme-update' ):
1578
1579						initApp.updateTheme($(this).attr('data-theme'), $(this).attr('data-themesave'));
1580
1581						break;
1582
1583					/**
1584					 * theme 'app-reset' trigger
1585					 **/
1586					case ( actiontype === 'app-reset' ):
1587
1588						initApp.resetSettings();
1589
1590						break;
1591
1592					/**
1593					 * theme 'factory-reset' trigger
1594					 **/
1595					case ( actiontype === 'factory-reset' ):
1596
1597						initApp.factoryReset();
1598
1599						break;	
1600
1601					/**
1602					 * app print
1603					 * starts print priview for browser
1604					 **/
1605					case ( actiontype === 'app-print' ):
1606
1607						window.print();
1608
1609						break;
1610
1611					/**
1612					 * ondemand
1613					 * load onDemand scripts
1614					 **/
1615					case ( actiontype === 'app-loadscript' ):
1616
1617						var loadurl = $(this).attr('data-loadurl'),
1618							loadfunction = $(this).attr('data-loadfunction');
1619
1620						initApp.loadScript(loadurl,loadfunction);
1621
1622						break;	
1623
1624					/**
1625					 * app language selection
1626					 * lazyloads i18n plugin and activates selected language
1627					 **/
1628					case ( actiontype === 'lang' ):
1629
1630						var applang = $(this).attr('data-lang').toString();
1631
1632						if (!$.i18n) {
1633						//jQuery.getScript('http://url/to/the/script');
1634
1635							initApp.loadScript("js/i18n/i18n.js", 
1636
1637								function activateLang () {
1638									
1639									$.i18n.init({
1640										resGetPath: 'media/data/__lng__.json',
1641										load: 'unspecific',
1642										fallbackLng: false,
1643										lng: applang
1644									}, function (t){
1645										$('[data-i18n]').i18n();
1646										$('[data-lang]').removeClass('active');
1647										$('[data-lang="' + applang + '"]').addClass('active');
1648									});								
1649									
1650								}
1651							);
1652
1653						} else {
1654
1655							i18n.setLng(applang, function(){
1656								$('[data-i18n]').i18n();
1657								$('[data-lang]').removeClass('active');
1658								$(this).addClass('active');
1659							});
1660
1661						}
1662
1663						break;	
1664
1665					/**
1666					 * app 'fullscreen' trigger
1667					 **/
1668					case ( actiontype === 'app-fullscreen' ):
1669
1670						/* NOTE: this may not work for all browsers if the browser security does not permit it 
1671						   IE issues: http://stackoverflow.com/questions/33732805/fullscreen-not-working-in-ie */
1672
1673						if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) {
1674
1675							if (document.documentElement.requestFullscreen) {
1676								/* Standard browsers */
1677								document.documentElement.requestFullscreen();
1678							} else if (document.documentElement.msRequestFullscreen) {
1679								/* Internet Explorer */
1680								document.documentElement.msRequestFullscreen();
1681							} else if (document.documentElement.mozRequestFullScreen) {
1682								/* Firefox */
1683								document.documentElement.mozRequestFullScreen();
1684							} else if (document.documentElement.webkitRequestFullscreen) {
1685								/* Chrome */
1686								document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
1687							}
1688
1689							if (myapp_config.debugState)
1690								console.log( "app fullscreen toggle active" );
1691
1692						} else {
1693
1694							if (document.exitFullscreen) {
1695								document.exitFullscreen();
1696							} else if (document.msExitFullscreen) {
1697								document.msExitFullscreen();
1698							} else if (document.mozCancelFullScreen) {
1699								document.mozCancelFullScreen();
1700							} else if (document.webkitExitFullscreen) {
1701								document.webkitExitFullscreen();
1702							}
1703
1704							if (myapp_config.debugState)
1705								console.log("%capp fullscreen toggle inactive! ", "color: #ed1c24");
1706						}
1707
1708						break; 
1709				
1710					/**
1711					 * app 'playsound' trigger
1712					 * usage: data-action="playsound" data-soundpath="media/sound/" data-soundfile="filename" (no file extensions)
1713					 **/
1714					case ( actiontype === 'playsound' ):
1715
1716						var path = $(this).attr('data-soundpath') || "media/sound/",
1717							sound = $(this).attr('data-soundfile');
1718
1719						initApp.playSound(path,sound);
1720
1721						break;
1722
1723				}
1724
1725				/* hide tooltip if any present */
1726				$(this).tooltip('hide');
1727
1728				if (myapp_config.debugState)
1729					console.log("data-action clicked: " + actiontype);
1730
1731				/* stop default link action */				
1732				e.stopPropagation(); 
1733				e.preventDefault();		
1734		}); 
1735
1736		/**
1737		 * Windows mobile 8 fix ~
1738		 * DOC: bootstrap related
1739		 **/
1740		if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
1741			var msViewportStyle = document.createElement('style');
1742			msViewportStyle.appendChild(
1743				document.createTextNode(
1744					'@-ms-viewport{width:auto!important}'
1745				)
1746			);
1747			document.head.appendChild(msViewportStyle)
1748		};
1749
1750		/**
1751		 * Display APP version
1752		 * DOC: only show this if debug state tree
1753		 **/
1754		 if (myapp_config.debugState)
1755			console.log("%c✔ Finished app.init() v" + myapp_config.VERSION + '\n' + "---------------------------", "color: #148f32");	
1756	};
1757
1758	return app;
1759	
1760})({});
1761
1762/*
1763	"Night is a bag that bursts with the golden dust of dawn..."
1764
1765	Oh wow, you actually opened this file and read it all the way though! Congrats! 
1766	Please do drop me a line at @myplaneticket :)
1767
1768*/
1769var layouts = (function(setlayout) {
1770
1771	setlayout.errorMessage = function(layout){
1772		
1773		console.log("('" + layout + "')" +" is not a valid entry, enter 'on' or 'off'");
1774	}
1775
1776	setlayout.fixedHeader = function(layout) {
1777		if (layout === 'on') {
1778			initApp.pushSettings('header-function-fixed')
1779		} else if (layout === 'off') {
1780			initApp.removeSettings('header-function-fixed')
1781		} else {
1782			layouts.errorMessage(layout);
1783		}
1784	};
1785	setlayout.fixedNavigation = function(layout) {
1786		if (layout === 'on') {
1787			initApp.pushSettings('nav-function-fixed')
1788		} else if (layout === 'off') {
1789			initApp.removeSettings('nav-function-fixed')
1790		} else {
1791			layouts.errorMessage(layout);
1792		}
1793	};
1794	setlayout.minifyNavigation = function(layout) {
1795		if (layout === 'on') {
1796			initApp.pushSettings('nav-function-minify')
1797		} else if (layout === 'off') {
1798			initApp.removeSettings('nav-function-minify')
1799		} else {
1800			layouts.errorMessage(layout);
1801		}
1802	};
1803	setlayout.hideNavigation = function(layout) {
1804		if (layout === 'on') {
1805			initApp.pushSettings('nav-function-hidden')
1806		} else if (layout === 'off') {
1807			initApp.removeSettings('nav-function-hidden')
1808		} else {
1809			layouts.errorMessage(layout);
1810		}
1811	};
1812	setlayout.horizontalNavigation = function(layout) {
1813		if (layout === 'on') {
1814			initApp.pushSettings('nav-function-top')
1815		} else if (layout === 'off') {
1816			initApp.removeSettings('nav-function-top')
1817		} else {
1818			layouts.errorMessage(layout);
1819		}
1820	};
1821	setlayout.fixedFooter = function(layout) {
1822		if (layout === 'on') {
1823			initApp.pushSettings('footer-function-fixed')
1824		} else if (layout === 'off') {
1825			initApp.removeSettings('footer-function-fixed')
1826		} else {
1827			layouts.errorMessage(layout);
1828		}
1829	};
1830	setlayout.boxed = function(layout) {
1831		if (layout === 'on') {
1832			initApp.pushSettings('mod-main-boxed')
1833		} else if (layout === 'off') {
1834			initApp.removeSettings('mod-main-boxed')
1835		} else {
1836			layouts.errorMessage(layout);
1837		}
1838	};
1839	//mobile
1840	setlayout.pushContent = function(layout) {
1841		if (layout === 'on') {
1842			initApp.pushSettings('nav-mobile-push')
1843		} else if (layout === 'off') {
1844			initApp.removeSettings('nav-mobile-push')
1845		} else {
1846			layouts.errorMessage(layout);
1847		}
1848	};
1849	setlayout.overlay = function(layout) {
1850		if (layout === 'on') {
1851			initApp.pushSettings('nav-mobile-no-overlay')
1852		} else if (layout === 'off') {
1853			initApp.removeSettings('nav-mobile-no-overlay')
1854		} else {
1855			layouts.errorMessage(layout);
1856		}
1857	};
1858	setlayout.offCanvas = function(layout) {
1859		if (layout === 'on') {
1860			initApp.pushSettings('nav-mobile-slide-out')
1861		} else if (layout === 'off') {
1862			initApp.removeSettings('nav-mobile-slide-out')
1863		} else {
1864			layouts.errorMessage(layout);
1865		}
1866	};
1867	//accessibility
1868	setlayout.bigFonts = function(layout) {
1869		if (layout === 'on') {
1870			initApp.pushSettings('mod-bigger-font')
1871		} else if (layout === 'off') {
1872			initApp.removeSettings('mod-bigger-font')
1873		} else {
1874			layouts.errorMessage(layout);
1875		}
1876	};
1877	setlayout.highContrast = function(layout) {
1878		if (layout === 'on') {
1879			initApp.pushSettings('mod-high-contrast')
1880		} else if (layout === 'off') {
1881			initApp.removeSettings('mod-high-contrast')
1882		} else {
1883			layouts.errorMessage(layout);
1884		}
1885	};
1886	setlayout.colorblind = function(layout) {
1887		if (layout === 'on') {
1888			initApp.pushSettings('mod-color-blind')
1889		} else if (layout === 'off') {
1890			initApp.removeSettings('mod-color-blind')
1891		} else {
1892			layouts.errorMessage(layout);
1893		}
1894	};
1895	setlayout.preloadInside = function(layout) {
1896		if (layout === 'on') {
1897			initApp.pushSettings('mod-pace-custom')
1898		} else if (layout === 'off') {
1899			initApp.removeSettings('mod-pace-custom')
1900		} else {
1901			layouts.errorMessage(layout);
1902		}
1903	};
1904	setlayout.panelIcons = function(layout) {
1905		if (layout === 'on') {
1906			initApp.pushSettings('mod-panel-icon')
1907		} else if (layout === 'off') {
1908			initApp.removeSettings('mod-panel-icon')
1909		} else {
1910			layouts.errorMessage(layout);
1911		}
1912	};
1913	//global
1914	setlayout.cleanBackground = function(layout) {
1915		if (layout === 'on') {
1916			initApp.pushSettings('mod-clean-page-bg')
1917		} else if (layout === 'off') {
1918			initApp.removeSettings('mod-clean-page-bg')
1919		} else {
1920			layouts.errorMessage(layout);
1921		}
1922	};
1923	setlayout.hideNavIcons = function(layout) {
1924		if (layout === 'on') {
1925			initApp.pushSettings('mod-hide-nav-icons')
1926		} else if (layout === 'off') {
1927			initApp.removeSettings('mod-hide-nav-icons')
1928		} else {
1929			layouts.errorMessage(layout);
1930		}
1931	};
1932	setlayout.noAnimation = function(layout) {
1933		if (layout === 'on') {
1934			initApp.pushSettings('mod-disable-animation')
1935		} else if (layout === 'off') {
1936			initApp.removeSettings('mod-disable-animation')
1937		} else {
1938			layouts.errorMessage(layout);
1939		}
1940	};
1941	setlayout.hideInfoCard = function(layout) {
1942		if (layout === 'on') {
1943			initApp.pushSettings('mod-hide-info-card')
1944		} else if (layout === 'off') {
1945			initApp.removeSettings('mod-hide-info-card')
1946		} else {
1947			layouts.errorMessage(layout);
1948		}
1949	};
1950	setlayout.leanSubheader = function(layout) {
1951		if (layout === 'on') {
1952			initApp.pushSettings('mod-lean-subheader')
1953		} else if (layout === 'off') {
1954			initApp.removeSettings('mod-lean-subheader')
1955		} else {
1956			layouts.errorMessage(layout);
1957		}
1958	};
1959	setlayout.hierarchicalNav = function(layout) {
1960		if (layout === 'on') {
1961			initApp.pushSettings('mod-nav-link')
1962		} else if (layout === 'off') {
1963			initApp.removeSettings('mod-nav-link')
1964		} else {
1965			layouts.errorMessage(layout);
1966		}
1967	};
1968	setlayout.darkNav = function(layout) {
1969		if (layout === 'on') {
1970			initApp.pushSettings('mod-nav-dark')
1971		} else if (layout === 'off') {
1972			initApp.removeSettings('mod-nav-dark')
1973		} else {
1974			layouts.errorMessage(layout);
1975		}
1976	};
1977	// ALT Approach
1978	/*setlayout.modeDark = function(layout) {
1979		if (layout === 'on') {
1980			initApp.pushSettings('mod-skin-dark')
1981		} else if (layout === 'off') {
1982			initApp.removeSettings('mod-skin-dark')
1983		} else {
1984			layouts.errorMessage(layout);
1985		}
1986	};
1987	setlayout.modeLight = function(layout) {
1988		if (layout === 'on') {
1989			initApp.pushSettings('mod-skin-light')
1990		} else if (layout === 'off') {
1991			initApp.removeSettings('mod-skin-light')
1992		} else {
1993			layouts.errorMessage(layout);
1994		}
1995	};
1996	setlayout.modeDefault = function() {
1997		layouts.modeDark('off');
1998		layouts.modeLight('off');
1999	};*/
2000
2001	//layouts.fontSize('sm');
2002	// TODO
2003	/*setlayout.fontSize = function(layout) {
2004
2005		switch ( true ) {
2006
2007			case ( layout === 'sm' ): 
2008				initApp.pushSettings('mod-skin-light') 
2009				break;
2010
2011			case ( layout === 'md' ): 
2012				initApp.pushSettings('mod-skin-light') 
2013				break;
2014
2015			case ( layout === 'lg' ): 
2016				initApp.pushSettings('mod-skin-light') 
2017				break;
2018
2019			case ( layout === 'xl' ): 
2020				initApp.pushSettings('mod-skin-light') 
2021				break;
2022
2023			default: 
2024				console.log("('" + layout + "')" +" is not a valid entry, enter 'sm', 'md', 'lg', or 'xl'");
2025				break;
2026		}	
2027
2028	};*/
2029
2030	//layouts.theme(themename.css,true)
2031	setlayout.theme = function(themename,save) {
2032		initApp.updateTheme(themename, save);
2033	};
2034
2035	//layouts.mode('default');
2036	setlayout.mode = function(layout) {
2037
2038		switch ( true ) {
2039
2040			case ( layout === 'default' ): 
2041				initApp.removeSettings('mod-skin-light', false);
2042				initApp.removeSettings('mod-skin-dark', true);
2043				break;
2044
2045			case ( layout === 'light' ): 
2046				initApp.removeSettings('mod-skin-dark', false);
2047				initApp.pushSettings('mod-skin-light', true);
2048				break;
2049
2050			case ( layout === 'dark' ): 
2051				initApp.removeSettings('mod-skin-light', false);
2052				initApp.pushSettings('mod-skin-dark', true);
2053				break;
2054
2055			default: 
2056				console.log("('" + layout + "')" +" is not a valid entry, enter 'default', 'light', or 'dark'");
2057				break;
2058		}	
2059
2060	};
2061
2062	return setlayout;
2063	
2064})({});
2065/**
2066 * Bind the throttled handler to the resize event.
2067 * NOTE: Please do not change the order displayed (e.g. 1a, 1b, 2a, 2b...etc)
2068 **/
2069$(window).resize(
2070
2071 	$.throttle( myapp_config.throttleDelay, function (e) {
2072
2073		 /**
2074		  * (1a) ADD CLASS WHEN BELOW CERTAIN WIDTH (MOBILE MENU)
2075		  * Description: tracks the page min-width of #CONTENT and NAV when navigation is resized.
2076		  * This is to counter bugs for minimum page width on many desktop and mobile devices.
2077		  **/
2078		  initApp.mobileCheckActivation();
2079
2080		 /**
2081		  * (1b) CHECK NAVIGATION STATUS (IF HORIZONTAL OR VERTICAL)
2082		  * Description: fires an event to check for navigation orientation.
2083		  * Based on the condition, it will initliaze or destroy the slimscroll, or horizontal nav plugins
2084		  **/
2085		  initApp.checkNavigationOrientation();
2086
2087
2088		 /** -- insert your resize codes below this line -- **/
2089	 
2090	})
2091); 
2092
2093/**
2094 * Bind the throttled handler to the scroll event
2095 **/
2096$(window).scroll(
2097
2098 	$.throttle( myapp_config.throttleDelay, function (e) {
2099
2100		 /**
2101		  * FIX APP HEIGHT
2102		  * Compare the height of nav and content;
2103		  * If one is longer/shorter than the other, measure them to be equal.
2104		  * This event is only fired on desktop.
2105		  **/
2106		  
2107
2108		  /** -- insert your other scroll codes below this line -- **/
2109
2110	})
2111
2112);
2113
2114/**
2115 * Initiate scroll events
2116 **/
2117$(window).on('scroll', initApp.windowScrollEvents);
2118
2119/**
2120 * DOCUMENT LOADED EVENT
2121 * DOC: Fire when DOM is ready
2122 * Do not change order a, b, c, d...
2123 **/
2124
2125document.addEventListener('DOMContentLoaded', function() {
2126
2127	/**
2128	 * detect desktop or mobile 
2129	 **/
2130	initApp.addDeviceType();
2131
2132	/**
2133	 * detect Webkit Browser 
2134	 **/
2135	initApp.detectBrowserType();
2136
2137	/**
2138	 * a. check for mobile view width and add class .mobile-view-activated
2139	 **/
2140	initApp.mobileCheckActivation();
2141
2142 	/**
2143	 * b. build navigation
2144	 **/
2145	initApp.buildNavigation(myapp_config.navHooks);
2146
2147 	/**
2148	 * c. initialize nav filter
2149	 **/
2150	initApp.listFilter(myapp_config.navHooks, myapp_config.navFilterInput, myapp_config.navAnchor);
2151
2152 	/**
2153	 * d. run DOM misc functions
2154	 **/
2155	initApp.domReadyMisc();
2156
2157 	/**
2158	 * e. run app forms class detectors [parentClass,focusClass,disabledClass]
2159	 **/
2160	initApp.appForms('.input-group', 'has-length', 'has-disabled');
2161
2162}); 
2163
2164/**
2165 * Mobile orientation change events
2166 * DOC: recalculates app height
2167 **/
2168$( window ).on( "orientationchange", function( event ) {
2169	/* reset any .CSS heights and force appHeight function to recalculate */
2170
2171	if (myapp_config.debugState)
2172		console.log("orientationchange event");
2173});
2174
2175/**
2176 * Window load function
2177 * DOC: window focus blur detection
2178 **/
2179$(window).on("blur focus", function(e) {
2180    var prevType = $(this).data("prevType");
2181    /**
2182     * reduce double fire issues
2183     **/
2184    if (prevType != e.type) {   
2185        switch (e.type) {
2186            case "blur":
2187                myapp_config.root_.toggleClass("blur") 
2188
2189                if (myapp_config.debugState)
2190                console.log("blur");
2191            
2192                break;
2193            case "focus":
2194                myapp_config.root_.toggleClass("blur")
2195                if (myapp_config.debugState)
2196
2197                console.log("focused");
2198
2199                break;
2200        }
2201    }
2202
2203    $(this).data("prevType", e.type);
2204})
2205
2206var color = {
2207	primary: {
2208		_50:  rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-50').css('color'))  || '#ccbfdf',
2209		_100: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-100').css('color')) || '#beaed7',
2210		_200: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-200').css('color')) || '#b19dce',
2211		_300: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-300').css('color')) || '#a38cc6',
2212		_400: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-400').css('color')) || '#967bbd',
2213		_500: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-500').css('color')) || '#886ab5',
2214		_600: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-600').css('color')) || '#7a59ad',
2215		_700: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-700').css('color')) || '#6e4e9e',
2216		_800: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-800').css('color')) || '#62468d',
2217		_900: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-primary-900').css('color')) || '#563d7c'
2218	},
2219	success: {
2220		_50:  rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-50').css('color'))  || '#7aece0',
2221		_100: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-100').css('color')) || '#63e9db',
2222		_200: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-200').css('color')) || '#4de5d5',
2223		_300: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-300').css('color')) || '#37e2d0',
2224		_400: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-400').css('color')) || '#21dfcb',
2225		_500: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-500').css('color')) || '#1dc9b7',
2226		_600: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-600').css('color')) || '#1ab3a3',
2227		_700: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-700').css('color')) || '#179c8e',
2228		_800: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-800').css('color')) || '#13867a',
2229		_900: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-success-900').css('color')) || '#107066'
2230	},
2231	info: {
2232		_50:  rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-50').css('color'))  || '#9acffa',
2233		_100: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-100').css('color')) || '#82c4f8',
2234		_200: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-200').css('color')) || '#6ab8f7',
2235		_300: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-300').css('color')) || '#51adf6',
2236		_400: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-400').css('color')) || '#39a1f4',
2237		_500: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-500').css('color')) || '#2196F3',
2238		_600: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-600').css('color')) || '#0d8aee',
2239		_700: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-700').css('color')) || '#0c7cd5',
2240		_800: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-800').css('color')) || '#0a6ebd',
2241		_900: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-info-900').css('color')) || '#0960a5'
2242	},
2243	warning: {
2244		_50:  rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-50').css('color'))  || '#ffebc1',
2245		_100: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-100').css('color')) || '#ffe3a7',
2246		_200: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-200').css('color')) || '#ffdb8e',
2247		_300: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-300').css('color')) || '#ffd274',
2248		_400: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-400').css('color')) || '#ffca5b',
2249		_500: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-500').css('color')) || '#ffc241',
2250		_600: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-600').css('color')) || '#ffba28',
2251		_700: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-700').css('color')) || '#ffb20e',
2252		_800: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-800').css('color')) || '#f4a500',
2253		_900: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-warning-900').css('color')) || '#da9400'
2254	},
2255	danger: {
2256		_50:  rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-50').css('color'))  || '#feb7d9',
2257		_100: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-100').css('color')) || '#fe9ecb',
2258		_200: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-200').css('color')) || '#fe85be',
2259		_300: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-300').css('color')) || '#fe6bb0',
2260		_400: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-400').css('color')) || '#fd52a3',
2261		_500: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-500').css('color')) || '#fd3995',
2262		_600: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-600').css('color')) || '#fd2087',
2263		_700: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-700').css('color')) || '#fc077a',
2264		_800: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-800').css('color')) || '#e7026e',
2265		_900: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-danger-900').css('color')) || '#ce0262'
2266	},
2267	fusion: {
2268		_50:  rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-50').css('color'))  || '#909090',
2269		_100: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-100').css('color')) || '#838383',
2270		_200: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-200').css('color')) || '#767676',
2271		_300: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-300').css('color')) || '#696969',
2272		_400: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-400').css('color')) || '#5d5d5d',
2273		_500: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-500').css('color')) || '#505050',
2274		_600: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-600').css('color')) || '#434343',
2275		_700: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-700').css('color')) || '#363636',
2276		_800: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-800').css('color')) || '#2a2a2a',
2277		_900: rgb2hex(myapp_config.mythemeColorProfileID.find('.color-fusion-900').css('color')) || '#1d1d1d'
2278	}
2279}

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.