702 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			702 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			JavaScript
		
	
	
/*
 | 
						||
 * VOICE COMMAND CONFIG
 | 
						||
 * dependency: js/speech/voicecommand.js
 | 
						||
 */
 | 
						||
	voice_command = true,
 | 
						||
/*
 | 
						||
 * Turns on speech as soon as the page is loaded
 | 
						||
 */	
 | 
						||
	voice_command_auto = false,
 | 
						||
/*
 | 
						||
 * 	Sets the language to the default 'en-US'. (supports over 50 languages 
 | 
						||
 * 	by google)
 | 
						||
 * 
 | 
						||
 *  Afrikaans         ['af-ZA']
 | 
						||
 *  Bahasa Indonesia  ['id-ID']
 | 
						||
 *  Bahasa Melayu     ['ms-MY']
 | 
						||
 *  Català            ['ca-ES']
 | 
						||
 *  Čeština           ['cs-CZ']
 | 
						||
 *  Deutsch           ['de-DE']
 | 
						||
 *  English           ['en-AU', 'Australia']
 | 
						||
 *                    ['en-CA', 'Canada']
 | 
						||
 *                    ['en-IN', 'India']
 | 
						||
 *                    ['en-NZ', 'New Zealand']
 | 
						||
 *                    ['en-ZA', 'South Africa']
 | 
						||
 *                    ['en-GB', 'United Kingdom']
 | 
						||
 *                    ['en-US', 'United States']
 | 
						||
 *  Español           ['es-AR', 'Argentina']
 | 
						||
 *                    ['es-BO', 'Bolivia']
 | 
						||
 *                    ['es-CL', 'Chile']
 | 
						||
 *                    ['es-CO', 'Colombia']
 | 
						||
 *                    ['es-CR', 'Costa Rica']
 | 
						||
 *                    ['es-EC', 'Ecuador']
 | 
						||
 *                    ['es-SV', 'El Salvador']
 | 
						||
 *                    ['es-ES', 'España']
 | 
						||
 *                    ['es-US', 'Estados Unidos']
 | 
						||
 *                    ['es-GT', 'Guatemala']
 | 
						||
 *                    ['es-HN', 'Honduras']
 | 
						||
 *                    ['es-MX', 'México']
 | 
						||
 *                    ['es-NI', 'Nicaragua']
 | 
						||
 *                    ['es-PA', 'Panamá']
 | 
						||
 *                    ['es-PY', 'Paraguay']
 | 
						||
 *                    ['es-PE', 'Perú']
 | 
						||
 *                    ['es-PR', 'Puerto Rico']
 | 
						||
 *                    ['es-DO', 'República Dominicana']
 | 
						||
 *                    ['es-UY', 'Uruguay']
 | 
						||
 *                    ['es-VE', 'Venezuela']
 | 
						||
 *  Euskara           ['eu-ES']
 | 
						||
 *  Français          ['fr-FR']
 | 
						||
 *  Galego            ['gl-ES']
 | 
						||
 *  Hrvatski          ['hr_HR']
 | 
						||
 *  IsiZulu           ['zu-ZA']
 | 
						||
 *  Íslenska          ['is-IS']
 | 
						||
 *  Italiano          ['it-IT', 'Italia']
 | 
						||
 *                    ['it-CH', 'Svizzera']
 | 
						||
 *  Magyar            ['hu-HU']
 | 
						||
 *  Nederlands        ['nl-NL']
 | 
						||
 *  Norsk bokmål      ['nb-NO']
 | 
						||
 *  Polski            ['pl-PL']
 | 
						||
 *  Português         ['pt-BR', 'Brasil']
 | 
						||
 *                    ['pt-PT', 'Portugal']
 | 
						||
 *  Română            ['ro-RO']
 | 
						||
 *  Slovenčina        ['sk-SK']
 | 
						||
 *  Suomi             ['fi-FI']
 | 
						||
 *  Svenska           ['sv-SE']
 | 
						||
 *  Türkçe            ['tr-TR']
 | 
						||
 *  български         ['bg-BG']
 | 
						||
 *  Pусский           ['ru-RU']
 | 
						||
 *  Српски            ['sr-RS']
 | 
						||
 *  한국어          ['ko-KR']
 | 
						||
 *  中文                            ['cmn-Hans-CN', '普通话 (中国大陆)']
 | 
						||
 *                    ['cmn-Hans-HK', '普通话 (香港)']
 | 
						||
 *                    ['cmn-Hant-TW', '中文 (台灣)']
 | 
						||
 *                    ['yue-Hant-HK', '粵語 (香港)']
 | 
						||
 *  日本語                         ['ja-JP']
 | 
						||
 *  Lingua latīna     ['la']
 | 
						||
 */
 | 
						||
	voice_command_lang = 'en-US',
 | 
						||
