· 6 years ago · Jun 29, 2019, 08:52 AM
1/* eslint-disable */
2// Platform: android
3// 74a4adc2d0fddb1e0cfb9be1961494ef0afc9893
4/*
5 Licensed to the Apache Software Foundation (ASF) under one
6 or more contributor license agreements. See the NOTICE file
7 distributed with this work for additional information
8 regarding copyright ownership. The ASF licenses this file
9 to you under the Apache License, Version 2.0 (the
10 "License"); you may not use this file except in compliance
11 with the License. You may obtain a copy of the License at
12
13 http://www.apache.org/licenses/LICENSE-2.0
14
15 Unless required by applicable law or agreed to in writing,
16 software distributed under the License is distributed on an
17 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 KIND, either express or implied. See the License for the
19 specific language governing permissions and limitations
20 under the License.
21*/
22;(function() {
23var PLATFORM_VERSION_BUILD_LABEL = '6.3.0';
24// file: src/scripts/require.js
25
26/*jshint -W079 */
27/*jshint -W020 */
28
29var require,
30 define;
31
32(function () {
33 var modules = {},
34 // Stack of moduleIds currently being built.
35 requireStack = [],
36 // Map of module ID -> index into requireStack of modules currently being built.
37 inProgressModules = {},
38 SEPARATOR = ".";
39
40
41
42 function build(module) {
43 var factory = module.factory,
44 localRequire = function (id) {
45 var resultantId = id;
46 //Its a relative path, so lop off the last portion and add the id (minus "./")
47 if (id.charAt(0) === ".") {
48 resultantId = module.id.slice(0, module.id.lastIndexOf(SEPARATOR)) + SEPARATOR + id.slice(2);
49 }
50 return require(resultantId);
51 };
52 module.exports = {};
53 delete module.factory;
54 factory(localRequire, module.exports, module);
55 return module.exports;
56 }
57
58 require = function (id) {
59 if (!modules[id]) {
60 throw "module " + id + " not found";
61 } else if (id in inProgressModules) {
62 var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
63 throw "Cycle in require graph: " + cycle;
64 }
65 if (modules[id].factory) {
66 try {
67 inProgressModules[id] = requireStack.length;
68 requireStack.push(id);
69 return build(modules[id]);
70 } finally {
71 delete inProgressModules[id];
72 requireStack.pop();
73 }
74 }
75 return modules[id].exports;
76 };
77
78 define = function (id, factory) {
79 if (modules[id]) {
80 throw "module " + id + " already defined";
81 }
82
83 modules[id] = {
84 id: id,
85 factory: factory
86 };
87 };
88
89 define.remove = function (id) {
90 delete modules[id];
91 };
92
93 define.moduleMap = modules;
94})();
95
96//Export for use in node
97if (typeof module === "object" && typeof require === "function") {
98 module.exports.require = require;
99 module.exports.define = define;
100}
101
102// file: src/cordova.js
103define("cordova", function(require, exports, module) {
104
105// Workaround for Windows 10 in hosted environment case
106// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
107if (window.cordova && !(window.cordova instanceof HTMLElement)) {
108 throw new Error("cordova already defined");
109}
110
111
112var channel = require('cordova/channel');
113var platform = require('cordova/platform');
114
115
116/**
117 * Intercept calls to addEventListener + removeEventListener and handle deviceready,
118 * resume, and pause events.
119 */
120var m_document_addEventListener = document.addEventListener;
121var m_document_removeEventListener = document.removeEventListener;
122var m_window_addEventListener = window.addEventListener;
123var m_window_removeEventListener = window.removeEventListener;
124
125/**
126 * Houses custom event handlers to intercept on document + window event listeners.
127 */
128var documentEventHandlers = {},
129 windowEventHandlers = {};
130
131document.addEventListener = function(evt, handler, capture) {
132 var e = evt.toLowerCase();
133 if (typeof documentEventHandlers[e] != 'undefined') {
134 documentEventHandlers[e].subscribe(handler);
135 } else {
136 m_document_addEventListener.call(document, evt, handler, capture);
137 }
138};
139
140window.addEventListener = function(evt, handler, capture) {
141 var e = evt.toLowerCase();
142 if (typeof windowEventHandlers[e] != 'undefined') {
143 windowEventHandlers[e].subscribe(handler);
144 } else {
145 m_window_addEventListener.call(window, evt, handler, capture);
146 }
147};
148
149document.removeEventListener = function(evt, handler, capture) {
150 var e = evt.toLowerCase();
151 // If unsubscribing from an event that is handled by a plugin
152 if (typeof documentEventHandlers[e] != "undefined") {
153 documentEventHandlers[e].unsubscribe(handler);
154 } else {
155 m_document_removeEventListener.call(document, evt, handler, capture);
156 }
157};
158
159window.removeEventListener = function(evt, handler, capture) {
160 var e = evt.toLowerCase();
161 // If unsubscribing from an event that is handled by a plugin
162 if (typeof windowEventHandlers[e] != "undefined") {
163 windowEventHandlers[e].unsubscribe(handler);
164 } else {
165 m_window_removeEventListener.call(window, evt, handler, capture);
166 }
167};
168
169function createEvent(type, data) {
170 var event = document.createEvent('Events');
171 event.initEvent(type, false, false);
172 if (data) {
173 for (var i in data) {
174 if (data.hasOwnProperty(i)) {
175 event[i] = data[i];
176 }
177 }
178 }
179 return event;
180}
181
182
183var cordova = {
184 define:define,
185 require:require,
186 version:PLATFORM_VERSION_BUILD_LABEL,
187 platformVersion:PLATFORM_VERSION_BUILD_LABEL,
188 platformId:platform.id,
189 /**
190 * Methods to add/remove your own addEventListener hijacking on document + window.
191 */
192 addWindowEventHandler:function(event) {
193 return (windowEventHandlers[event] = channel.create(event));
194 },
195 addStickyDocumentEventHandler:function(event) {
196 return (documentEventHandlers[event] = channel.createSticky(event));
197 },
198 addDocumentEventHandler:function(event) {
199 return (documentEventHandlers[event] = channel.create(event));
200 },
201 removeWindowEventHandler:function(event) {
202 delete windowEventHandlers[event];
203 },
204 removeDocumentEventHandler:function(event) {
205 delete documentEventHandlers[event];
206 },
207 /**
208 * Retrieve original event handlers that were replaced by Cordova
209 *
210 * @return object
211 */
212 getOriginalHandlers: function() {
213 return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
214 'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
215 },
216 /**
217 * Method to fire event from native code
218 * bNoDetach is required for events which cause an exception which needs to be caught in native code
219 */
220 fireDocumentEvent: function(type, data, bNoDetach) {
221 var evt = createEvent(type, data);
222 if (typeof documentEventHandlers[type] != 'undefined') {
223 if( bNoDetach ) {
224 documentEventHandlers[type].fire(evt);
225 }
226 else {
227 setTimeout(function() {
228 // Fire deviceready on listeners that were registered before cordova.js was loaded.
229 if (type == 'deviceready') {
230 document.dispatchEvent(evt);
231 }
232 documentEventHandlers[type].fire(evt);
233 }, 0);
234 }
235 } else {
236 document.dispatchEvent(evt);
237 }
238 },
239 fireWindowEvent: function(type, data) {
240 var evt = createEvent(type,data);
241 if (typeof windowEventHandlers[type] != 'undefined') {
242 setTimeout(function() {
243 windowEventHandlers[type].fire(evt);
244 }, 0);
245 } else {
246 window.dispatchEvent(evt);
247 }
248 },
249
250 /**
251 * Plugin callback mechanism.
252 */
253 // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
254 // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
255 callbackId: Math.floor(Math.random() * 2000000000),
256 callbacks: {},
257 callbackStatus: {
258 NO_RESULT: 0,
259 OK: 1,
260 CLASS_NOT_FOUND_EXCEPTION: 2,
261 ILLEGAL_ACCESS_EXCEPTION: 3,
262 INSTANTIATION_EXCEPTION: 4,
263 MALFORMED_URL_EXCEPTION: 5,
264 IO_EXCEPTION: 6,
265 INVALID_ACTION: 7,
266 JSON_EXCEPTION: 8,
267 ERROR: 9
268 },
269
270 /**
271 * Called by native code when returning successful result from an action.
272 */
273 callbackSuccess: function(callbackId, args) {
274 cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
275 },
276
277 /**
278 * Called by native code when returning error result from an action.
279 */
280 callbackError: function(callbackId, args) {
281 // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
282 // Derive success from status.
283 cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
284 },
285
286 /**
287 * Called by native code when returning the result from an action.
288 */
289 callbackFromNative: function(callbackId, isSuccess, status, args, keepCallback) {
290 try {
291 var callback = cordova.callbacks[callbackId];
292 if (callback) {
293 if (isSuccess && status == cordova.callbackStatus.OK) {
294 callback.success && callback.success.apply(null, args);
295 } else if (!isSuccess) {
296 callback.fail && callback.fail.apply(null, args);
297 }
298 /*
299 else
300 Note, this case is intentionally not caught.
301 this can happen if isSuccess is true, but callbackStatus is NO_RESULT
302 which is used to remove a callback from the list without calling the callbacks
303 typically keepCallback is false in this case
304 */
305 // Clear callback if not expecting any more results
306 if (!keepCallback) {
307 delete cordova.callbacks[callbackId];
308 }
309 }
310 }
311 catch (err) {
312 var msg = "Error in " + (isSuccess ? "Success" : "Error") + " callbackId: " + callbackId + " : " + err;
313 console && console.log && console.log(msg);
314 cordova.fireWindowEvent("cordovacallbackerror", { 'message': msg });
315 throw err;
316 }
317 },
318 addConstructor: function(func) {
319 channel.onCordovaReady.subscribe(function() {
320 try {
321 func();
322 } catch(e) {
323 console.log("Failed to run constructor: " + e);
324 }
325 });
326 }
327};
328
329
330module.exports = cordova;
331
332});
333
334// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js
335define("cordova/android/nativeapiprovider", function(require, exports, module) {
336
337/**
338 * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
339 */
340
341var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
342var currentApi = nativeApi;
343
344module.exports = {
345 get: function() { return currentApi; },
346 setPreferPrompt: function(value) {
347 currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
348 },
349 // Used only by tests.
350 set: function(value) {
351 currentApi = value;
352 }
353};
354
355});
356
357// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js
358define("cordova/android/promptbasednativeapi", function(require, exports, module) {
359
360/**
361 * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
362 * This is used pre-JellyBean, where addJavascriptInterface() is disabled.
363 */
364
365module.exports = {
366 exec: function(bridgeSecret, service, action, callbackId, argsJson) {
367 return prompt(argsJson, 'gap:'+JSON.stringify([bridgeSecret, service, action, callbackId]));
368 },
369 setNativeToJsBridgeMode: function(bridgeSecret, value) {
370 prompt(value, 'gap_bridge_mode:' + bridgeSecret);
371 },
372 retrieveJsMessages: function(bridgeSecret, fromOnlineEvent) {
373 return prompt(+fromOnlineEvent, 'gap_poll:' + bridgeSecret);
374 }
375};
376
377});
378
379// file: src/common/argscheck.js
380define("cordova/argscheck", function(require, exports, module) {
381
382var utils = require('cordova/utils');
383
384var moduleExports = module.exports;
385
386var typeMap = {
387 'A': 'Array',
388 'D': 'Date',
389 'N': 'Number',
390 'S': 'String',
391 'F': 'Function',
392 'O': 'Object'
393};
394
395function extractParamName(callee, argIndex) {
396 return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
397}
398
399function checkArgs(spec, functionName, args, opt_callee) {
400 if (!moduleExports.enableChecks) {
401 return;
402 }
403 var errMsg = null;
404 var typeName;
405 for (var i = 0; i < spec.length; ++i) {
406 var c = spec.charAt(i),
407 cUpper = c.toUpperCase(),
408 arg = args[i];
409 // Asterix means allow anything.
410 if (c == '*') {
411 continue;
412 }
413 typeName = utils.typeName(arg);
414 if ((arg === null || arg === undefined) && c == cUpper) {
415 continue;
416 }
417 if (typeName != typeMap[cUpper]) {
418 errMsg = 'Expected ' + typeMap[cUpper];
419 break;
420 }
421 }
422 if (errMsg) {
423 errMsg += ', but got ' + typeName + '.';
424 errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
425 // Don't log when running unit tests.
426 if (typeof jasmine == 'undefined') {
427 console.error(errMsg);
428 }
429 throw TypeError(errMsg);
430 }
431}
432
433function getValue(value, defaultValue) {
434 return value === undefined ? defaultValue : value;
435}
436
437moduleExports.checkArgs = checkArgs;
438moduleExports.getValue = getValue;
439moduleExports.enableChecks = true;
440
441
442});
443
444// file: src/common/base64.js
445define("cordova/base64", function(require, exports, module) {
446
447var base64 = exports;
448
449base64.fromArrayBuffer = function(arrayBuffer) {
450 var array = new Uint8Array(arrayBuffer);
451 return uint8ToBase64(array);
452};
453
454base64.toArrayBuffer = function(str) {
455 var decodedStr = typeof atob != 'undefined' ? atob(str) : new Buffer(str,'base64').toString('binary');
456 var arrayBuffer = new ArrayBuffer(decodedStr.length);
457 var array = new Uint8Array(arrayBuffer);
458 for (var i=0, len=decodedStr.length; i < len; i++) {
459 array[i] = decodedStr.charCodeAt(i);
460 }
461 return arrayBuffer;
462};
463
464//------------------------------------------------------------------------------
465
466/* This code is based on the performance tests at http://jsperf.com/b64tests
467 * This 12-bit-at-a-time algorithm was the best performing version on all
468 * platforms tested.
469 */
470
471var b64_6bit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
472var b64_12bit;
473
474var b64_12bitTable = function() {
475 b64_12bit = [];
476 for (var i=0; i<64; i++) {
477 for (var j=0; j<64; j++) {
478 b64_12bit[i*64+j] = b64_6bit[i] + b64_6bit[j];
479 }
480 }
481 b64_12bitTable = function() { return b64_12bit; };
482 return b64_12bit;
483};
484
485function uint8ToBase64(rawData) {
486 var numBytes = rawData.byteLength;
487 var output="";
488 var segment;
489 var table = b64_12bitTable();
490 for (var i=0;i<numBytes-2;i+=3) {
491 segment = (rawData[i] << 16) + (rawData[i+1] << 8) + rawData[i+2];
492 output += table[segment >> 12];
493 output += table[segment & 0xfff];
494 }
495 if (numBytes - i == 2) {
496 segment = (rawData[i] << 16) + (rawData[i+1] << 8);
497 output += table[segment >> 12];
498 output += b64_6bit[(segment & 0xfff) >> 6];
499 output += '=';
500 } else if (numBytes - i == 1) {
501 segment = (rawData[i] << 16);
502 output += table[segment >> 12];
503 output += '==';
504 }
505 return output;
506}
507
508});
509
510// file: src/common/builder.js
511define("cordova/builder", function(require, exports, module) {
512
513var utils = require('cordova/utils');
514
515function each(objects, func, context) {
516 for (var prop in objects) {
517 if (objects.hasOwnProperty(prop)) {
518 func.apply(context, [objects[prop], prop]);
519 }
520 }
521}
522
523function clobber(obj, key, value) {
524 exports.replaceHookForTesting(obj, key);
525 var needsProperty = false;
526 try {
527 obj[key] = value;
528 } catch (e) {
529 needsProperty = true;
530 }
531 // Getters can only be overridden by getters.
532 if (needsProperty || obj[key] !== value) {
533 utils.defineGetter(obj, key, function() {
534 return value;
535 });
536 }
537}
538
539function assignOrWrapInDeprecateGetter(obj, key, value, message) {
540 if (message) {
541 utils.defineGetter(obj, key, function() {
542 console.log(message);
543 delete obj[key];
544 clobber(obj, key, value);
545 return value;
546 });
547 } else {
548 clobber(obj, key, value);
549 }
550}
551
552function include(parent, objects, clobber, merge) {
553 each(objects, function (obj, key) {
554 try {
555 var result = obj.path ? require(obj.path) : {};
556
557 if (clobber) {
558 // Clobber if it doesn't exist.
559 if (typeof parent[key] === 'undefined') {
560 assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
561 } else if (typeof obj.path !== 'undefined') {
562 // If merging, merge properties onto parent, otherwise, clobber.
563 if (merge) {
564 recursiveMerge(parent[key], result);
565 } else {
566 assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
567 }
568 }
569 result = parent[key];
570 } else {
571 // Overwrite if not currently defined.
572 if (typeof parent[key] == 'undefined') {
573 assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
574 } else {
575 // Set result to what already exists, so we can build children into it if they exist.
576 result = parent[key];
577 }
578 }
579
580 if (obj.children) {
581 include(result, obj.children, clobber, merge);
582 }
583 } catch(e) {
584 utils.alert('Exception building Cordova JS globals: ' + e + ' for key "' + key + '"');
585 }
586 });
587}
588
589/**
590 * Merge properties from one object onto another recursively. Properties from
591 * the src object will overwrite existing target property.
592 *
593 * @param target Object to merge properties into.
594 * @param src Object to merge properties from.
595 */
596function recursiveMerge(target, src) {
597 for (var prop in src) {
598 if (src.hasOwnProperty(prop)) {
599 if (target.prototype && target.prototype.constructor === target) {
600 // If the target object is a constructor override off prototype.
601 clobber(target.prototype, prop, src[prop]);
602 } else {
603 if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
604 recursiveMerge(target[prop], src[prop]);
605 } else {
606 clobber(target, prop, src[prop]);
607 }
608 }
609 }
610 }
611}
612
613exports.buildIntoButDoNotClobber = function(objects, target) {
614 include(target, objects, false, false);
615};
616exports.buildIntoAndClobber = function(objects, target) {
617 include(target, objects, true, false);
618};
619exports.buildIntoAndMerge = function(objects, target) {
620 include(target, objects, true, true);
621};
622exports.recursiveMerge = recursiveMerge;
623exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
624exports.replaceHookForTesting = function() {};
625
626});
627
628// file: src/common/channel.js
629define("cordova/channel", function(require, exports, module) {
630
631var utils = require('cordova/utils'),
632 nextGuid = 1;
633
634/**
635 * Custom pub-sub "channel" that can have functions subscribed to it
636 * This object is used to define and control firing of events for
637 * cordova initialization, as well as for custom events thereafter.
638 *
639 * The order of events during page load and Cordova startup is as follows:
640 *
641 * onDOMContentLoaded* Internal event that is received when the web page is loaded and parsed.
642 * onNativeReady* Internal event that indicates the Cordova native side is ready.
643 * onCordovaReady* Internal event fired when all Cordova JavaScript objects have been created.
644 * onDeviceReady* User event fired to indicate that Cordova is ready
645 * onResume User event fired to indicate a start/resume lifecycle event
646 * onPause User event fired to indicate a pause lifecycle event
647 *
648 * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
649 * All listeners that subscribe after the event is fired will be executed right away.
650 *
651 * The only Cordova events that user code should register for are:
652 * deviceready Cordova native code is initialized and Cordova APIs can be called from JavaScript
653 * pause App has moved to background
654 * resume App has returned to foreground
655 *
656 * Listeners can be registered as:
657 * document.addEventListener("deviceready", myDeviceReadyListener, false);
658 * document.addEventListener("resume", myResumeListener, false);
659 * document.addEventListener("pause", myPauseListener, false);
660 *
661 * The DOM lifecycle events should be used for saving and restoring state
662 * window.onload
663 * window.onunload
664 *
665 */
666
667/**
668 * Channel
669 * @constructor
670 * @param type String the channel name
671 */
672var Channel = function(type, sticky) {
673 this.type = type;
674 // Map of guid -> function.
675 this.handlers = {};
676 // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
677 this.state = sticky ? 1 : 0;
678 // Used in sticky mode to remember args passed to fire().
679 this.fireArgs = null;
680 // Used by onHasSubscribersChange to know if there are any listeners.
681 this.numHandlers = 0;
682 // Function that is called when the first listener is subscribed, or when
683 // the last listener is unsubscribed.
684 this.onHasSubscribersChange = null;
685},
686 channel = {
687 /**
688 * Calls the provided function only after all of the channels specified
689 * have been fired. All channels must be sticky channels.
690 */
691 join: function(h, c) {
692 var len = c.length,
693 i = len,
694 f = function() {
695 if (!(--i)) h();
696 };
697 for (var j=0; j<len; j++) {
698 if (c[j].state === 0) {
699 throw Error('Can only use join with sticky channels.');
700 }
701 c[j].subscribe(f);
702 }
703 if (!len) h();
704 },
705 create: function(type) {
706 return channel[type] = new Channel(type, false);
707 },
708 createSticky: function(type) {
709 return channel[type] = new Channel(type, true);
710 },
711
712 /**
713 * cordova Channels that must fire before "deviceready" is fired.
714 */
715 deviceReadyChannelsArray: [],
716 deviceReadyChannelsMap: {},
717
718 /**
719 * Indicate that a feature needs to be initialized before it is ready to be used.
720 * This holds up Cordova's "deviceready" event until the feature has been initialized
721 * and Cordova.initComplete(feature) is called.
722 *
723 * @param feature {String} The unique feature name
724 */
725 waitForInitialization: function(feature) {
726 if (feature) {
727 var c = channel[feature] || this.createSticky(feature);
728 this.deviceReadyChannelsMap[feature] = c;
729 this.deviceReadyChannelsArray.push(c);
730 }
731 },
732
733 /**
734 * Indicate that initialization code has completed and the feature is ready to be used.
735 *
736 * @param feature {String} The unique feature name
737 */
738 initializationComplete: function(feature) {
739 var c = this.deviceReadyChannelsMap[feature];
740 if (c) {
741 c.fire();
742 }
743 }
744 };
745
746function checkSubscriptionArgument(argument) {
747 if (typeof argument !== "function" && typeof argument.handleEvent !== "function") {
748 throw new Error(
749 "Must provide a function or an EventListener object " +
750 "implementing the handleEvent interface."
751 );
752 }
753}
754
755/**
756 * Subscribes the given function to the channel. Any time that
757 * Channel.fire is called so too will the function.
758 * Optionally specify an execution context for the function
759 * and a guid that can be used to stop subscribing to the channel.
760 * Returns the guid.
761 */
762Channel.prototype.subscribe = function(eventListenerOrFunction, eventListener) {
763 checkSubscriptionArgument(eventListenerOrFunction);
764 var handleEvent, guid;
765
766 if (eventListenerOrFunction && typeof eventListenerOrFunction === "object") {
767 // Received an EventListener object implementing the handleEvent interface
768 handleEvent = eventListenerOrFunction.handleEvent;
769 eventListener = eventListenerOrFunction;
770 } else {
771 // Received a function to handle event
772 handleEvent = eventListenerOrFunction;
773 }
774
775 if (this.state == 2) {
776 handleEvent.apply(eventListener || this, this.fireArgs);
777 return;
778 }
779
780 guid = eventListenerOrFunction.observer_guid;
781 if (typeof eventListener === "object") {
782 handleEvent = utils.close(eventListener, handleEvent);
783 }
784
785 if (!guid) {
786 // First time any channel has seen this subscriber
787 guid = '' + nextGuid++;
788 }
789 handleEvent.observer_guid = guid;
790 eventListenerOrFunction.observer_guid = guid;
791
792 // Don't add the same handler more than once.
793 if (!this.handlers[guid]) {
794 this.handlers[guid] = handleEvent;
795 this.numHandlers++;
796 if (this.numHandlers == 1) {
797 this.onHasSubscribersChange && this.onHasSubscribersChange();
798 }
799 }
800};
801
802/**
803 * Unsubscribes the function with the given guid from the channel.
804 */
805Channel.prototype.unsubscribe = function(eventListenerOrFunction) {
806 checkSubscriptionArgument(eventListenerOrFunction);
807 var handleEvent, guid, handler;
808
809 if (eventListenerOrFunction && typeof eventListenerOrFunction === "object") {
810 // Received an EventListener object implementing the handleEvent interface
811 handleEvent = eventListenerOrFunction.handleEvent;
812 } else {
813 // Received a function to handle event
814 handleEvent = eventListenerOrFunction;
815 }
816
817 guid = handleEvent.observer_guid;
818 handler = this.handlers[guid];
819 if (handler) {
820 delete this.handlers[guid];
821 this.numHandlers--;
822 if (this.numHandlers === 0) {
823 this.onHasSubscribersChange && this.onHasSubscribersChange();
824 }
825 }
826};
827
828/**
829 * Calls all functions subscribed to this channel.
830 */
831Channel.prototype.fire = function(e) {
832 var fail = false,
833 fireArgs = Array.prototype.slice.call(arguments);
834 // Apply stickiness.
835 if (this.state == 1) {
836 this.state = 2;
837 this.fireArgs = fireArgs;
838 }
839 if (this.numHandlers) {
840 // Copy the values first so that it is safe to modify it from within
841 // callbacks.
842 var toCall = [];
843 for (var item in this.handlers) {
844 toCall.push(this.handlers[item]);
845 }
846 for (var i = 0; i < toCall.length; ++i) {
847 toCall[i].apply(this, fireArgs);
848 }
849 if (this.state == 2 && this.numHandlers) {
850 this.numHandlers = 0;
851 this.handlers = {};
852 this.onHasSubscribersChange && this.onHasSubscribersChange();
853 }
854 }
855};
856
857
858// defining them here so they are ready super fast!
859// DOM event that is received when the web page is loaded and parsed.
860channel.createSticky('onDOMContentLoaded');
861
862// Event to indicate the Cordova native side is ready.
863channel.createSticky('onNativeReady');
864
865// Event to indicate that all Cordova JavaScript objects have been created
866// and it's time to run plugin constructors.
867channel.createSticky('onCordovaReady');
868
869// Event to indicate that all automatically loaded JS plugins are loaded and ready.
870// FIXME remove this
871channel.createSticky('onPluginsReady');
872
873// Event to indicate that Cordova is ready
874channel.createSticky('onDeviceReady');
875
876// Event to indicate a resume lifecycle event
877channel.create('onResume');
878
879// Event to indicate a pause lifecycle event
880channel.create('onPause');
881
882// Channels that must fire before "deviceready" is fired.
883channel.waitForInitialization('onCordovaReady');
884channel.waitForInitialization('onDOMContentLoaded');
885
886module.exports = channel;
887
888});
889
890// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/exec.js
891define("cordova/exec", function(require, exports, module) {
892
893/**
894 * Execute a cordova command. It is up to the native side whether this action
895 * is synchronous or asynchronous. The native side can return:
896 * Synchronous: PluginResult object as a JSON string
897 * Asynchronous: Empty string ""
898 * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
899 * depending upon the result of the action.
900 *
901 * @param {Function} success The success callback
902 * @param {Function} fail The fail callback
903 * @param {String} service The name of the service to use
904 * @param {String} action Action to be run in cordova
905 * @param {String[]} [args] Zero or more arguments to pass to the method
906 */
907var cordova = require('cordova'),
908 nativeApiProvider = require('cordova/android/nativeapiprovider'),
909 utils = require('cordova/utils'),
910 base64 = require('cordova/base64'),
911 channel = require('cordova/channel'),
912 jsToNativeModes = {
913 PROMPT: 0,
914 JS_OBJECT: 1
915 },
916 nativeToJsModes = {
917 // Polls for messages using the JS->Native bridge.
918 POLLING: 0,
919 // For LOAD_URL to be viable, it would need to have a work-around for
920 // the bug where the soft-keyboard gets dismissed when a message is sent.
921 LOAD_URL: 1,
922 // For the ONLINE_EVENT to be viable, it would need to intercept all event
923 // listeners (both through addEventListener and window.ononline) as well
924 // as set the navigator property itself.
925 ONLINE_EVENT: 2,
926 EVAL_BRIDGE: 3
927 },
928 jsToNativeBridgeMode, // Set lazily.
929 nativeToJsBridgeMode = nativeToJsModes.EVAL_BRIDGE,
930 pollEnabled = false,
931 bridgeSecret = -1;
932
933var messagesFromNative = [];
934var isProcessing = false;
935var resolvedPromise = typeof Promise == 'undefined' ? null : Promise.resolve();
936var nextTick = resolvedPromise ? function(fn) { resolvedPromise.then(fn); } : function(fn) { setTimeout(fn); };
937
938function androidExec(success, fail, service, action, args) {
939 if (bridgeSecret < 0) {
940 // If we ever catch this firing, we'll need to queue up exec()s
941 // and fire them once we get a secret. For now, I don't think
942 // it's possible for exec() to be called since plugins are parsed but
943 // not run until until after onNativeReady.
944 throw new Error('exec() called without bridgeSecret');
945 }
946 // Set default bridge modes if they have not already been set.
947 // By default, we use the failsafe, since addJavascriptInterface breaks too often
948 if (jsToNativeBridgeMode === undefined) {
949 androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
950 }
951
952 // If args is not provided, default to an empty array
953 args = args || [];
954
955 // Process any ArrayBuffers in the args into a string.
956 for (var i = 0; i < args.length; i++) {
957 if (utils.typeName(args[i]) == 'ArrayBuffer') {
958 args[i] = base64.fromArrayBuffer(args[i]);
959 }
960 }
961
962 var callbackId = service + cordova.callbackId++,
963 argsJson = JSON.stringify(args);
964 if (success || fail) {
965 cordova.callbacks[callbackId] = {success:success, fail:fail};
966 }
967
968 var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);
969 // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
970 // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2. See CB-2666.
971 if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && msgs === "@Null arguments.") {
972 androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
973 androidExec(success, fail, service, action, args);
974 androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
975 } else if (msgs) {
976 messagesFromNative.push(msgs);
977 // Always process async to avoid exceptions messing up stack.
978 nextTick(processMessages);
979 }
980}
981
982androidExec.init = function() {
983 //CB-11828
984 //This failsafe checks the version of Android and if it's Jellybean, it switches it to
985 //using the Online Event bridge for communicating from Native to JS
986 //
987 //It's ugly, but it's necessary.
988 var check = navigator.userAgent.toLowerCase().match(/android\s[0-9].[0-9]/);
989 var version_code = check && check[0].match(/4.[0-3].*/);
990 if (version_code != null && nativeToJsBridgeMode == nativeToJsModes.EVAL_BRIDGE) {
991 nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT;
992 }
993
994 bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode);
995 channel.onNativeReady.fire();
996};
997
998function pollOnceFromOnlineEvent() {
999 pollOnce(true);
1000}
1001
1002function pollOnce(opt_fromOnlineEvent) {
1003 if (bridgeSecret < 0) {
1004 // This can happen when the NativeToJsMessageQueue resets the online state on page transitions.
1005 // We know there's nothing to retrieve, so no need to poll.
1006 return;
1007 }
1008 var msgs = nativeApiProvider.get().retrieveJsMessages(bridgeSecret, !!opt_fromOnlineEvent);
1009 if (msgs) {
1010 messagesFromNative.push(msgs);
1011 // Process sync since we know we're already top-of-stack.
1012 processMessages();
1013 }
1014}
1015
1016function pollingTimerFunc() {
1017 if (pollEnabled) {
1018 pollOnce();
1019 setTimeout(pollingTimerFunc, 50);
1020 }
1021}
1022
1023function hookOnlineApis() {
1024 function proxyEvent(e) {
1025 cordova.fireWindowEvent(e.type);
1026 }
1027 // The network module takes care of firing online and offline events.
1028 // It currently fires them only on document though, so we bridge them
1029 // to window here (while first listening for exec()-releated online/offline
1030 // events).
1031 window.addEventListener('online', pollOnceFromOnlineEvent, false);
1032 window.addEventListener('offline', pollOnceFromOnlineEvent, false);
1033 cordova.addWindowEventHandler('online');
1034 cordova.addWindowEventHandler('offline');
1035 document.addEventListener('online', proxyEvent, false);
1036 document.addEventListener('offline', proxyEvent, false);
1037}
1038
1039hookOnlineApis();
1040
1041androidExec.jsToNativeModes = jsToNativeModes;
1042androidExec.nativeToJsModes = nativeToJsModes;
1043
1044androidExec.setJsToNativeBridgeMode = function(mode) {
1045 if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
1046 mode = jsToNativeModes.PROMPT;
1047 }
1048 nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
1049 jsToNativeBridgeMode = mode;
1050};
1051
1052androidExec.setNativeToJsBridgeMode = function(mode) {
1053 if (mode == nativeToJsBridgeMode) {
1054 return;
1055 }
1056 if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
1057 pollEnabled = false;
1058 }
1059
1060 nativeToJsBridgeMode = mode;
1061 // Tell the native side to switch modes.
1062 // Otherwise, it will be set by androidExec.init()
1063 if (bridgeSecret >= 0) {
1064 nativeApiProvider.get().setNativeToJsBridgeMode(bridgeSecret, mode);
1065 }
1066
1067 if (mode == nativeToJsModes.POLLING) {
1068 pollEnabled = true;
1069 setTimeout(pollingTimerFunc, 1);
1070 }
1071};
1072
1073function buildPayload(payload, message) {
1074 var payloadKind = message.charAt(0);
1075 if (payloadKind == 's') {
1076 payload.push(message.slice(1));
1077 } else if (payloadKind == 't') {
1078 payload.push(true);
1079 } else if (payloadKind == 'f') {
1080 payload.push(false);
1081 } else if (payloadKind == 'N') {
1082 payload.push(null);
1083 } else if (payloadKind == 'n') {
1084 payload.push(+message.slice(1));
1085 } else if (payloadKind == 'A') {
1086 var data = message.slice(1);
1087 payload.push(base64.toArrayBuffer(data));
1088 } else if (payloadKind == 'S') {
1089 payload.push(window.atob(message.slice(1)));
1090 } else if (payloadKind == 'M') {
1091 var multipartMessages = message.slice(1);
1092 while (multipartMessages !== "") {
1093 var spaceIdx = multipartMessages.indexOf(' ');
1094 var msgLen = +multipartMessages.slice(0, spaceIdx);
1095 var multipartMessage = multipartMessages.substr(spaceIdx + 1, msgLen);
1096 multipartMessages = multipartMessages.slice(spaceIdx + msgLen + 1);
1097 buildPayload(payload, multipartMessage);
1098 }
1099 } else {
1100 payload.push(JSON.parse(message));
1101 }
1102}
1103
1104// Processes a single message, as encoded by NativeToJsMessageQueue.java.
1105function processMessage(message) {
1106 var firstChar = message.charAt(0);
1107 if (firstChar == 'J') {
1108 // This is deprecated on the .java side. It doesn't work with CSP enabled.
1109 eval(message.slice(1));
1110 } else if (firstChar == 'S' || firstChar == 'F') {
1111 var success = firstChar == 'S';
1112 var keepCallback = message.charAt(1) == '1';
1113 var spaceIdx = message.indexOf(' ', 2);
1114 var status = +message.slice(2, spaceIdx);
1115 var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
1116 var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
1117 var payloadMessage = message.slice(nextSpaceIdx + 1);
1118 var payload = [];
1119 buildPayload(payload, payloadMessage);
1120 cordova.callbackFromNative(callbackId, success, status, payload, keepCallback);
1121 } else {
1122 console.log("processMessage failed: invalid message: " + JSON.stringify(message));
1123 }
1124}
1125
1126function processMessages() {
1127 // Check for the reentrant case.
1128 if (isProcessing) {
1129 return;
1130 }
1131 if (messagesFromNative.length === 0) {
1132 return;
1133 }
1134 isProcessing = true;
1135 try {
1136 var msg = popMessageFromQueue();
1137 // The Java side can send a * message to indicate that it
1138 // still has messages waiting to be retrieved.
1139 if (msg == '*' && messagesFromNative.length === 0) {
1140 nextTick(pollOnce);
1141 return;
1142 }
1143 processMessage(msg);
1144 } finally {
1145 isProcessing = false;
1146 if (messagesFromNative.length > 0) {
1147 nextTick(processMessages);
1148 }
1149 }
1150}
1151
1152function popMessageFromQueue() {
1153 var messageBatch = messagesFromNative.shift();
1154 if (messageBatch == '*') {
1155 return '*';
1156 }
1157
1158 var spaceIdx = messageBatch.indexOf(' ');
1159 var msgLen = +messageBatch.slice(0, spaceIdx);
1160 var message = messageBatch.substr(spaceIdx + 1, msgLen);
1161 messageBatch = messageBatch.slice(spaceIdx + msgLen + 1);
1162 if (messageBatch) {
1163 messagesFromNative.unshift(messageBatch);
1164 }
1165 return message;
1166}
1167
1168module.exports = androidExec;
1169
1170});
1171
1172// file: src/common/exec/proxy.js
1173define("cordova/exec/proxy", function(require, exports, module) {
1174
1175
1176// internal map of proxy function
1177var CommandProxyMap = {};
1178
1179module.exports = {
1180
1181 // example: cordova.commandProxy.add("Accelerometer",{getCurrentAcceleration: function(successCallback, errorCallback, options) {...},...);
1182 add:function(id,proxyObj) {
1183 console.log("adding proxy for " + id);
1184 CommandProxyMap[id] = proxyObj;
1185 return proxyObj;
1186 },
1187
1188 // cordova.commandProxy.remove("Accelerometer");
1189 remove:function(id) {
1190 var proxy = CommandProxyMap[id];
1191 delete CommandProxyMap[id];
1192 CommandProxyMap[id] = null;
1193 return proxy;
1194 },
1195
1196 get:function(service,action) {
1197 return ( CommandProxyMap[service] ? CommandProxyMap[service][action] : null );
1198 }
1199};
1200});
1201
1202// file: src/common/init.js
1203define("cordova/init", function(require, exports, module) {
1204
1205var channel = require('cordova/channel');
1206var cordova = require('cordova');
1207var modulemapper = require('cordova/modulemapper');
1208var platform = require('cordova/platform');
1209var pluginloader = require('cordova/pluginloader');
1210var utils = require('cordova/utils');
1211
1212var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
1213
1214function logUnfiredChannels(arr) {
1215 for (var i = 0; i < arr.length; ++i) {
1216 if (arr[i].state != 2) {
1217 console.log('Channel not fired: ' + arr[i].type);
1218 }
1219 }
1220}
1221
1222window.setTimeout(function() {
1223 if (channel.onDeviceReady.state != 2) {
1224 console.log('deviceready has not fired after 5 seconds.');
1225 logUnfiredChannels(platformInitChannelsArray);
1226 logUnfiredChannels(channel.deviceReadyChannelsArray);
1227 }
1228}, 5000);
1229
1230// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
1231// We replace it so that properties that can't be clobbered can instead be overridden.
1232function replaceNavigator(origNavigator) {
1233 var CordovaNavigator = function() {};
1234 CordovaNavigator.prototype = origNavigator;
1235 var newNavigator = new CordovaNavigator();
1236 // This work-around really only applies to new APIs that are newer than Function.bind.
1237 // Without it, APIs such as getGamepads() break.
1238 if (CordovaNavigator.bind) {
1239 for (var key in origNavigator) {
1240 if (typeof origNavigator[key] == 'function') {
1241 newNavigator[key] = origNavigator[key].bind(origNavigator);
1242 }
1243 else {
1244 (function(k) {
1245 utils.defineGetterSetter(newNavigator,key,function() {
1246 return origNavigator[k];
1247 });
1248 })(key);
1249 }
1250 }
1251 }
1252 return newNavigator;
1253}
1254
1255if (window.navigator) {
1256 window.navigator = replaceNavigator(window.navigator);
1257}
1258
1259if (!window.console) {
1260 window.console = {
1261 log: function(){}
1262 };
1263}
1264if (!window.console.warn) {
1265 window.console.warn = function(msg) {
1266 this.log("warn: " + msg);
1267 };
1268}
1269
1270// Register pause, resume and deviceready channels as events on document.
1271channel.onPause = cordova.addDocumentEventHandler('pause');
1272channel.onResume = cordova.addDocumentEventHandler('resume');
1273channel.onActivated = cordova.addDocumentEventHandler('activated');
1274channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
1275
1276// Listen for DOMContentLoaded and notify our channel subscribers.
1277if (document.readyState == 'complete' || document.readyState == 'interactive') {
1278 channel.onDOMContentLoaded.fire();
1279} else {
1280 document.addEventListener('DOMContentLoaded', function() {
1281 channel.onDOMContentLoaded.fire();
1282 }, false);
1283}
1284
1285// _nativeReady is global variable that the native side can set
1286// to signify that the native code is ready. It is a global since
1287// it may be called before any cordova JS is ready.
1288if (window._nativeReady) {
1289 channel.onNativeReady.fire();
1290}
1291
1292modulemapper.clobbers('cordova', 'cordova');
1293modulemapper.clobbers('cordova/exec', 'cordova.exec');
1294modulemapper.clobbers('cordova/exec', 'Cordova.exec');
1295
1296// Call the platform-specific initialization.
1297platform.bootstrap && platform.bootstrap();
1298
1299// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
1300// The delay allows the attached modules to be defined before the plugin loader looks for them.
1301setTimeout(function() {
1302 pluginloader.load(function() {
1303 channel.onPluginsReady.fire();
1304 });
1305}, 0);
1306
1307/**
1308 * Create all cordova objects once native side is ready.
1309 */
1310channel.join(function() {
1311 modulemapper.mapModules(window);
1312
1313 platform.initialize && platform.initialize();
1314
1315 // Fire event to notify that all objects are created
1316 channel.onCordovaReady.fire();
1317
1318 // Fire onDeviceReady event once page has fully loaded, all
1319 // constructors have run and cordova info has been received from native
1320 // side.
1321 channel.join(function() {
1322 require('cordova').fireDocumentEvent('deviceready');
1323 }, channel.deviceReadyChannelsArray);
1324
1325}, platformInitChannelsArray);
1326
1327
1328});
1329
1330// file: src/common/init_b.js
1331define("cordova/init_b", function(require, exports, module) {
1332
1333var channel = require('cordova/channel');
1334var cordova = require('cordova');
1335var modulemapper = require('cordova/modulemapper');
1336var platform = require('cordova/platform');
1337var pluginloader = require('cordova/pluginloader');
1338var utils = require('cordova/utils');
1339
1340var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
1341
1342// setting exec
1343cordova.exec = require('cordova/exec');
1344
1345function logUnfiredChannels(arr) {
1346 for (var i = 0; i < arr.length; ++i) {
1347 if (arr[i].state != 2) {
1348 console.log('Channel not fired: ' + arr[i].type);
1349 }
1350 }
1351}
1352
1353window.setTimeout(function() {
1354 if (channel.onDeviceReady.state != 2) {
1355 console.log('deviceready has not fired after 5 seconds.');
1356 logUnfiredChannels(platformInitChannelsArray);
1357 logUnfiredChannels(channel.deviceReadyChannelsArray);
1358 }
1359}, 5000);
1360
1361// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
1362// We replace it so that properties that can't be clobbered can instead be overridden.
1363function replaceNavigator(origNavigator) {
1364 var CordovaNavigator = function() {};
1365 CordovaNavigator.prototype = origNavigator;
1366 var newNavigator = new CordovaNavigator();
1367 // This work-around really only applies to new APIs that are newer than Function.bind.
1368 // Without it, APIs such as getGamepads() break.
1369 if (CordovaNavigator.bind) {
1370 for (var key in origNavigator) {
1371 if (typeof origNavigator[key] == 'function') {
1372 newNavigator[key] = origNavigator[key].bind(origNavigator);
1373 }
1374 else {
1375 (function(k) {
1376 utils.defineGetterSetter(newNavigator,key,function() {
1377 return origNavigator[k];
1378 });
1379 })(key);
1380 }
1381 }
1382 }
1383 return newNavigator;
1384}
1385if (window.navigator) {
1386 window.navigator = replaceNavigator(window.navigator);
1387}
1388
1389if (!window.console) {
1390 window.console = {
1391 log: function(){}
1392 };
1393}
1394if (!window.console.warn) {
1395 window.console.warn = function(msg) {
1396 this.log("warn: " + msg);
1397 };
1398}
1399
1400// Register pause, resume and deviceready channels as events on document.
1401channel.onPause = cordova.addDocumentEventHandler('pause');
1402channel.onResume = cordova.addDocumentEventHandler('resume');
1403channel.onActivated = cordova.addDocumentEventHandler('activated');
1404channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
1405
1406// Listen for DOMContentLoaded and notify our channel subscribers.
1407if (document.readyState == 'complete' || document.readyState == 'interactive') {
1408 channel.onDOMContentLoaded.fire();
1409} else {
1410 document.addEventListener('DOMContentLoaded', function() {
1411 channel.onDOMContentLoaded.fire();
1412 }, false);
1413}
1414
1415// _nativeReady is global variable that the native side can set
1416// to signify that the native code is ready. It is a global since
1417// it may be called before any cordova JS is ready.
1418if (window._nativeReady) {
1419 channel.onNativeReady.fire();
1420}
1421
1422// Call the platform-specific initialization.
1423platform.bootstrap && platform.bootstrap();
1424
1425// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
1426// The delay allows the attached modules to be defined before the plugin loader looks for them.
1427setTimeout(function() {
1428 pluginloader.load(function() {
1429 channel.onPluginsReady.fire();
1430 });
1431}, 0);
1432
1433/**
1434 * Create all cordova objects once native side is ready.
1435 */
1436channel.join(function() {
1437 modulemapper.mapModules(window);
1438
1439 platform.initialize && platform.initialize();
1440
1441 // Fire event to notify that all objects are created
1442 channel.onCordovaReady.fire();
1443
1444 // Fire onDeviceReady event once page has fully loaded, all
1445 // constructors have run and cordova info has been received from native
1446 // side.
1447 channel.join(function() {
1448 require('cordova').fireDocumentEvent('deviceready');
1449 }, channel.deviceReadyChannelsArray);
1450
1451}, platformInitChannelsArray);
1452
1453});
1454
1455// file: src/common/modulemapper.js
1456define("cordova/modulemapper", function(require, exports, module) {
1457
1458var builder = require('cordova/builder'),
1459 moduleMap = define.moduleMap,
1460 symbolList,
1461 deprecationMap;
1462
1463exports.reset = function() {
1464 symbolList = [];
1465 deprecationMap = {};
1466};
1467
1468function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
1469 if (!(moduleName in moduleMap)) {
1470 throw new Error('Module ' + moduleName + ' does not exist.');
1471 }
1472 symbolList.push(strategy, moduleName, symbolPath);
1473 if (opt_deprecationMessage) {
1474 deprecationMap[symbolPath] = opt_deprecationMessage;
1475 }
1476}
1477
1478// Note: Android 2.3 does have Function.bind().
1479exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
1480 addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
1481};
1482
1483exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
1484 addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
1485};
1486
1487exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
1488 addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
1489};
1490
1491exports.runs = function(moduleName) {
1492 addEntry('r', moduleName, null);
1493};
1494
1495function prepareNamespace(symbolPath, context) {
1496 if (!symbolPath) {
1497 return context;
1498 }
1499 var parts = symbolPath.split('.');
1500 var cur = context;
1501 for (var i = 0, part; part = parts[i]; ++i) {
1502 cur = cur[part] = cur[part] || {};
1503 }
1504 return cur;
1505}
1506
1507exports.mapModules = function(context) {
1508 var origSymbols = {};
1509 context.CDV_origSymbols = origSymbols;
1510 for (var i = 0, len = symbolList.length; i < len; i += 3) {
1511 var strategy = symbolList[i];
1512 var moduleName = symbolList[i + 1];
1513 var module = require(moduleName);
1514 // <runs/>
1515 if (strategy == 'r') {
1516 continue;
1517 }
1518 var symbolPath = symbolList[i + 2];
1519 var lastDot = symbolPath.lastIndexOf('.');
1520 var namespace = symbolPath.substr(0, lastDot);
1521 var lastName = symbolPath.substr(lastDot + 1);
1522
1523 var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
1524 var parentObj = prepareNamespace(namespace, context);
1525 var target = parentObj[lastName];
1526
1527 if (strategy == 'm' && target) {
1528 builder.recursiveMerge(target, module);
1529 } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
1530 if (!(symbolPath in origSymbols)) {
1531 origSymbols[symbolPath] = target;
1532 }
1533 builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
1534 }
1535 }
1536};
1537
1538exports.getOriginalSymbol = function(context, symbolPath) {
1539 var origSymbols = context.CDV_origSymbols;
1540 if (origSymbols && (symbolPath in origSymbols)) {
1541 return origSymbols[symbolPath];
1542 }
1543 var parts = symbolPath.split('.');
1544 var obj = context;
1545 for (var i = 0; i < parts.length; ++i) {
1546 obj = obj && obj[parts[i]];
1547 }
1548 return obj;
1549};
1550
1551exports.reset();
1552
1553
1554});
1555
1556// file: src/common/modulemapper_b.js
1557define("cordova/modulemapper_b", function(require, exports, module) {
1558
1559var builder = require('cordova/builder'),
1560 symbolList = [],
1561 deprecationMap;
1562
1563exports.reset = function() {
1564 symbolList = [];
1565 deprecationMap = {};
1566};
1567
1568function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
1569 symbolList.push(strategy, moduleName, symbolPath);
1570 if (opt_deprecationMessage) {
1571 deprecationMap[symbolPath] = opt_deprecationMessage;
1572 }
1573}
1574
1575// Note: Android 2.3 does have Function.bind().
1576exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
1577 addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
1578};
1579
1580exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
1581 addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
1582};
1583
1584exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
1585 addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
1586};
1587
1588exports.runs = function(moduleName) {
1589 addEntry('r', moduleName, null);
1590};
1591
1592function prepareNamespace(symbolPath, context) {
1593 if (!symbolPath) {
1594 return context;
1595 }
1596 var parts = symbolPath.split('.');
1597 var cur = context;
1598 for (var i = 0, part; part = parts[i]; ++i) {
1599 cur = cur[part] = cur[part] || {};
1600 }
1601 return cur;
1602}
1603
1604exports.mapModules = function(context) {
1605 var origSymbols = {};
1606 context.CDV_origSymbols = origSymbols;
1607 for (var i = 0, len = symbolList.length; i < len; i += 3) {
1608 var strategy = symbolList[i];
1609 var moduleName = symbolList[i + 1];
1610 var module = require(moduleName);
1611 // <runs/>
1612 if (strategy == 'r') {
1613 continue;
1614 }
1615 var symbolPath = symbolList[i + 2];
1616 var lastDot = symbolPath.lastIndexOf('.');
1617 var namespace = symbolPath.substr(0, lastDot);
1618 var lastName = symbolPath.substr(lastDot + 1);
1619
1620 var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
1621 var parentObj = prepareNamespace(namespace, context);
1622 var target = parentObj[lastName];
1623
1624 if (strategy == 'm' && target) {
1625 builder.recursiveMerge(target, module);
1626 } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
1627 if (!(symbolPath in origSymbols)) {
1628 origSymbols[symbolPath] = target;
1629 }
1630 builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
1631 }
1632 }
1633};
1634
1635exports.getOriginalSymbol = function(context, symbolPath) {
1636 var origSymbols = context.CDV_origSymbols;
1637 if (origSymbols && (symbolPath in origSymbols)) {
1638 return origSymbols[symbolPath];
1639 }
1640 var parts = symbolPath.split('.');
1641 var obj = context;
1642 for (var i = 0; i < parts.length; ++i) {
1643 obj = obj && obj[parts[i]];
1644 }
1645 return obj;
1646};
1647
1648exports.reset();
1649
1650
1651});
1652
1653// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/platform.js
1654define("cordova/platform", function(require, exports, module) {
1655
1656// The last resume event that was received that had the result of a plugin call.
1657var lastResumeEvent = null;
1658
1659module.exports = {
1660 id: 'android',
1661 bootstrap: function() {
1662 var channel = require('cordova/channel'),
1663 cordova = require('cordova'),
1664 exec = require('cordova/exec'),
1665 modulemapper = require('cordova/modulemapper');
1666
1667 // Get the shared secret needed to use the bridge.
1668 exec.init();
1669
1670 // TODO: Extract this as a proper plugin.
1671 modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
1672
1673 var APP_PLUGIN_NAME = Number(cordova.platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
1674
1675 // Inject a listener for the backbutton on the document.
1676 var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
1677 backButtonChannel.onHasSubscribersChange = function() {
1678 // If we just attached the first handler or detached the last handler,
1679 // let native know we need to override the back button.
1680 exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [this.numHandlers == 1]);
1681 };
1682
1683 // Add hardware MENU and SEARCH button handlers
1684 cordova.addDocumentEventHandler('menubutton');
1685 cordova.addDocumentEventHandler('searchbutton');
1686
1687 function bindButtonChannel(buttonName) {
1688 // generic button bind used for volumeup/volumedown buttons
1689 var volumeButtonChannel = cordova.addDocumentEventHandler(buttonName + 'button');
1690 volumeButtonChannel.onHasSubscribersChange = function() {
1691 exec(null, null, APP_PLUGIN_NAME, "overrideButton", [buttonName, this.numHandlers == 1]);
1692 };
1693 }
1694 // Inject a listener for the volume buttons on the document.
1695 bindButtonChannel('volumeup');
1696 bindButtonChannel('volumedown');
1697
1698 // The resume event is not "sticky", but it is possible that the event
1699 // will contain the result of a plugin call. We need to ensure that the
1700 // plugin result is delivered even after the event is fired (CB-10498)
1701 var cordovaAddEventListener = document.addEventListener;
1702
1703 document.addEventListener = function(evt, handler, capture) {
1704 cordovaAddEventListener(evt, handler, capture);
1705
1706 if (evt === 'resume' && lastResumeEvent) {
1707 handler(lastResumeEvent);
1708 }
1709 };
1710
1711 // Let native code know we are all done on the JS side.
1712 // Native code will then un-hide the WebView.
1713 channel.onCordovaReady.subscribe(function() {
1714 exec(onMessageFromNative, null, APP_PLUGIN_NAME, 'messageChannel', []);
1715 exec(null, null, APP_PLUGIN_NAME, "show", []);
1716 });
1717 }
1718};
1719
1720function onMessageFromNative(msg) {
1721 var cordova = require('cordova');
1722 var action = msg.action;
1723
1724 switch (action)
1725 {
1726 // Button events
1727 case 'backbutton':
1728 case 'menubutton':
1729 case 'searchbutton':
1730 // App life cycle events
1731 case 'pause':
1732 // Volume events
1733 case 'volumedownbutton':
1734 case 'volumeupbutton':
1735 cordova.fireDocumentEvent(action);
1736 break;
1737 case 'resume':
1738 if(arguments.length > 1 && msg.pendingResult) {
1739 if(arguments.length === 2) {
1740 msg.pendingResult.result = arguments[1];
1741 } else {
1742 // The plugin returned a multipart message
1743 var res = [];
1744 for(var i = 1; i < arguments.length; i++) {
1745 res.push(arguments[i]);
1746 }
1747 msg.pendingResult.result = res;
1748 }
1749
1750 // Save the plugin result so that it can be delivered to the js
1751 // even if they miss the initial firing of the event
1752 lastResumeEvent = msg;
1753 }
1754 cordova.fireDocumentEvent(action, msg);
1755 break;
1756 default:
1757 throw new Error('Unknown event action ' + action);
1758 }
1759}
1760
1761});
1762
1763// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/plugin/android/app.js
1764define("cordova/plugin/android/app", function(require, exports, module) {
1765
1766var exec = require('cordova/exec');
1767var APP_PLUGIN_NAME = Number(require('cordova').platformVersion.split('.')[0]) >= 4 ? 'CoreAndroid' : 'App';
1768
1769module.exports = {
1770 /**
1771 * Clear the resource cache.
1772 */
1773 clearCache:function() {
1774 exec(null, null, APP_PLUGIN_NAME, "clearCache", []);
1775 },
1776
1777 /**
1778 * Load the url into the webview or into new browser instance.
1779 *
1780 * @param url The URL to load
1781 * @param props Properties that can be passed in to the activity:
1782 * wait: int => wait msec before loading URL
1783 * loadingDialog: "Title,Message" => display a native loading dialog
1784 * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error
1785 * clearHistory: boolean => clear webview history (default=false)
1786 * openExternal: boolean => open in a new browser (default=false)
1787 *
1788 * Example:
1789 * navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
1790 */
1791 loadUrl:function(url, props) {
1792 exec(null, null, APP_PLUGIN_NAME, "loadUrl", [url, props]);
1793 },
1794
1795 /**
1796 * Cancel loadUrl that is waiting to be loaded.
1797 */
1798 cancelLoadUrl:function() {
1799 exec(null, null, APP_PLUGIN_NAME, "cancelLoadUrl", []);
1800 },
1801
1802 /**
1803 * Clear web history in this web view.
1804 * Instead of BACK button loading the previous web page, it will exit the app.
1805 */
1806 clearHistory:function() {
1807 exec(null, null, APP_PLUGIN_NAME, "clearHistory", []);
1808 },
1809
1810 /**
1811 * Go to previous page displayed.
1812 * This is the same as pressing the backbutton on Android device.
1813 */
1814 backHistory:function() {
1815 exec(null, null, APP_PLUGIN_NAME, "backHistory", []);
1816 },
1817
1818 /**
1819 * Override the default behavior of the Android back button.
1820 * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
1821 *
1822 * Note: The user should not have to call this method. Instead, when the user
1823 * registers for the "backbutton" event, this is automatically done.
1824 *
1825 * @param override T=override, F=cancel override
1826 */
1827 overrideBackbutton:function(override) {
1828 exec(null, null, APP_PLUGIN_NAME, "overrideBackbutton", [override]);
1829 },
1830
1831 /**
1832 * Override the default behavior of the Android volume button.
1833 * If overridden, when the volume button is pressed, the "volume[up|down]button"
1834 * JavaScript event will be fired.
1835 *
1836 * Note: The user should not have to call this method. Instead, when the user
1837 * registers for the "volume[up|down]button" event, this is automatically done.
1838 *
1839 * @param button volumeup, volumedown
1840 * @param override T=override, F=cancel override
1841 */
1842 overrideButton:function(button, override) {
1843 exec(null, null, APP_PLUGIN_NAME, "overrideButton", [button, override]);
1844 },
1845
1846 /**
1847 * Exit and terminate the application.
1848 */
1849 exitApp:function() {
1850 return exec(null, null, APP_PLUGIN_NAME, "exitApp", []);
1851 }
1852};
1853
1854});
1855
1856// file: src/common/pluginloader.js
1857define("cordova/pluginloader", function(require, exports, module) {
1858
1859var modulemapper = require('cordova/modulemapper');
1860var urlutil = require('cordova/urlutil');
1861
1862// Helper function to inject a <script> tag.
1863// Exported for testing.
1864exports.injectScript = function(url, onload, onerror) {
1865 var script = document.createElement("script");
1866 // onload fires even when script fails loads with an error.
1867 script.onload = onload;
1868 // onerror fires for malformed URLs.
1869 script.onerror = onerror;
1870 script.src = url;
1871 document.head.appendChild(script);
1872};
1873
1874function injectIfNecessary(id, url, onload, onerror) {
1875 onerror = onerror || onload;
1876 if (id in define.moduleMap) {
1877 onload();
1878 } else {
1879 exports.injectScript(url, function() {
1880 if (id in define.moduleMap) {
1881 onload();
1882 } else {
1883 onerror();
1884 }
1885 }, onerror);
1886 }
1887}
1888
1889function onScriptLoadingComplete(moduleList, finishPluginLoading) {
1890 // Loop through all the plugins and then through their clobbers and merges.
1891 for (var i = 0, module; module = moduleList[i]; i++) {
1892 if (module.clobbers && module.clobbers.length) {
1893 for (var j = 0; j < module.clobbers.length; j++) {
1894 modulemapper.clobbers(module.id, module.clobbers[j]);
1895 }
1896 }
1897
1898 if (module.merges && module.merges.length) {
1899 for (var k = 0; k < module.merges.length; k++) {
1900 modulemapper.merges(module.id, module.merges[k]);
1901 }
1902 }
1903
1904 // Finally, if runs is truthy we want to simply require() the module.
1905 if (module.runs) {
1906 modulemapper.runs(module.id);
1907 }
1908 }
1909
1910 finishPluginLoading();
1911}
1912
1913// Handler for the cordova_plugins.js content.
1914// See plugman's plugin_loader.js for the details of this object.
1915// This function is only called if the really is a plugins array that isn't empty.
1916// Otherwise the onerror response handler will just call finishPluginLoading().
1917function handlePluginsObject(path, moduleList, finishPluginLoading) {
1918 // Now inject the scripts.
1919 var scriptCounter = moduleList.length;
1920
1921 if (!scriptCounter) {
1922 finishPluginLoading();
1923 return;
1924 }
1925 function scriptLoadedCallback() {
1926 if (!--scriptCounter) {
1927 onScriptLoadingComplete(moduleList, finishPluginLoading);
1928 }
1929 }
1930
1931 for (var i = 0; i < moduleList.length; i++) {
1932 injectIfNecessary(moduleList[i].id, path + moduleList[i].file, scriptLoadedCallback);
1933 }
1934}
1935
1936function findCordovaPath() {
1937 var path = null;
1938 var scripts = document.getElementsByTagName('script');
1939 var term = '/cordova.js';
1940 for (var n = scripts.length-1; n>-1; n--) {
1941 var src = scripts[n].src.replace(/\?.*$/, ''); // Strip any query param (CB-6007).
1942 if (src.indexOf(term) == (src.length - term.length)) {
1943 path = src.substring(0, src.length - term.length) + '/';
1944 break;
1945 }
1946 }
1947 return path;
1948}
1949
1950// Tries to load all plugins' js-modules.
1951// This is an async process, but onDeviceReady is blocked on onPluginsReady.
1952// onPluginsReady is fired when there are no plugins to load, or they are all done.
1953exports.load = function(callback) {
1954 var pathPrefix = findCordovaPath();
1955 if (pathPrefix === null) {
1956 console.log('Could not find cordova.js script tag. Plugin loading may fail.');
1957 pathPrefix = '';
1958 }
1959 injectIfNecessary('cordova/plugin_list', pathPrefix + 'cordova_plugins.js', function() {
1960 var moduleList = require("cordova/plugin_list");
1961 handlePluginsObject(pathPrefix, moduleList, callback);
1962 }, callback);
1963};
1964
1965
1966});
1967
1968// file: src/common/pluginloader_b.js
1969define("cordova/pluginloader_b", function(require, exports, module) {
1970
1971var modulemapper = require('cordova/modulemapper');
1972
1973// Handler for the cordova_plugins.js content.
1974// See plugman's plugin_loader.js for the details of this object.
1975function handlePluginsObject(moduleList) {
1976 // if moduleList is not defined or empty, we've nothing to do
1977 if (!moduleList || !moduleList.length) {
1978 return;
1979 }
1980
1981 // Loop through all the modules and then through their clobbers and merges.
1982 for (var i = 0, module; module = moduleList[i]; i++) {
1983 if (module.clobbers && module.clobbers.length) {
1984 for (var j = 0; j < module.clobbers.length; j++) {
1985 modulemapper.clobbers(module.id, module.clobbers[j]);
1986 }
1987 }
1988
1989 if (module.merges && module.merges.length) {
1990 for (var k = 0; k < module.merges.length; k++) {
1991 modulemapper.merges(module.id, module.merges[k]);
1992 }
1993 }
1994
1995 // Finally, if runs is truthy we want to simply require() the module.
1996 if (module.runs) {
1997 modulemapper.runs(module.id);
1998 }
1999 }
2000}
2001
2002// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
2003// but the method accepts callback to be compatible with non-browserify flow.
2004// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
2005// no plugins to load, or they are all done.
2006exports.load = function(callback) {
2007 var moduleList = require("cordova/plugin_list");
2008 handlePluginsObject(moduleList);
2009
2010 callback();
2011};
2012
2013
2014});
2015
2016// file: src/common/urlutil.js
2017define("cordova/urlutil", function(require, exports, module) {
2018
2019
2020/**
2021 * For already absolute URLs, returns what is passed in.
2022 * For relative URLs, converts them to absolute ones.
2023 */
2024exports.makeAbsolute = function makeAbsolute(url) {
2025 var anchorEl = document.createElement('a');
2026 anchorEl.href = url;
2027 return anchorEl.href;
2028};
2029
2030
2031});
2032
2033// file: src/common/utils.js
2034define("cordova/utils", function(require, exports, module) {
2035
2036var utils = exports;
2037
2038/**
2039 * Defines a property getter / setter for obj[key].
2040 */
2041utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
2042 if (Object.defineProperty) {
2043 var desc = {
2044 get: getFunc,
2045 configurable: true
2046 };
2047 if (opt_setFunc) {
2048 desc.set = opt_setFunc;
2049 }
2050 Object.defineProperty(obj, key, desc);
2051 } else {
2052 obj.__defineGetter__(key, getFunc);
2053 if (opt_setFunc) {
2054 obj.__defineSetter__(key, opt_setFunc);
2055 }
2056 }
2057};
2058
2059/**
2060 * Defines a property getter for obj[key].
2061 */
2062utils.defineGetter = utils.defineGetterSetter;
2063
2064utils.arrayIndexOf = function(a, item) {
2065 if (a.indexOf) {
2066 return a.indexOf(item);
2067 }
2068 var len = a.length;
2069 for (var i = 0; i < len; ++i) {
2070 if (a[i] == item) {
2071 return i;
2072 }
2073 }
2074 return -1;
2075};
2076
2077/**
2078 * Returns whether the item was found in the array.
2079 */
2080utils.arrayRemove = function(a, item) {
2081 var index = utils.arrayIndexOf(a, item);
2082 if (index != -1) {
2083 a.splice(index, 1);
2084 }
2085 return index != -1;
2086};
2087
2088utils.typeName = function(val) {
2089 return Object.prototype.toString.call(val).slice(8, -1);
2090};
2091
2092/**
2093 * Returns an indication of whether the argument is an array or not
2094 */
2095utils.isArray = Array.isArray ||
2096 function(a) {return utils.typeName(a) == 'Array';};
2097
2098/**
2099 * Returns an indication of whether the argument is a Date or not
2100 */
2101utils.isDate = function(d) {
2102 return (d instanceof Date);
2103};
2104
2105/**
2106 * Does a deep clone of the object.
2107 */
2108utils.clone = function(obj) {
2109 if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
2110 return obj;
2111 }
2112
2113 var retVal, i;
2114
2115 if(utils.isArray(obj)){
2116 retVal = [];
2117 for(i = 0; i < obj.length; ++i){
2118 retVal.push(utils.clone(obj[i]));
2119 }
2120 return retVal;
2121 }
2122
2123 retVal = {};
2124 for(i in obj){
2125 // https://issues.apache.org/jira/browse/CB-11522 'unknown' type may be returned in
2126 // custom protocol activation case on Windows Phone 8.1 causing "No such interface supported" exception
2127 // on cloning.
2128 if((!(i in retVal) || retVal[i] != obj[i]) && typeof obj[i] != 'undefined' && typeof obj[i] != 'unknown') {
2129 retVal[i] = utils.clone(obj[i]);
2130 }
2131 }
2132 return retVal;
2133};
2134
2135/**
2136 * Returns a wrapped version of the function
2137 */
2138utils.close = function(context, func, params) {
2139 return function() {
2140 var args = params || arguments;
2141 return func.apply(context, args);
2142 };
2143};
2144
2145//------------------------------------------------------------------------------
2146function UUIDcreatePart(length) {
2147 var uuidpart = "";
2148 for (var i=0; i<length; i++) {
2149 var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
2150 if (uuidchar.length == 1) {
2151 uuidchar = "0" + uuidchar;
2152 }
2153 uuidpart += uuidchar;
2154 }
2155 return uuidpart;
2156}
2157
2158/**
2159 * Create a UUID
2160 */
2161utils.createUUID = function() {
2162 return UUIDcreatePart(4) + '-' +
2163 UUIDcreatePart(2) + '-' +
2164 UUIDcreatePart(2) + '-' +
2165 UUIDcreatePart(2) + '-' +
2166 UUIDcreatePart(6);
2167};
2168
2169
2170/**
2171 * Extends a child object from a parent object using classical inheritance
2172 * pattern.
2173 */
2174utils.extend = (function() {
2175 // proxy used to establish prototype chain
2176 var F = function() {};
2177 // extend Child from Parent
2178 return function(Child, Parent) {
2179
2180 F.prototype = Parent.prototype;
2181 Child.prototype = new F();
2182 Child.__super__ = Parent.prototype;
2183 Child.prototype.constructor = Child;
2184 };
2185}());
2186
2187/**
2188 * Alerts a message in any available way: alert or console.log.
2189 */
2190utils.alert = function(msg) {
2191 if (window.alert) {
2192 window.alert(msg);
2193 } else if (console && console.log) {
2194 console.log(msg);
2195 }
2196};
2197
2198
2199
2200
2201
2202});
2203
2204window.cordova = require('cordova');
2205// file: src/scripts/bootstrap.js
2206
2207require('cordova/init');
2208
2209})();