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