/*
 | 
						||
 * 	Use localstorage to remember on/off (best used with HTML Version
 | 
						||
 * 	when going from one page to the next)
 | 
						||
 */	
 | 
						||
	voice_localStorage = false;
 | 
						||
/*
 | 
						||
 * Voice Commands
 | 
						||
 * Defines voice command variables and functions
 | 
						||
 */	
 | 
						||
 	if (voice_command) {
 | 
						||
	 		
 | 
						||
		var commands = {
 | 
						||
					
 | 
						||
			'show dashboard' : function() { $('nav a[href="ajax/dashboard.html"]').trigger("click"); },
 | 
						||
			'show inbox' : function() { $('nav a[href="ajax/inbox.html"]').trigger("click"); },
 | 
						||
			'show graphs' : function() { $('nav a[href="ajax/flot.html"]').trigger("click"); },
 | 
						||
			'show flotchart' : function() { $('nav a[href="ajax/flot.html"]').trigger("click"); },
 | 
						||
			'show morris chart' : function() { $('nav a[href="ajax/morris.html"]').trigger("click"); },
 | 
						||
			'show inline chart' : function() { $('nav a[href="ajax/inline-charts.html"]').trigger("click"); },
 | 
						||
			'show dygraphs' : function() { $('nav a[href="ajax/dygraphs.html"]').trigger("click"); },
 | 
						||
			'show tables' : function() { $('nav a[href="ajax/table.html"]').trigger("click"); },
 | 
						||
			'show data table' : function() { $('nav a[href="ajax/datatables.html"]').trigger("click"); },
 | 
						||
			'show jquery grid' : function() { $('nav a[href="ajax/jqgrid.html"]').trigger("click"); },
 | 
						||
			'show form' : function() { $('nav a[href="ajax/form-elements.html"]').trigger("click"); },
 | 
						||
			'show form layouts' : function() { $('nav a[href="ajax/form-templates.html"]').trigger("click"); },
 | 
						||
			'show form validation' : function() { $('nav a[href="ajax/validation.html"]').trigger("click"); },
 | 
						||
			'show form elements' : function() { $('nav a[href="ajax/bootstrap-forms.html"]').trigger("click"); },
 | 
						||
			'show form plugins' : function() { $('nav a[href="ajax/plugins.html"]').trigger("click"); },
 | 
						||
			'show form wizards' : function() { $('nav a[href="ajax/wizards.html"]').trigger("click"); },
 | 
						||
			'show bootstrap editor' : function() { $('nav a[href="ajax/other-editors.html"]').trigger("click"); },
 | 
						||
			'show dropzone' : function() { $('nav a[href="ajax/dropzone.html"]').trigger("click"); },
 | 
						||
			'show image cropping' : function() { $('nav a[href="ajax/image-editor.html"]').trigger("click"); },
 | 
						||
			'show general elements' : function() { $('nav a[href="ajax/general-elements.html"]').trigger("click"); },
 | 
						||
			'show buttons' : function() { $('nav a[href="ajax/buttons.html"]').trigger("click"); },
 | 
						||
			'show fontawesome' : function() { $('nav a[href="ajax/fa.html"]').trigger("click"); },
 | 
						||
			'show glyph icons' : function() { $('nav a[href="ajax/glyph.html"]').trigger("click"); },
 | 
						||
			'show flags' : function() { $('nav a[href="ajax/flags.html"]').trigger("click"); },
 | 
						||
			'show grid' : function() { $('nav a[href="ajax/grid.html"]').trigger("click"); },
 | 
						||
			'show tree view' : function() { $('nav a[href="ajax/treeview.html"]').trigger("click"); },
 | 
						||
			'show nestable lists' : function() { $('nav a[href="ajax/nestable-list.html"]').trigger("click"); },
 | 
						||
			'show jquery U I' : function() { $('nav a[href="ajax/jqui.html"]').trigger("click"); },
 | 
						||
			'show typography' : function() { $('nav a[href="ajax/typography.html"]').trigger("click"); },
 | 
						||
			'show calendar' : function() { $('nav a[href="ajax/calendar.html"]').trigger("click"); },
 | 
						||
			'show widgets' : function() { $('nav a[href="ajax/widgets.html"]').trigger("click"); },
 | 
						||
			'show gallery' : function() { $('nav a[href="ajax/gallery.html"]').trigger("click"); },
 | 
						||
			'show maps' : function() { $('nav a[href="ajax/gmap-xml.html"]').trigger("click"); },
 | 
						||
			'show pricing tables' : function() { $('nav a[href="ajax/pricing-table.html"]').trigger("click"); },
 | 
						||
			'show invoice' : function() { $('nav a[href="ajax/invoice.html"]').trigger("click"); },
 | 
						||
			'show search' : function() { $('nav a[href="ajax/search.html"]').trigger("click"); },
 | 
						||
			'go back' :  function() { history.back(1); }, 
 | 
						||
			'scroll up' : function () { $('html, body').animate({ scrollTop: 0 }, 100); },
 | 
						||
			'scroll down' : function () { $('html, body').animate({ scrollTop: $(document).height() }, 100);},
 | 
						||
			'hide navigation' : function() { 
 | 
						||
				if ($.root_.hasClass("container") && !$.root_.hasClass("menu-on-top")){
 | 
						||
					$('span.minifyme').trigger("click");
 | 
						||
				} else {
 | 
						||
					$('#hide-menu > span > a').trigger("click"); 
 | 
						||
				}
 | 
						||
			},
 | 
						||
			'show navigation' : function() { 
 | 
						||
				if ($.root_.hasClass("container") && !$.root_.hasClass("menu-on-top")){
 | 
						||
					$('span.minifyme').trigger("click");
 | 
						||
				} else {
 | 
						||
					$('#hide-menu > span > a').trigger("click"); 
 | 
						||
				}
 | 
						||
			},
 | 
						||
			'mute' : function() {
 | 
						||
				$.sound_on = false;
 | 
						||
				$.smallBox({
 | 
						||
					title : "MUTE",
 | 
						||
					content : "All sounds have been muted!",
 | 
						||
					color : "#a90329",
 | 
						||
					timeout: 4000,
 | 
						||
					icon : "fa fa-volume-off"
 | 
						||
				});
 | 
						||
			},
 | 
						||
			'sound on' : function() {
 | 
						||
				$.sound_on = true;
 | 
						||
				$.speechApp.playConfirmation();
 | 
						||
				$.smallBox({
 | 
						||
					title : "UNMUTE",
 | 
						||
					content : "All sounds have been turned on!",
 | 
						||
					color : "#40ac2b",
 | 
						||
					sound_file: 'voice_alert',
 | 
						||
					timeout: 5000,
 | 
						||
					icon : "fa fa-volume-up"
 | 
						||
				});
 | 
						||
			},
 | 
						||
			'stop' : function() {
 | 
						||
				smartSpeechRecognition.abort();
 | 
						||
				$.root_.removeClass("voice-command-active");
 | 
						||
				$.smallBox({
 | 
						||
					title : "VOICE COMMAND OFF",
 | 
						||
					content : "Your voice commands has been successfully turned off. Click on the <i class='fa fa-microphone fa-lg fa-fw'></i> icon to turn it back on.",
 | 
						||
					color : "#40ac2b",
 | 
						||
					sound_file: 'voice_off',
 | 
						||
					timeout: 8000,
 | 
						||
					icon : "fa fa-microphone-slash"
 | 
						||
				});
 | 
						||
				if ($('#speech-btn .popover').is(':visible')) {
 | 
						||
					$('#speech-btn .popover').fadeOut(250);
 | 
						||
				}
 | 
						||
			},
 | 
						||
			'help' : function() {
 | 
						||
				$('#voiceModal').removeData('modal').modal( { remote: "ajax/modal-content/modal-voicecommand.html", show: true } );
 | 
						||
				if ($('#speech-btn .popover').is(':visible')) {
 | 
						||
					$('#speech-btn .popover').fadeOut(250);
 | 
						||
				}
 | 
						||
			},		
 | 
						||
			'got it' : function() {
 | 
						||
				$('#voiceModal').modal('hide');
 | 
						||
			},	
 | 
						||
			'logout' : function() {
 | 
						||
				$.speechApp.stop();
 | 
						||
				window.location = $('#logout > span > a').attr("href");
 | 
						||
			}
 | 
						||
		}; 
 | 
						||
		
 | 
						||
	};
 | 
						||
/*
 | 
						||
 * SMART VOICE
 | 
						||
 * Author: MyOrange | @bootstraphunt
 | 
						||
 * http://www.myorange.ca
 | 
						||
 */
 | 
						||
 | 
						||
SpeechRecognition = root.SpeechRecognition || root.webkitSpeechRecognition || root.mozSpeechRecognition || root.msSpeechRecognition || root.oSpeechRecognition;
 | 
						||
 | 
						||
// ref: http://updates.html5rocks.com/2013/01/Voice-Driven-Web-Apps-Introduction-to-the-Web-Speech-API
 | 
						||
if (SpeechRecognition && voice_command) {
 | 
						||
 | 
						||
	// commands are pulled from app.config file
 | 
						||
 | 
						||
	// add function to button
 | 
						||
	$.root_.on('click', '[data-action="voiceCommand"]', function(e) {
 | 
						||
 | 
						||
		if ($.root_.hasClass("voice-command-active")) {
 | 
						||
			$.speechApp.stop();
 | 
						||
			//$('#speech-btn > span > a > i').removeClass().addClass('fa fa-microphone-slash');
 | 
						||
		} else {
 | 
						||
			$.speechApp.start();
 | 
						||
			//add popover
 | 
						||
			$('#speech-btn .popover').fadeIn(350);
 | 
						||
			//$('#speech-btn > span > a > i').removeClass().addClass('fa fa-microphone')
 | 
						||
 | 
						||
		}
 | 
						||
 | 
						||
		e.preventDefault();
 | 
						||
	});
 | 
						||
 | 
						||
	//remove popover
 | 
						||
	$(document).mouseup(function(e) {
 | 
						||
		if (!$('#speech-btn .popover').is(e.target) && $('#speech-btn .popover').has(e.target).length === 0) {
 | 
						||
			$('#speech-btn .popover').fadeOut(250);
 | 
						||
		}
 | 
						||
	});
 | 
						||
 | 
						||
	// create dynamic modal instance
 | 
						||
	var modal = $('<div class="modal fade" id="voiceModal" tabindex="-1" role="dialog" aria-labelledby="remoteModalLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"></div></div></div>');
 | 
						||
	// attach to body
 | 
						||
	modal.appendTo("body");
 | 
						||
 | 
						||
	//debugState
 | 
						||
	if (debugState) {
 | 
						||
		root.console.log("This browser supports Voice Command");
 | 
						||
	}
 | 
						||
 | 
						||
	// function
 | 
						||
	$.speechApp = (function(speech) {
 | 
						||
 | 
						||
		speech.start = function() {
 | 
						||
 | 
						||
			// Add our commands to smartSpeechRecognition
 | 
						||
			smartSpeechRecognition.addCommands(commands);
 | 
						||
 | 
						||
			if (smartSpeechRecognition) {
 | 
						||
				// activate plugin
 | 
						||
				smartSpeechRecognition.start();
 | 
						||
				// add btn class
 | 
						||
				$.root_.addClass("voice-command-active");
 | 
						||
				// play sound
 | 
						||
				$.speechApp.playON();
 | 
						||
				// set localStorage when switch is on manually
 | 
						||
				if (voice_localStorage) {
 | 
						||
					localStorage.setItem('sm-setautovoice', 'true');
 | 
						||
				}
 | 
						||
 | 
						||
			} else {
 | 
						||
				// if plugin not found
 | 
						||
				alert("speech plugin not loaded");
 | 
						||
			}
 | 
						||
 | 
						||
		};
 | 
						||
		speech.stop = function() {
 | 
						||
 | 
						||
			if (smartSpeechRecognition) {
 | 
						||
				// deactivate plugin
 | 
						||
				smartSpeechRecognition.abort();
 | 
						||
				// remove btn class
 | 
						||
				$.root_.removeClass("voice-command-active");
 | 
						||
				// sound
 | 
						||
				$.speechApp.playOFF();
 | 
						||
				// del localStorage when switch if off manually
 | 
						||
				if (voice_localStorage) {
 | 
						||
					localStorage.setItem('sm-setautovoice', 'false');
 | 
						||
				}
 | 
						||
				// remove popover if visible
 | 
						||
				if ($('#speech-btn .popover').is(':visible')) {
 | 
						||
					$('#speech-btn .popover').fadeOut(250);
 | 
						||
				}
 | 
						||
			}
 | 
						||
 | 
						||
		};
 | 
						||
 | 
						||
		// play sound
 | 
						||
		speech.playON = function() {
 | 
						||
 | 
						||
			var audioElement = document.createElement('audio');
 | 
						||
 | 
						||
			if (navigator.userAgent.match('Firefox/'))
 | 
						||
				audioElement.setAttribute('src', $.sound_path + 'voice_on' + ".ogg");
 | 
						||
			else
 | 
						||
				audioElement.setAttribute('src', $.sound_path + 'voice_on' + ".mp3");
 | 
						||
 | 
						||
			//$.get();
 | 
						||
			audioElement.addEventListener("load", function() {
 | 
						||
				audioElement.play();
 | 
						||
			}, true);
 | 
						||
 | 
						||
			if ($.sound_on) {
 | 
						||
				audioElement.pause();
 | 
						||
				audioElement.play();
 | 
						||
			}
 | 
						||
		};
 | 
						||
 | 
						||
		speech.playOFF = function() {
 | 
						||
 | 
						||
			var audioElement = document.createElement('audio');
 | 
						||
 | 
						||
			if (navigator.userAgent.match('Firefox/'))
 | 
						||
				audioElement.setAttribute('src', $.sound_path + 'voice_off' + ".ogg");
 | 
						||
			else
 | 
						||
				audioElement.setAttribute('src', $.sound_path + 'voice_off' + ".mp3");
 | 
						||
 | 
						||
			$.get();
 | 
						||
			audioElement.addEventListener("load", function() {
 | 
						||
				audioElement.play();
 | 
						||
			}, true);
 | 
						||
 | 
						||
			if ($.sound_on) {
 | 
						||
				audioElement.pause();
 | 
						||
				audioElement.play();
 | 
						||
			}
 | 
						||
		};
 | 
						||
 | 
						||
		speech.playConfirmation = function() {
 | 
						||
 | 
						||
			var audioElement = document.createElement('audio');
 | 
						||
 | 
						||
			if (navigator.userAgent.match('Firefox/'))
 | 
						||
				audioElement.setAttribute('src', $.sound_path + 'voice_alert' + ".ogg");
 | 
						||
			else
 | 
						||
				audioElement.setAttribute('src', $.sound_path + 'voice_alert' + ".mp3");
 | 
						||
 | 
						||
			$.get();
 | 
						||
			audioElement.addEventListener("load", function() {
 | 
						||
				audioElement.play();
 | 
						||
			}, true);
 | 
						||
 | 
						||
			if ($.sound_on) {
 | 
						||
				audioElement.pause();
 | 
						||
				audioElement.play();
 | 
						||
			}
 | 
						||
		};
 | 
						||
 | 
						||
		return speech;
 | 
						||
 | 
						||
	})({});
 | 
						||
 | 
						||
} else {
 | 
						||
	$("#speech-btn").addClass("display-none");
 | 
						||
}
 | 
						||
 | 
						||
/*
 | 
						||
 * SPEECH RECOGNITION ENGINE
 | 
						||
 * Copyright (c) 2013 Tal Ater
 | 
						||
 * Modified by MyOrange
 | 
						||
 * All modifications made are hereby copyright (c) 2014 MyOrange
 | 
						||
 */
 | 
						||
 | 
						||
(function(undefined) {"use strict";
 | 
						||
 | 
						||
	// Check browser support
 | 
						||
	// This is done as early as possible, to make it as fast as possible for unsupported browsers
 | 
						||
	if (!SpeechRecognition) {
 | 
						||
		root.smartSpeechRecognition = null;
 | 
						||
		return undefined;
 | 
						||
	}
 | 
						||
 | 
						||
	var commandsList = [], recognition, callbacks = {
 | 
						||
		start : [],
 | 
						||
		error : [],
 | 
						||
		end : [],
 | 
						||
		result : [],
 | 
						||
		resultMatch : [],
 | 
						||
		resultNoMatch : [],
 | 
						||
		errorNetwork : [],
 | 
						||
		errorPermissionBlocked : [],
 | 
						||
		errorPermissionDenied : []
 | 
						||
	}, autoRestart, lastStartedAt = 0,
 | 
						||
	//debugState = false, // decleared in app.config.js
 | 
						||
	//debugStyle = 'font-weight: bold; color: #00f;', // decleared in app.config.js
 | 
						||
 | 
						||
	// The command matching code is a modified version of Backbone.Router by Jeremy Ashkenas, under the MIT license.
 | 
						||
	optionalParam = /\s*\((.*?)\)\s*/g, optionalRegex = /(\(\?:[^)]+\))\?/g, namedParam = /(\(\?)?:\w+/g, splatParam = /\*\w+/g, escapeRegExp = /[\-{}\[\]+?.,\\\^$|#]/g, commandToRegExp = function(command) {
 | 
						||
		command = command.replace(escapeRegExp, '\\$&').replace(optionalParam, '(?:$1)?').replace(namedParam, function(match, optional) {
 | 
						||
			return optional ? match : '([^\\s]+)';
 | 
						||
		}).replace(splatParam, '(.*?)').replace(optionalRegex, '\\s*$1?\\s*');
 | 
						||
		return new RegExp('^' + command + '$', 'i');
 | 
						||
	};
 | 
						||
 | 
						||
	// This method receives an array of callbacks to iterate over, and invokes each of them
 | 
						||
	var invokeCallbacks = function(callbacks) {
 | 
						||
		callbacks.forEach(function(callback) {
 | 
						||
			callback.callback.apply(callback.context);
 | 
						||
		});
 | 
						||
	};
 | 
						||
 | 
						||
	var initIfNeeded = function() {
 | 
						||
		if (!isInitialized()) {
 | 
						||
			root.smartSpeechRecognition.init({}, false);
 | 
						||
		}
 | 
						||
	};
 | 
						||
 | 
						||
	var isInitialized = function() {
 | 
						||
		return recognition !== undefined;
 | 
						||
	};
 | 
						||
 | 
						||
	root.smartSpeechRecognition = {
 | 
						||
		// Initialize smartSpeechRecognition with a list of commands to recognize.
 | 
						||
		// e.g. smartSpeechRecognition.init({'hello :name': helloFunction})
 | 
						||
		// smartSpeechRecognition understands commands with named variables, splats, and optional words.
 | 
						||
		init : function(commands, resetCommands) {
 | 
						||
 | 
						||
			// resetCommands defaults to true
 | 
						||
			if (resetCommands === undefined) {
 | 
						||
				resetCommands = true;
 | 
						||
			} else {
 | 
						||
				resetCommands = !!resetCommands;
 | 
						||
			}
 | 
						||
 | 
						||
			// Abort previous instances of recognition already running
 | 
						||
			if (recognition && recognition.abort) {
 | 
						||
				recognition.abort();
 | 
						||
			}
 | 
						||
 | 
						||
			// initiate SpeechRecognition
 | 
						||
			recognition = new SpeechRecognition();
 | 
						||
 | 
						||
			// Set the max number of alternative transcripts to try and match with a command
 | 
						||
			recognition.maxAlternatives = 5;
 | 
						||
			recognition.continuous = true;
 | 
						||
			// Sets the language to the default 'en-US'. This can be changed with smartSpeechRecognition.setLanguage()
 | 
						||
			recognition.lang = voice_command_lang || 'en-US';
 | 
						||
 | 
						||
			recognition.onstart = function() {
 | 
						||
				invokeCallbacks(callbacks.start);
 | 
						||
				//debugState
 | 
						||
				if (debugState) {
 | 
						||
					root.console.log('%c ✔ SUCCESS: User allowed access the microphone service to start ', debugStyle_success);
 | 
						||
					root.console.log('Language setting is set to: ' + recognition.lang, debugStyle);
 | 
						||
				}
 | 
						||
				$.root_.removeClass("service-not-allowed");
 | 
						||
				$.root_.addClass("service-allowed");
 | 
						||
			};
 | 
						||
 | 
						||
			recognition.onerror = function(event) {
 | 
						||
				invokeCallbacks(callbacks.error);
 | 
						||
				switch (event.error) {
 | 
						||
					case 'network':
 | 
						||
						invokeCallbacks(callbacks.errorNetwork);
 | 
						||
						break;
 | 
						||
					case 'not-allowed':
 | 
						||
					case 'service-not-allowed':
 | 
						||
						// if permission to use the mic is denied, turn off auto-restart
 | 
						||
						autoRestart = false;
 | 
						||
						$.root_.removeClass("service-allowed");
 | 
						||
						$.root_.addClass("service-not-allowed");
 | 
						||
						//debugState
 | 
						||
						if (debugState) {
 | 
						||
							root.console.log('%c WARNING: Microphone was not detected (either user denied access or it is not installed properly) ', debugStyle_warning);
 | 
						||
						}
 | 
						||
						// determine if permission was denied by user or automatically.
 | 
						||
						if (new Date().getTime() - lastStartedAt < 200) {
 | 
						||
							invokeCallbacks(callbacks.errorPermissionBlocked);
 | 
						||
						} else {
 | 
						||
							invokeCallbacks(callbacks.errorPermissionDenied);
 | 
						||
							//console.log("You need your mic to be active")
 | 
						||
						}
 | 
						||
						break;
 | 
						||
				}
 | 
						||
			};
 | 
						||
 | 
						||
			recognition.onend = function() {
 | 
						||
				invokeCallbacks(callbacks.end);
 | 
						||
				// smartSpeechRecognition will auto restart if it is closed automatically and not by user action.
 | 
						||
				if (autoRestart) {
 | 
						||
					// play nicely with the browser, and never restart smartSpeechRecognition automatically more than once per second
 | 
						||
					var timeSinceLastStart = new Date().getTime() - lastStartedAt;
 | 
						||
					if (timeSinceLastStart < 1000) {
 | 
						||
						setTimeout(root.smartSpeechRecognition.start, 1000 - timeSinceLastStart);
 | 
						||
					} else {
 | 
						||
						root.smartSpeechRecognition.start();
 | 
						||
					}
 | 
						||
				}
 | 
						||
			};
 | 
						||
 | 
						||
			recognition.onresult = function(event) {
 | 
						||
				invokeCallbacks(callbacks.result);
 | 
						||
 | 
						||
				var results = event.results[event.resultIndex], commandText;
 | 
						||
 | 
						||
				// go over each of the 5 results and alternative results received (we've set maxAlternatives to 5 above)
 | 
						||
				for (var i = 0; i < results.length; i++) {
 | 
						||
					// the text recognized
 | 
						||
					commandText = results[i].transcript.trim();
 | 
						||
					if (debugState) {
 | 
						||
						root.console.log('Speech recognized: %c' + commandText, debugStyle);
 | 
						||
					}
 | 
						||
 | 
						||
					// try and match recognized text to one of the commands on the list
 | 
						||
					for (var j = 0, l = commandsList.length; j < l; j++) {
 | 
						||
						var result = commandsList[j].command.exec(commandText);
 | 
						||
						if (result) {
 | 
						||
							var parameters = result.slice(1);
 | 
						||
							if (debugState) {
 | 
						||
								root.console.log('command matched: %c' + commandsList[j].originalPhrase, debugStyle);
 | 
						||
								if (parameters.length) {
 | 
						||
									root.console.log('with parameters', parameters);
 | 
						||
								}
 | 
						||
							}
 | 
						||
							// execute the matched command
 | 
						||
							commandsList[j].callback.apply(this, parameters);
 | 
						||
							invokeCallbacks(callbacks.resultMatch);
 | 
						||
 | 
						||
							// for commands "sound on", "stop" and "mute" do not play sound or display message
 | 
						||
							//var myMatchedCommand = commandsList[j].originalPhrase;
 | 
						||
 | 
						||
							var ignoreCallsFor = ["sound on", "mute", "stop"];
 | 
						||
 | 
						||
							if (ignoreCallsFor.indexOf(commandsList[j].originalPhrase) < 0) {
 | 
						||
								// play sound when match found
 | 
						||
								$.smallBox({
 | 
						||
									title : (commandsList[j].originalPhrase),
 | 
						||
									content : "loading...",
 | 
						||
									color : "#333",
 | 
						||
									sound_file : 'voice_alert',
 | 
						||
									timeout : 2000
 | 
						||
								});
 | 
						||
 | 
						||
								if ($('#speech-btn .popover').is(':visible')) {
 | 
						||
									$('#speech-btn .popover').fadeOut(250);
 | 
						||
								}
 | 
						||
							}// end if
 | 
						||
 | 
						||
							return true;
 | 
						||
						}
 | 
						||
					} // end for
 | 
						||
				}// end for
 | 
						||
 | 
						||
				invokeCallbacks(callbacks.resultNoMatch);
 | 
						||
				//console.log("no match found for: " + commandText)
 | 
						||
				$.smallBox({
 | 
						||
					title : "Error: <strong>" + ' " ' + commandText + ' " ' + "</strong> no match found!",
 | 
						||
					content : "Please speak clearly into the microphone",
 | 
						||
					color : "#a90329",
 | 
						||
					timeout : 5000,
 | 
						||
					icon : "fa fa-microphone"
 | 
						||
				});
 | 
						||
				if ($('#speech-btn .popover').is(':visible')) {
 | 
						||
					$('#speech-btn .popover').fadeOut(250);
 | 
						||
				}
 | 
						||
				return false;
 | 
						||
			};
 | 
						||
 | 
						||
			// build commands list
 | 
						||
			if (resetCommands) {
 | 
						||
				commandsList = [];
 | 
						||
			}
 | 
						||
			if (commands.length) {
 | 
						||
				this.addCommands(commands);
 | 
						||
			}
 | 
						||
		},
 | 
						||
 | 
						||
		// Start listening (asking for permission first, if needed).
 | 
						||
		// Call this after you've initialized smartSpeechRecognition with commands.
 | 
						||
		// Receives an optional options object:
 | 
						||
		// { autoRestart: true }
 | 
						||
		start : function(options) {
 | 
						||
			initIfNeeded();
 | 
						||
			options = options || {};
 | 
						||
			if (options.autoRestart !== undefined) {
 | 
						||
				autoRestart = !!options.autoRestart;
 | 
						||
			} else {
 | 
						||
				autoRestart = true;
 | 
						||
			}
 | 
						||
			lastStartedAt = new Date().getTime();
 | 
						||
			recognition.start();
 | 
						||
		},
 | 
						||
 | 
						||
		// abort the listening session (aka stop)
 | 
						||
		abort : function() {
 | 
						||
			autoRestart = false;
 | 
						||
			if (isInitialized) {
 | 
						||
				recognition.abort();
 | 
						||
			}
 | 
						||
		},
 | 
						||
 | 
						||
		// Turn on output of debug messages to the console. Ugly, but super-handy!
 | 
						||
		debug : function(newState) {
 | 
						||
			if (arguments.length > 0) {
 | 
						||
				debugState = !!newState;
 | 
						||
			} else {
 | 
						||
				debugState = true;
 | 
						||
			}
 | 
						||
		},
 | 
						||
 | 
						||
		// Set the language the user will speak in. If not called, defaults to 'en-US'.
 | 
						||
		// e.g. 'fr-FR' (French-France), 'es-CR' (Español-Costa Rica)
 | 
						||
		setLanguage : function(language) {
 | 
						||
			initIfNeeded();
 | 
						||
			recognition.lang = language;
 | 
						||
		},
 | 
						||
 | 
						||
		// Add additional commands that smartSpeechRecognition will respond to. Similar in syntax to smartSpeechRecognition.init()
 | 
						||
		addCommands : function(commands) {
 | 
						||
			var cb, command;
 | 
						||
 | 
						||
			initIfNeeded();
 | 
						||
 | 
						||
			for (var phrase in commands) {
 | 
						||
				if (commands.hasOwnProperty(phrase)) {
 | 
						||
					cb = root[commands[phrase]] || commands[phrase];
 | 
						||
					if ( typeof cb !== 'function') {
 | 
						||
						continue;
 | 
						||
					}
 | 
						||
					//convert command to regex
 | 
						||
					command = commandToRegExp(phrase);
 | 
						||
 | 
						||
					commandsList.push({
 | 
						||
						command : command,
 | 
						||
						callback : cb,
 | 
						||
						originalPhrase : phrase
 | 
						||
					});
 | 
						||
				}
 | 
						||
			}
 | 
						||
			if (debugState) {
 | 
						||
				root.console.log('Commands successfully loaded: %c' + commandsList.length, debugStyle);
 | 
						||
			}
 | 
						||
		},
 | 
						||
 | 
						||
		// Remove existing commands. Called with a single phrase, array of phrases, or methodically. Pass no params to remove all commands.
 | 
						||
		removeCommands : function(commandsToRemove) {
 | 
						||
			if (commandsToRemove === undefined) {
 | 
						||
				commandsList = [];
 | 
						||
				return;
 | 
						||
			}
 | 
						||
			commandsToRemove = Array.isArray(commandsToRemove) ? commandsToRemove : [commandsToRemove];
 | 
						||
			commandsList = commandsList.filter(function(command) {
 | 
						||
				for (var i = 0; i < commandsToRemove.length; i++) {
 | 
						||
					if (commandsToRemove[i] === command.originalPhrase) {
 | 
						||
						return false;
 | 
						||
					}
 | 
						||
				}
 | 
						||
				return true;
 | 
						||
			});
 | 
						||
		},
 | 
						||
 | 
						||
		// Lets the user add a callback of one of 9 types:
 | 
						||
		// start, error, end, result, resultMatch, resultNoMatch, errorNetwork, errorPermissionBlocked, errorPermissionDenied
 | 
						||
		// Can also optionally receive a context for the callback function as the third argument
 | 
						||
		addCallback : function(type, callback, context) {
 | 
						||
			if (callbacks[type] === undefined) {
 | 
						||
				return;
 | 
						||
			}
 | 
						||
			var cb = root[callback] || callback;
 | 
						||
			if ( typeof cb !== 'function') {
 | 
						||
				return;
 | 
						||
			}
 | 
						||
			callbacks[type].push({
 | 
						||
				callback : cb,
 | 
						||
				context : context || this
 | 
						||
			});
 | 
						||
		}
 | 
						||
	};
 | 
						||
 | 
						||
}).call(this);
 | 
						||
 | 
						||
var autoStart = function() {
 | 
						||
 | 
						||
	smartSpeechRecognition.addCommands(commands);
 | 
						||
 | 
						||
	if (smartSpeechRecognition) {
 | 
						||
		// activate plugin
 | 
						||
		smartSpeechRecognition.start();
 | 
						||
		// add btn class
 | 
						||
		$.root_.addClass("voice-command-active");
 | 
						||
		// set localStorage when switch is on manually
 | 
						||
		if (voice_localStorage) {
 | 
						||
			localStorage.setItem('sm-setautovoice', 'true');
 | 
						||
		}
 | 
						||
 | 
						||
	} else {
 | 
						||
		// if plugin not found
 | 
						||
		alert("speech plugin not loaded");
 | 
						||
	}
 | 
						||
}
 | 
						||
// if already running with localstorage
 | 
						||
if (SpeechRecognition && voice_command && localStorage.getItem('sm-setautovoice') == 'true') {
 | 
						||
	autoStart();
 | 
						||
}
 | 
						||
 | 
						||
// auto start
 | 
						||
if (SpeechRecognition && voice_command_auto && voice_command) {
 | 
						||
	autoStart();
 | 
						||
} |