diff --git a/Makefile b/Makefile
new file mode 100755
index 0000000..5869ac7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,39 @@
+GREP = /usr/bin/grep
+CUT = /usr/bin/cut
+SHELL = /bin/sh
+CHMOD = chmod
+CP = cp
+MV = mv
+NOOP = $(SHELL) -c true
+RM_F = rm -f
+RM_RF = rm -rf
+TEST_F = test -f
+TOUCH = touch
+UMASK_NULL = umask 0
+DEV_NULL = > /dev/null 2>&1
+MKPATH = mkdir -p
+CAT = cat
+MAKE = make
+OPEN = open
+ECHO = echo
+ECHO_N = echo -n
+JAVA = java
+PGVERSION = 2.0.0
+
+all :: js copy_js
+
+clean :: clean_libs
+
+clean_libs:
+	$(RM_RF) lib
+
+copy_js: js
+	$(CP) lib/cordova.js framework/cordova-$(PGVERSION).js
+
+js: lib/cordova.js
+
+lib/cordova.js: js/cordova.tizen.js js/native.js
+	$(MKPATH) lib
+	$(RM_F) $@
+	$(CAT) js/native.js >> $@
+	$(CAT) js/cordova.tizen.js >> $@
diff --git a/framework/config.xml b/framework/config.xml
new file mode 100644
index 0000000..72fd375
--- /dev/null
+++ b/framework/config.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets" version="1.0" viewmodes="fullscreen" id="http://YourDomain.com/cordova">  
+	<icon src="icon.png"/>  
+	<content src="index.html"/>  
+	<feature name="http://tizen.org/api/alarm" required="true"/>  
+	<feature name="http://tizen.org/api/alarm.read" required="true"/>  
+	<feature name="http://tizen.org/api/alarm.write" required="true"/>  
+	<feature name="http://tizen.org/api/application" required="true"/>  
+	<feature name="http://tizen.org/api/application.kill" required="true"/>  
+	<feature name="http://tizen.org/api/application.launch" required="true"/>  
+	<feature name="http://tizen.org/api/application.read" required="true"/>  
+	<feature name="http://tizen.org/api/bluetooth" required="true"/>  
+	<feature name="http://tizen.org/api/bluetooth.gap" required="true"/>  
+	<feature name="http://tizen.org/api/bluetooth.spp" required="true"/>  
+	<feature name="http://tizen.org/api/calendar" required="true"/>  
+	<feature name="http://tizen.org/api/calendar.read" required="true"/>  
+	<feature name="http://tizen.org/api/calendar.write" required="true"/>  
+	<feature name="http://tizen.org/api/call" required="true"/>  
+	<feature name="http://tizen.org/api/call.history" required="true"/>  
+	<feature name="http://tizen.org/api/call.history.read" required="true"/>  
+	<feature name="http://tizen.org/api/call.history.write" required="true"/>  
+	<feature name="http://tizen.org/api/call.simple" required="true"/>  
+	<feature name="http://tizen.org/api/contact" required="true"/>  
+	<feature name="http://tizen.org/api/contact.read" required="true"/>  
+	<feature name="http://tizen.org/api/contact.write" required="true"/>  
+	<feature name="http://tizen.org/api/filesystem" required="true"/>  
+	<feature name="http://tizen.org/api/filesystem.read" required="true"/>  
+	<feature name="http://tizen.org/api/filesystem.write" required="true"/>  
+	<feature name="http://tizen.org/api/geocoder" required="true"/>  
+	<feature name="http://tizen.org/api/mediacontent" required="true"/>  
+	<feature name="http://tizen.org/api/mediacontent.read" required="true"/>  
+	<feature name="http://tizen.org/api/messaging" required="true"/>  
+	<feature name="http://tizen.org/api/messaging.read" required="true"/>  
+	<feature name="http://tizen.org/api/messaging.send" required="true"/>  
+	<feature name="http://tizen.org/api/messaging.write" required="true"/>  
+	<feature name="http://tizen.org/api/nfc" required="true"/>  
+	<feature name="http://tizen.org/api/nfc.p2p" required="true"/>  
+	<feature name="http://tizen.org/api/nfc.se" required="true"/>  
+	<feature name="http://tizen.org/api/nfc.tag" required="true"/>  
+	<feature name="http://tizen.org/api/systeminfo" required="true"/>  
+	<feature name="http://tizen.org/api/time" required="true"/>  
+	<feature name="http://tizen.org/api/time.read" required="true"/>  
+	<feature name="http://tizen.org/api/time.write" required="true"/>  
+	<feature name="http://tizen.org/api/tizen" required="true"/>  
+	<feature name="http://tizen.org/api/sensors" required="true"/>  
+	<name>Cordova</name>  
+	<author/>
+	<license/>
+	<description>Cordova for Tizen sample application</description>
+</widget>
diff --git a/framework/cordova-2.0.0.js b/framework/cordova-2.0.0.js
new file mode 100644
index 0000000..04a0a99
--- /dev/null
+++ b/framework/cordova-2.0.0.js
@@ -0,0 +1,7075 @@
+/*
+ * No real native code
+ */
+
+/* Needed for File API implementation */
+window.webkitFileReader = window.FileReader;
+
+window._nativeReady = true;
+
+// commit 7dd17b00544742d14ecdeff2148a66480680f12b
+
+// File generated at :: Thu Jul 26 2012 17:32:56 GMT+0200 (CEST)
+
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+;(function() {
+
+// file: lib/scripts/require.js
+var require,
+    define;
+
+(function () {
+    var modules = {};
+
+    function build(module) {
+        var factory = module.factory;
+        module.exports = {};
+        delete module.factory;
+        factory(require, module.exports, module);
+        return module.exports;
+    }
+
+    require = function (id) {
+        if (!modules[id]) {
+            throw "module " + id + " not found";
+        }
+        return modules[id].factory ? build(modules[id]) : modules[id].exports;
+    };
+
+    define = function (id, factory) {
+        if (modules[id]) {
+            throw "module " + id + " already defined";
+        }
+
+        modules[id] = {
+            id: id,
+            factory: factory
+        };
+    };
+
+    define.remove = function (id) {
+        delete modules[id];
+    };
+
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+    module.exports.require = require;
+    module.exports.define = define;
+}
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+var channel = require('cordova/channel');
+
+/**
+ * Listen for DOMContentLoaded and notify our channel subscribers.
+ */
+document.addEventListener('DOMContentLoaded', function() {
+    channel.onDOMContentLoaded.fire();
+}, false);
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+    channel.onDOMContentLoaded.fire();
+}
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+    windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof documentEventHandlers[e] != 'undefined') {
+        if (evt === 'deviceready') {
+            documentEventHandlers[e].subscribeOnce(handler);
+        } else {
+            documentEventHandlers[e].subscribe(handler);
+        }
+    } else {
+        m_document_addEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof windowEventHandlers[e] != 'undefined') {
+        windowEventHandlers[e].subscribe(handler);
+    } else {
+        m_window_addEventListener.call(window, evt, handler, capture);
+    }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof documentEventHandlers[e] != "undefined") {
+        documentEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_document_removeEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof windowEventHandlers[e] != "undefined") {
+        windowEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_window_removeEventListener.call(window, evt, handler, capture);
+    }
+};
+
+function createEvent(type, data) {
+    var event = document.createEvent('Events');
+    event.initEvent(type, false, false);
+    if (data) {
+        for (var i in data) {
+            if (data.hasOwnProperty(i)) {
+                event[i] = data[i];
+            }
+        }
+    }
+    return event;
+}
+
+if(typeof window.console === "undefined") {
+    window.console = {
+        log:function(){}
+    };
+}
+
+var cordova = {
+    define:define,
+    require:require,
+    /**
+     * Methods to add/remove your own addEventListener hijacking on document + window.
+     */
+    addWindowEventHandler:function(event, opts) {
+        return (windowEventHandlers[event] = channel.create(event, opts));
+    },
+    addDocumentEventHandler:function(event, opts) {
+        return (documentEventHandlers[event] = channel.create(event, opts));
+    },
+    removeWindowEventHandler:function(event) {
+        delete windowEventHandlers[event];
+    },
+    removeDocumentEventHandler:function(event) {
+        delete documentEventHandlers[event];
+    },
+    /**
+     * Retreive original event handlers that were replaced by Cordova
+     *
+     * @return object
+     */
+    getOriginalHandlers: function() {
+        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+    },
+    /**
+     * Method to fire event from native code
+     */
+    fireDocumentEvent: function(type, data) {
+        var evt = createEvent(type, data);
+        if (typeof documentEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                documentEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            document.dispatchEvent(evt);
+        }
+    },
+    fireWindowEvent: function(type, data) {
+        var evt = createEvent(type,data);
+        if (typeof windowEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                windowEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            window.dispatchEvent(evt);
+        }
+    },
+    // TODO: this is Android only; think about how to do this better
+    shuttingDown:false,
+    UsePolling:false,
+    // END TODO
+
+    // TODO: iOS only
+    // This queue holds the currently executing command and all pending
+    // commands executed with cordova.exec().
+    commandQueue:[],
+    // Indicates if we're currently in the middle of flushing the command
+    // queue on the native side.
+    commandQueueFlushing:false,
+    // END TODO
+    /**
+     * Plugin callback mechanism.
+     */
+    callbackId: 0,
+    callbacks:  {},
+    callbackStatus: {
+        NO_RESULT: 0,
+        OK: 1,
+        CLASS_NOT_FOUND_EXCEPTION: 2,
+        ILLEGAL_ACCESS_EXCEPTION: 3,
+        INSTANTIATION_EXCEPTION: 4,
+        MALFORMED_URL_EXCEPTION: 5,
+        IO_EXCEPTION: 6,
+        INVALID_ACTION: 7,
+        JSON_EXCEPTION: 8,
+        ERROR: 9
+    },
+
+    /**
+     * Called by native code when returning successful result from an action.
+     *
+     * @param callbackId
+     * @param args
+     */
+    callbackSuccess: function(callbackId, args) {
+        if (cordova.callbacks[callbackId]) {
+
+            // If result is to be sent to callback
+            if (args.status == cordova.callbackStatus.OK) {
+                try {
+                    if (cordova.callbacks[callbackId].success) {
+                        cordova.callbacks[callbackId].success(args.message);
+                    }
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+callbackId+" = "+e);
+                }
+            }
+
+            // Clear callback if not expecting any more results
+            if (!args.keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+
+    /**
+     * Called by native code when returning error result from an action.
+     *
+     * @param callbackId
+     * @param args
+     */
+    callbackError: function(callbackId, args) {
+        if (cordova.callbacks[callbackId]) {
+            try {
+                if (cordova.callbacks[callbackId].fail) {
+                    cordova.callbacks[callbackId].fail(args.message);
+                }
+            }
+            catch (e) {
+                console.log("Error in error callback: "+callbackId+" = "+e);
+            }
+
+            // Clear callback if not expecting any more results
+            if (!args.keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+    addConstructor: function(func) {
+        channel.onCordovaReady.subscribeOnce(function() {
+            try {
+                func();
+            } catch(e) {
+                console.log("Failed to run constructor: " + e);
+            }
+        });
+    }
+};
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addDocumentEventHandler('deviceready');
+
+module.exports = cordova;
+
+});
+
+// file: lib/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+    for (var prop in objects) {
+        if (objects.hasOwnProperty(prop)) {
+            func.apply(context, [objects[prop], prop]);
+        }
+    }
+}
+
+function include(parent, objects, clobber, merge) {
+    each(objects, function (obj, key) {
+        try {
+          var result = obj.path ? require(obj.path) : {};
+
+          if (clobber) {
+              // Clobber if it doesn't exist.
+              if (typeof parent[key] === 'undefined') {
+                  parent[key] = result;
+              } else if (typeof obj.path !== 'undefined') {
+                  // If merging, merge properties onto parent, otherwise, clobber.
+                  if (merge) {
+                      recursiveMerge(parent[key], result);
+                  } else {
+                      parent[key] = result;
+                  }
+              }
+              result = parent[key];
+          } else {
+            // Overwrite if not currently defined.
+            if (typeof parent[key] == 'undefined') {
+              parent[key] = result;
+            } else if (merge && typeof obj.path !== 'undefined') {
+              // If merging, merge parent onto result
+              recursiveMerge(result, parent[key]);
+              parent[key] = result;
+            } else {
+              // Set result to what already exists, so we can build children into it if they exist.
+              result = parent[key];
+            }
+          }
+
+          if (obj.children) {
+            include(result, obj.children, clobber, merge);
+          }
+        } catch(e) {
+          utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+        }
+    });
+}
+
+/**
+ * Merge properties from one object onto another recursively.  Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+    for (var prop in src) {
+        if (src.hasOwnProperty(prop)) {
+            if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) {
+                // If the target object is a constructor override off prototype.
+                target.prototype[prop] = src[prop];
+            } else {
+                target[prop] = typeof src[prop] === 'object' ? recursiveMerge(
+                        target[prop], src[prop]) : src[prop];
+            }
+        }
+    }
+    return target;
+}
+
+module.exports = {
+    build: function (objects) {
+        return {
+            intoButDontClobber: function (target) {
+                include(target, objects, false, false);
+            },
+            intoAndClobber: function(target) {
+                include(target, objects, true, false);
+            },
+            intoAndMerge: function(target) {
+                include(target, objects, true, true);
+            }
+        };
+    }
+};
+
+});
+
+// file: lib/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+var utils = require('cordova/utils');
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded         Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady              Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady             Internal event fired when all Cordova JavaScript objects have been created.
+ * onCordovaInfoReady         Internal event fired when device properties are available.
+ * onCordovaConnectionReady   Internal event fired when the connection property has been set.
+ * onDeviceReady              User event fired to indicate that Cordova is ready
+ * onResume                   User event fired to indicate a start/resume lifecycle event
+ * onPause                    User event fired to indicate a pause lifecycle event
+ * onDestroy                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The only Cordova events that user code should register for are:
+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ *      pause                 App has moved to background
+ *      resume                App has returned to foreground
+ *
+ * Listeners can be registered as:
+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);
+ *      document.addEventListener("resume", myResumeListener, false);
+ *      document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ *      window.onload
+ *      window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type  String the channel name
+ * @param opts  Object options to pass into the channel, currently
+ *                     supports:
+ *                     onSubscribe: callback that fires when
+ *                       something subscribes to the Channel. Sets
+ *                       context to the Channel.
+ *                     onUnsubscribe: callback that fires when
+ *                       something unsubscribes to the Channel. Sets
+ *                       context to the Channel.
+ */
+var Channel = function(type, opts) {
+    this.type = type;
+    this.handlers = {};
+    this.numHandlers = 0;
+    this.guid = 1;
+    this.fired = false;
+    this.enabled = true;
+    this.events = {
+        onSubscribe:null,
+        onUnsubscribe:null
+    };
+    if (opts) {
+        if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe;
+        if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe;
+    }
+},
+    channel = {
+        /**
+         * Calls the provided function only after all of the channels specified
+         * have been fired.
+         */
+        join: function (h, c) {
+            var i = c.length;
+            var len = i;
+            var f = function() {
+                if (!(--i)) h();
+            };
+            for (var j=0; j<len; j++) {
+                !c[j].fired?c[j].subscribeOnce(f):i--;
+            }
+            if (!i) h();
+        },
+        create: function (type, opts) {
+            channel[type] = new Channel(type, opts);
+            return channel[type];
+        },
+
+        /**
+         * cordova Channels that must fire before "deviceready" is fired.
+         */
+        deviceReadyChannelsArray: [],
+        deviceReadyChannelsMap: {},
+
+        /**
+         * Indicate that a feature needs to be initialized before it is ready to be used.
+         * This holds up Cordova's "deviceready" event until the feature has been initialized
+         * and Cordova.initComplete(feature) is called.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        waitForInitialization: function(feature) {
+            if (feature) {
+                var c = null;
+                if (this[feature]) {
+                    c = this[feature];
+                }
+                else {
+                    c = this.create(feature);
+                }
+                this.deviceReadyChannelsMap[feature] = c;
+                this.deviceReadyChannelsArray.push(c);
+            }
+        },
+
+        /**
+         * Indicate that initialization code has completed and the feature is ready to be used.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        initializationComplete: function(feature) {
+            var c = this.deviceReadyChannelsMap[feature];
+            if (c) {
+                c.fire();
+            }
+        }
+    };
+
+function forceFunction(f) {
+    if (f === null || f === undefined || typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c, g) {
+    // need a function to call
+    forceFunction(f);
+
+    var func = f;
+    if (typeof c == "object") { func = utils.close(c, f); }
+
+    g = g || func.observer_guid || f.observer_guid;
+    if (!g) {
+        // first time we've seen this subscriber
+        g = this.guid++;
+    }
+    else {
+        // subscriber already handled; dont set it twice
+        return g;
+    }
+    func.observer_guid = g;
+    f.observer_guid = g;
+    this.handlers[g] = func;
+    this.numHandlers++;
+    if (this.events.onSubscribe) this.events.onSubscribe.call(this);
+    if (this.fired) func.call(this);
+    return g;
+};
+
+/**
+ * Like subscribe but the function is only called once and then it
+ * auto-unsubscribes itself.
+ */
+Channel.prototype.subscribeOnce = function(f, c) {
+    // need a function to call
+    forceFunction(f);
+
+    var g = null;
+    var _this = this;
+    var m = function() {
+        f.apply(c || null, arguments);
+        _this.unsubscribe(g);
+    };
+    if (this.fired) {
+        if (typeof c == "object") { f = utils.close(c, f); }
+        f.apply(this, this.fireArgs);
+    } else {
+        g = this.subscribe(m);
+    }
+    return g;
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(g) {
+    // need a function to unsubscribe
+    if (g === null || g === undefined) { throw "You must pass _something_ into Channel.unsubscribe"; }
+
+    if (typeof g == 'function') { g = g.observer_guid; }
+    var handler = this.handlers[g];
+    if (handler) {
+        if (handler.observer_guid) handler.observer_guid=null;
+        this.handlers[g] = null;
+        delete this.handlers[g];
+        this.numHandlers--;
+        if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);
+    }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+    if (this.enabled) {
+        var fail = false;
+        this.fired = true;
+        for (var item in this.handlers) {
+            var handler = this.handlers[item];
+            if (typeof handler == 'function') {
+                var rv = (handler.apply(this, arguments)===false);
+                fail = fail || rv;
+            }
+        }
+        this.fireArgs = arguments;
+        return !fail;
+    }
+    return true;
+};
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.create('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.create('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.create('onCordovaReady');
+
+// Event to indicate that device properties are available
+channel.create('onCordovaInfoReady');
+
+// Event to indicate that the connection property has been set.
+channel.create('onCordovaConnectionReady');
+
+// Event to indicate that Cordova is ready
+channel.create('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.create('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onCordovaConnectionReady');
+
+module.exports = channel;
+
+});
+
+// file: lib/common/common.js
+define("cordova/common", function(require, exports, module) {
+module.exports = {
+    objects: {
+        cordova: {
+            path: 'cordova',
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                },
+                logger: {
+                    path: 'cordova/plugin/logger'
+                }
+            }
+        },
+        Cordova: {
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                }
+            }
+        },
+        PhoneGap:{
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                }
+            }
+        },
+        navigator: {
+            children: {
+                notification: {
+                    path: 'cordova/plugin/notification'
+                },
+                accelerometer: {
+                    path: 'cordova/plugin/accelerometer'
+                },
+                battery: {
+                    path: 'cordova/plugin/battery'
+                },
+                camera:{
+                    path: 'cordova/plugin/Camera'
+                },
+                compass:{
+                    path: 'cordova/plugin/compass'
+                },
+                contacts: {
+                    path: 'cordova/plugin/contacts'
+                },
+                device:{
+                    children:{
+                        capture: {
+                            path: 'cordova/plugin/capture'
+                        }
+                    }
+                },
+                geolocation: {
+                    path: 'cordova/plugin/geolocation'
+                },
+                network: {
+                    children: {
+                        connection: {
+                            path: 'cordova/plugin/network'
+                        }
+                    }
+                },
+                splashscreen: {
+                    path: 'cordova/plugin/splashscreen'
+                }
+            }
+        },
+        Acceleration: {
+            path: 'cordova/plugin/Acceleration'
+        },
+        Camera:{
+            path: 'cordova/plugin/CameraConstants'
+        },
+        CameraPopoverOptions: {
+            path: 'cordova/plugin/CameraPopoverOptions'
+        },
+        CaptureError: {
+            path: 'cordova/plugin/CaptureError'
+        },
+        CaptureAudioOptions:{
+            path: 'cordova/plugin/CaptureAudioOptions'
+        },
+        CaptureImageOptions: {
+            path: 'cordova/plugin/CaptureImageOptions'
+        },
+        CaptureVideoOptions: {
+            path: 'cordova/plugin/CaptureVideoOptions'
+        },
+        CompassHeading:{
+            path: 'cordova/plugin/CompassHeading'
+        },
+        CompassError:{
+            path: 'cordova/plugin/CompassError'
+        },
+        ConfigurationData: {
+            path: 'cordova/plugin/ConfigurationData'
+        },
+        Connection: {
+            path: 'cordova/plugin/Connection'
+        },
+        Contact: {
+            path: 'cordova/plugin/Contact'
+        },
+        ContactAddress: {
+            path: 'cordova/plugin/ContactAddress'
+        },
+        ContactError: {
+            path: 'cordova/plugin/ContactError'
+        },
+        ContactField: {
+            path: 'cordova/plugin/ContactField'
+        },
+        ContactFindOptions: {
+            path: 'cordova/plugin/ContactFindOptions'
+        },
+        ContactName: {
+            path: 'cordova/plugin/ContactName'
+        },
+        ContactOrganization: {
+            path: 'cordova/plugin/ContactOrganization'
+        },
+        Coordinates: {
+            path: 'cordova/plugin/Coordinates'
+        },
+        device: {
+            path: 'cordova/plugin/device'
+        },
+        DirectoryEntry: {
+            path: 'cordova/plugin/DirectoryEntry'
+        },
+        DirectoryReader: {
+            path: 'cordova/plugin/DirectoryReader'
+        },
+        Entry: {
+            path: 'cordova/plugin/Entry'
+        },
+        File: {
+            path: 'cordova/plugin/File'
+        },
+        FileEntry: {
+            path: 'cordova/plugin/FileEntry'
+        },
+        FileError: {
+            path: 'cordova/plugin/FileError'
+        },
+        FileReader: {
+            path: 'cordova/plugin/FileReader'
+        },
+        FileSystem: {
+            path: 'cordova/plugin/FileSystem'
+        },
+        FileTransfer: {
+            path: 'cordova/plugin/FileTransfer'
+        },
+        FileTransferError: {
+            path: 'cordova/plugin/FileTransferError'
+        },
+        FileUploadOptions: {
+            path: 'cordova/plugin/FileUploadOptions'
+        },
+        FileUploadResult: {
+            path: 'cordova/plugin/FileUploadResult'
+        },
+        FileWriter: {
+            path: 'cordova/plugin/FileWriter'
+        },
+        Flags: {
+            path: 'cordova/plugin/Flags'
+        },
+        LocalFileSystem: {
+            path: 'cordova/plugin/LocalFileSystem'
+        },
+        Media: {
+            path: 'cordova/plugin/Media'
+        },
+        MediaError: {
+            path: 'cordova/plugin/MediaError'
+        },
+        MediaFile: {
+            path: 'cordova/plugin/MediaFile'
+        },
+        MediaFileData:{
+            path: 'cordova/plugin/MediaFileData'
+        },
+        Metadata:{
+            path: 'cordova/plugin/Metadata'
+        },
+        Position: {
+            path: 'cordova/plugin/Position'
+        },
+        PositionError: {
+            path: 'cordova/plugin/PositionError'
+        },
+        ProgressEvent: {
+            path: 'cordova/plugin/ProgressEvent'
+        },
+        requestFileSystem:{
+            path: 'cordova/plugin/requestFileSystem'
+        },
+        resolveLocalFileSystemURI:{
+            path: 'cordova/plugin/resolveLocalFileSystemURI'
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/exec.js
+define("cordova/exec", function(require, exports, module) {
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchrounous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} successCB  The success callback
+ * @param {Function} failCB     The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ */
+
+var tizen = require('cordova/plugin/tizen/manager'),
+    cordova = require('cordova'),
+    utils = require('cordova/utils');
+
+module.exports = function(successCB, failCB, service, action, args) {
+
+    try {
+        var v = tizen.exec(successCB, failCB, service, action, args);
+
+        // If status is OK, then return value back to caller
+        if (v.status == cordova.callbackStatus.OK) {
+
+            // If there is a success callback, then call it now with returned value
+            if (successCB) {
+                try {
+                    successCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+ service + "." + action + " = " + e);
+                }
+
+            }
+            return v.message;
+        } else if (v.status == cordova.callbackStatus.NO_RESULT) {
+            // Nothing to do here
+        } else {
+            // If error, then display error
+            console.log("Error: " + service + "." + action + " Status=" + v.status + " Message=" + v.message);
+
+            // If there is a fail callback, then call it now with returned value
+            if (failCB) {
+                try {
+                    failCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in error callback: " + service + "." + action + " = "+e);
+                }
+            }
+            return null;
+        }
+    } catch (e) {
+        utils.alert("Error: " + e);
+    }
+};
+
+});
+
+// file: lib/tizen/platform.js
+define("cordova/platform", function(require, exports, module) {
+module.exports = {
+    id: "tizen",
+    initialize: function() {},
+    objects: {
+        device: {
+            path: "cordova/plugin/tizen/Device"
+        },
+        File: { // exists natively, override
+            path: "cordova/plugin/File"
+        },
+        FileReader: { // exists natively, override
+            path: "cordova/plugin/FileReader"
+        },
+        FileError: { //exists natively, override
+            path: "cordova/plugin/FileError"
+        }
+    },
+    merges: {
+        MediaError: { // exists natively
+            path: "cordova/plugin/tizen/MediaError"
+        },
+        navigator: {
+            children: {
+                device: {
+                    path: "cordova/plugin/tizen/Device"
+                },
+                contacts: {
+                    path: "cordova/plugin/tizen/contacts"
+                },
+               notification: {
+                   path: "cordova/plugin/tizen/Notification"
+               }
+            }
+        },
+        Contact: {
+            path: "cordova/plugin/tizen/Contact"
+        }
+    }
+};
+
+});
+
+// file: lib/common/plugin/Acceleration.js
+define("cordova/plugin/Acceleration", function(require, exports, module) {
+var Acceleration = function(x, y, z, timestamp) {
+    this.x = x;
+    this.y = y;
+    this.z = z;
+    this.timestamp = timestamp || (new Date()).getTime();
+};
+
+module.exports = Acceleration;
+
+});
+
+// file: lib/common/plugin/Camera.js
+define("cordova/plugin/Camera", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    Camera = require('cordova/plugin/CameraConstants');
+
+var cameraExport = {};
+
+// Tack on the Camera Constants to the base camera plugin.
+for (var key in Camera) {
+    cameraExport[key] = Camera[key];
+}
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+cameraExport.getPicture = function(successCallback, errorCallback, options) {
+    // successCallback required
+    if (typeof successCallback != "function") {
+        console.log("Camera Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback != "function")) {
+        console.log("Camera Error: errorCallback is not a function");
+        return;
+    }
+
+    var quality = 50;
+    if (options && typeof options.quality == "number") {
+        quality = options.quality;
+    } else if (options && typeof options.quality == "string") {
+        var qlity = parseInt(options.quality, 10);
+        if (isNaN(qlity) === false) {
+            quality = qlity.valueOf();
+        }
+    }
+
+    var destinationType = Camera.DestinationType.FILE_URI;
+    if (typeof options.destinationType == "number") {
+        destinationType = options.destinationType;
+    }
+
+    var sourceType = Camera.PictureSourceType.CAMERA;
+    if (typeof options.sourceType == "number") {
+        sourceType = options.sourceType;
+    }
+
+    var targetWidth = -1;
+    if (typeof options.targetWidth == "number") {
+        targetWidth = options.targetWidth;
+    } else if (typeof options.targetWidth == "string") {
+        var width = parseInt(options.targetWidth, 10);
+        if (isNaN(width) === false) {
+            targetWidth = width.valueOf();
+        }
+    }
+
+    var targetHeight = -1;
+    if (typeof options.targetHeight == "number") {
+        targetHeight = options.targetHeight;
+    } else if (typeof options.targetHeight == "string") {
+        var height = parseInt(options.targetHeight, 10);
+        if (isNaN(height) === false) {
+            targetHeight = height.valueOf();
+        }
+    }
+
+    var encodingType = Camera.EncodingType.JPEG;
+    if (typeof options.encodingType == "number") {
+        encodingType = options.encodingType;
+    }
+
+    var mediaType = Camera.MediaType.PICTURE;
+    if (typeof options.mediaType == "number") {
+        mediaType = options.mediaType;
+    }
+    var allowEdit = false;
+    if (typeof options.allowEdit == "boolean") {
+        allowEdit = options.allowEdit;
+    } else if (typeof options.allowEdit == "number") {
+        allowEdit = options.allowEdit <= 0 ? false : true;
+    }
+    var correctOrientation = false;
+    if (typeof options.correctOrientation == "boolean") {
+        correctOrientation = options.correctOrientation;
+    } else if (typeof options.correctOrientation == "number") {
+        correctOrientation = options.correctOrientation <=0 ? false : true;
+    }
+    var saveToPhotoAlbum = false;
+    if (typeof options.saveToPhotoAlbum == "boolean") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum;
+    } else if (typeof options.saveToPhotoAlbum == "number") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum <=0 ? false : true;
+    }
+    var popoverOptions = null;
+    if (typeof options.popoverOptions == "object") {
+        popoverOptions = options.popoverOptions;
+    }
+
+    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
+                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+
+    exec(successCallback, errorCallback, "Camera", "takePicture", args);
+};
+
+cameraExport.cleanup = function(successCallback, errorCallback) {
+    exec(successCallback, errorCallback, "Camera", "cleanup", []);
+};
+
+module.exports = cameraExport;
+});
+
+// file: lib/common/plugin/CameraConstants.js
+define("cordova/plugin/CameraConstants", function(require, exports, module) {
+module.exports = {
+  DestinationType:{
+    DATA_URL: 0,         // Return base64 encoded string
+    FILE_URI: 1          // Return file uri (content://media/external/images/media/2 for Android)
+  },
+  EncodingType:{
+    JPEG: 0,             // Return JPEG encoded image
+    PNG: 1               // Return PNG encoded image
+  },
+  MediaType:{
+    PICTURE: 0,          // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
+    VIDEO: 1,            // allow selection of video only, ONLY RETURNS URL
+    ALLMEDIA : 2         // allow selection from all media types
+  },
+  PictureSourceType:{
+    PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
+    CAMERA : 1,          // Take picture from camera
+    SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)
+  },
+  PopoverArrowDirection:{
+      ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
+      ARROW_DOWN : 2,
+      ARROW_LEFT : 4,
+      ARROW_RIGHT : 8,
+      ARROW_ANY : 15
+  }
+};
+});
+
+// file: lib/common/plugin/CameraPopoverOptions.js
+define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
+var Camera = require('cordova/plugin/CameraConstants');
+
+/**
+ * Encapsulates options for iOS Popover image picker
+ */
+var CameraPopoverOptions = function(x,y,width,height,arrowDir){
+    // information of rectangle that popover should be anchored to
+    this.x = x || 0;
+    this.y = y || 32;
+    this.width = width || 320;
+    this.height = height || 480;
+    // The direction of the popover arrow
+    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
+};
+
+module.exports = CameraPopoverOptions;
+});
+
+// file: lib/common/plugin/CaptureAudioOptions.js
+define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
+/**
+ * Encapsulates all audio capture operation configuration options.
+ */
+var CaptureAudioOptions = function(){
+    // Upper limit of sound clips user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single sound clip in seconds.
+    this.duration = 0;
+    // The selected audio mode. Must match with one of the elements in supportedAudioModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureAudioOptions;
+});
+
+// file: lib/common/plugin/CaptureError.js
+define("cordova/plugin/CaptureError", function(require, exports, module) {
+/**
+ * The CaptureError interface encapsulates all errors in the Capture API.
+ */
+var CaptureError = function(c) {
+   this.code = c || null;
+};
+
+// Camera or microphone failed to capture image or sound.
+CaptureError.CAPTURE_INTERNAL_ERR = 0;
+// Camera application or audio capture application is currently serving other capture request.
+CaptureError.CAPTURE_APPLICATION_BUSY = 1;
+// Invalid use of the API (e.g. limit parameter has value less than one).
+CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
+// User exited camera application or audio capture application before capturing anything.
+CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
+// The requested capture operation is not supported.
+CaptureError.CAPTURE_NOT_SUPPORTED = 20;
+
+module.exports = CaptureError;
+});
+
+// file: lib/common/plugin/CaptureImageOptions.js
+define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
+/**
+ * Encapsulates all image capture operation configuration options.
+ */
+var CaptureImageOptions = function(){
+    // Upper limit of images user can take. Value must be equal or greater than 1.
+    this.limit = 1;
+    // The selected image mode. Must match with one of the elements in supportedImageModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureImageOptions;
+});
+
+// file: lib/common/plugin/CaptureVideoOptions.js
+define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
+/**
+ * Encapsulates all video capture operation configuration options.
+ */
+var CaptureVideoOptions = function(){
+    // Upper limit of videos user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single video clip in seconds.
+    this.duration = 0;
+    // The selected video mode. Must match with one of the elements in supportedVideoModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureVideoOptions;
+});
+
+// file: lib/common/plugin/CompassError.js
+define("cordova/plugin/CompassError", function(require, exports, module) {
+/**
+ *  CompassError.
+ *  An error code assigned by an implementation when an error has occured
+ * @constructor
+ */
+var CompassError = function(err) {
+    this.code = (err !== undefined ? err : null);
+};
+
+CompassError.COMPASS_INTERNAL_ERR = 0;
+CompassError.COMPASS_NOT_SUPPORTED = 20;
+
+module.exports = CompassError;
+});
+
+// file: lib/common/plugin/CompassHeading.js
+define("cordova/plugin/CompassHeading", function(require, exports, module) {
+var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
+  this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null);
+  this.trueHeading = (trueHeading !== undefined ? trueHeading : null);
+  this.headingAccuracy = (headingAccuracy !== undefined ? headingAccuracy : null);
+  this.timestamp = (timestamp !== undefined ? timestamp : new Date().getTime());
+};
+
+module.exports = CompassHeading;
+});
+
+// file: lib/common/plugin/ConfigurationData.js
+define("cordova/plugin/ConfigurationData", function(require, exports, module) {
+/**
+ * Encapsulates a set of parameters that the capture device supports.
+ */
+function ConfigurationData() {
+    // The ASCII-encoded string in lower case representing the media type.
+    this.type = null;
+    // The height attribute represents height of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0.
+    this.height = 0;
+    // The width attribute represents width of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0
+    this.width = 0;
+}
+
+module.exports = ConfigurationData;
+});
+
+// file: lib/common/plugin/Connection.js
+define("cordova/plugin/Connection", function(require, exports, module) {
+/**
+ * Network status
+ */
+module.exports = {
+        UNKNOWN: "unknown",
+        ETHERNET: "ethernet",
+        WIFI: "wifi",
+        CELL_2G: "2g",
+        CELL_3G: "3g",
+        CELL_4G: "4g",
+        NONE: "none"
+};
+});
+
+// file: lib/common/plugin/Contact.js
+define("cordova/plugin/Contact", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils');
+
+/**
+* Converts primitives into Complex Object
+* Currently only used for Date fields
+*/
+function convertIn(contact) {
+    var value = contact.birthday;
+    try {
+      contact.birthday = new Date(parseFloat(value));
+    } catch (exception){
+      console.log("Cordova Contact convertIn error: exception creating date.");
+    }
+    return contact;
+}
+
+/**
+* Converts Complex objects into primitives
+* Only conversion at present is for Dates.
+**/
+
+function convertOut(contact) {
+    var value = contact.birthday;
+    if (value !== null) {
+        // try to make it a Date object if it is not already
+        if (!utils.isDate(value)){
+            try {
+                value = new Date(value);
+            } catch(exception){
+                value = null;
+            }
+        }
+        if (utils.isDate(value)){
+            value = value.valueOf(); // convert to milliseconds
+        }
+        contact.birthday = value;
+    }
+    return contact;
+}
+
+/**
+* Contains information about a single contact.
+* @constructor
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {Array.<ContactField>} phoneNumbers array of phone numbers
+* @param {Array.<ContactField>} emails array of email addresses
+* @param {Array.<ContactAddress>} addresses array of addresses
+* @param {Array.<ContactField>} ims instant messaging user ids
+* @param {Array.<ContactOrganization>} organizations
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} note user notes about contact
+* @param {Array.<ContactField>} photos
+* @param {Array.<ContactField>} categories
+* @param {Array.<ContactField>} urls contact's web sites
+*/
+var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
+    ims, organizations, birthday, note, photos, categories, urls) {
+    this.id = id || null;
+    this.rawId = null;
+    this.displayName = displayName || null;
+    this.name = name || null; // ContactName
+    this.nickname = nickname || null;
+    this.phoneNumbers = phoneNumbers || null; // ContactField[]
+    this.emails = emails || null; // ContactField[]
+    this.addresses = addresses || null; // ContactAddress[]
+    this.ims = ims || null; // ContactField[]
+    this.organizations = organizations || null; // ContactOrganization[]
+    this.birthday = birthday || null;
+    this.note = note || null;
+    this.photos = photos || null; // ContactField[]
+    this.categories = categories || null; // ContactField[]
+    this.urls = urls || null; // ContactField[]
+};
+
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+    var fail = function(code) {
+        errorCB(new ContactError(code));
+    };
+    if (this.id === null) {
+        fail(ContactError.UNKNOWN_ERROR);
+    }
+    else {
+        exec(successCB, fail, "Contacts", "remove", [this.id]);
+    }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+    var clonedContact = utils.clone(this);
+    var i;
+    clonedContact.id = null;
+    clonedContact.rawId = null;
+    // Loop through and clear out any id's in phones, emails, etc.
+    if (clonedContact.phoneNumbers) {
+        for (i = 0; i < clonedContact.phoneNumbers.length; i++) {
+            clonedContact.phoneNumbers[i].id = null;
+        }
+    }
+    if (clonedContact.emails) {
+        for (i = 0; i < clonedContact.emails.length; i++) {
+            clonedContact.emails[i].id = null;
+        }
+    }
+    if (clonedContact.addresses) {
+        for (i = 0; i < clonedContact.addresses.length; i++) {
+            clonedContact.addresses[i].id = null;
+        }
+    }
+    if (clonedContact.ims) {
+        for (i = 0; i < clonedContact.ims.length; i++) {
+            clonedContact.ims[i].id = null;
+        }
+    }
+    if (clonedContact.organizations) {
+        for (i = 0; i < clonedContact.organizations.length; i++) {
+            clonedContact.organizations[i].id = null;
+        }
+    }
+    if (clonedContact.categories) {
+        for (i = 0; i < clonedContact.categories.length; i++) {
+            clonedContact.categories[i].id = null;
+        }
+    }
+    if (clonedContact.photos) {
+        for (i = 0; i < clonedContact.photos.length; i++) {
+            clonedContact.photos[i].id = null;
+        }
+    }
+    if (clonedContact.urls) {
+        for (i = 0; i < clonedContact.urls.length; i++) {
+            clonedContact.urls[i].id = null;
+        }
+    }
+    return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+  var fail = function(code) {
+      errorCB(new ContactError(code));
+  };
+    var success = function(result) {
+      if (result) {
+          if (typeof successCB === 'function') {
+              var fullContact = require('cordova/plugin/contacts').create(result);
+              successCB(convertIn(fullContact));
+          }
+      }
+      else {
+          // no Entry object returned
+          fail(ContactError.UNKNOWN_ERROR);
+      }
+  };
+    var dupContact = convertOut(utils.clone(this));
+    exec(success, fail, "Contacts", "save", [dupContact]);
+};
+
+
+module.exports = Contact;
+
+});
+
+// file: lib/common/plugin/ContactAddress.js
+define("cordova/plugin/ContactAddress", function(require, exports, module) {
+/**
+* Contact address.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code
+* @param formatted // NOTE: not a W3C standard
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+
+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.formatted = formatted || null;
+    this.streetAddress = streetAddress || null;
+    this.locality = locality || null;
+    this.region = region || null;
+    this.postalCode = postalCode || null;
+    this.country = country || null;
+};
+
+module.exports = ContactAddress;
+});
+
+// file: lib/common/plugin/ContactError.js
+define("cordova/plugin/ContactError", function(require, exports, module) {
+/**
+ *  ContactError.
+ *  An error code assigned by an implementation when an error has occured
+ * @constructor
+ */
+var ContactError = function(err) {
+    this.code = (typeof err != 'undefined' ? err : null);
+};
+
+/**
+ * Error codes
+ */
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.TIMEOUT_ERROR = 2;
+ContactError.PENDING_OPERATION_ERROR = 3;
+ContactError.IO_ERROR = 4;
+ContactError.NOT_SUPPORTED_ERROR = 5;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+module.exports = ContactError;
+});
+
+// file: lib/common/plugin/ContactField.js
+define("cordova/plugin/ContactField", function(require, exports, module) {
+/**
+* Generic contact field.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param type
+* @param value
+* @param pref
+*/
+var ContactField = function(type, value, pref) {
+    this.id = null;
+    this.type = (type && type.toString()) || null;
+    this.value = (value && value.toString()) || null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+};
+
+module.exports = ContactField;
+});
+
+// file: lib/common/plugin/ContactFindOptions.js
+define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
+/**
+ * ContactFindOptions.
+ * @constructor
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ */
+
+var ContactFindOptions = function(filter, multiple) {
+    this.filter = filter || '';
+    this.multiple = (typeof multiple != 'undefined' ? multiple : false);
+};
+
+module.exports = ContactFindOptions;
+});
+
+// file: lib/common/plugin/ContactName.js
+define("cordova/plugin/ContactName", function(require, exports, module) {
+/**
+* Contact name.
+* @constructor
+* @param formatted // NOTE: not part of W3C standard
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
+    this.formatted = formatted || null;
+    this.familyName = familyName || null;
+    this.givenName = givenName || null;
+    this.middleName = middle || null;
+    this.honorificPrefix = prefix || null;
+    this.honorificSuffix = suffix || null;
+};
+
+module.exports = ContactName;
+});
+
+// file: lib/common/plugin/ContactOrganization.js
+define("cordova/plugin/ContactOrganization", function(require, exports, module) {
+/**
+* Contact organization.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param name
+* @param dept
+* @param title
+* @param startDate
+* @param endDate
+* @param location
+* @param desc
+*/
+
+var ContactOrganization = function(pref, type, name, dept, title) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.name = name || null;
+    this.department = dept || null;
+    this.title = title || null;
+};
+
+module.exports = ContactOrganization;
+});
+
+// file: lib/common/plugin/Coordinates.js
+define("cordova/plugin/Coordinates", function(require, exports, module) {
+/**
+ * This class contains position information.
+ * @param {Object} lat
+ * @param {Object} lng
+ * @param {Object} alt
+ * @param {Object} acc
+ * @param {Object} head
+ * @param {Object} vel
+ * @param {Object} altacc
+ * @constructor
+ */
+var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
+    /**
+     * The latitude of the position.
+     */
+    this.latitude = lat;
+    /**
+     * The longitude of the position,
+     */
+    this.longitude = lng;
+    /**
+     * The accuracy of the position.
+     */
+    this.accuracy = acc;
+    /**
+     * The altitude of the position.
+     */
+    this.altitude = (alt !== undefined ? alt : null);
+    /**
+     * The direction the device is moving at the position.
+     */
+    this.heading = (head !== undefined ? head : null);
+    /**
+     * The velocity with which the device is moving at the position.
+     */
+    this.speed = (vel !== undefined ? vel : null);
+
+    if (this.speed === 0 || this.speed === null) {
+        this.heading = NaN;
+    }
+
+    /**
+     * The altitude accuracy of the position.
+     */
+    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
+};
+
+module.exports = Coordinates;
+
+});
+
+// file: lib/common/plugin/DirectoryEntry.js
+define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileError = require('cordova/plugin/FileError'),
+    DirectoryReader = require('cordova/plugin/DirectoryReader');
+
+/**
+ * An interface representing a directory on the file system.
+ *
+ * {boolean} isFile always false (readonly)
+ * {boolean} isDirectory always true (readonly)
+ * {DOMString} name of the directory, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the directory (readonly)
+ * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
+ */
+var DirectoryEntry = function(name, fullPath) {
+     DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]);
+};
+
+utils.extend(DirectoryEntry, Entry);
+
+/**
+ * Creates a new DirectoryReader to read entries from this directory
+ */
+DirectoryEntry.prototype.createReader = function() {
+    return new DirectoryReader(this.fullPath);
+};
+
+/**
+ * Creates or looks up a directory
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
+ * @param {Flags} options to create or excluively create the directory
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
+};
+
+/**
+ * Deletes a directory and all of it's contents
+ *
+ * @param {Function} successCallback is called with no parameters
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
+};
+
+/**
+ * Creates or looks up a file
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
+ * @param {Flags} options to create or excluively create the file
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var FileEntry = require('cordova/plugin/FileEntry');
+        var entry = new FileEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
+};
+
+module.exports = DirectoryEntry;
+
+});
+
+// file: lib/common/plugin/DirectoryReader.js
+define("cordova/plugin/DirectoryReader", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError') ;
+
+/**
+ * An interface that lists the files and directories in a directory.
+ */
+function DirectoryReader(path) {
+    this.path = path || null;
+}
+
+/**
+ * Returns a list of entries from a directory.
+ *
+ * @param {Function} successCallback is called with a list of entries
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var retVal = [];
+        for (var i=0; i<result.length; i++) {
+            var entry = null;
+            if (result[i].isDirectory) {
+                entry = new (require('cordova/plugin/DirectoryEntry'))();
+            }
+            else if (result[i].isFile) {
+                entry = new (require('cordova/plugin/FileEntry'))();
+            }
+            entry.isDirectory = result[i].isDirectory;
+            entry.isFile = result[i].isFile;
+            entry.name = result[i].name;
+            entry.fullPath = result[i].fullPath;
+            retVal.push(entry);
+        }
+        successCallback(retVal);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "readEntries", [this.path]);
+};
+
+module.exports = DirectoryReader;
+
+});
+
+// file: lib/common/plugin/Entry.js
+define("cordova/plugin/Entry", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    Metadata = require('cordova/plugin/Metadata');
+
+/**
+ * Represents a file or directory on the local file system.
+ *
+ * @param isFile
+ *            {boolean} true if Entry is a file (readonly)
+ * @param isDirectory
+ *            {boolean} true if Entry is a directory (readonly)
+ * @param name
+ *            {DOMString} name of the file or directory, excluding the path
+ *            leading to it (readonly)
+ * @param fullPath
+ *            {DOMString} the absolute full path to the file or directory
+ *            (readonly)
+ */
+function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
+    this.isFile = (typeof isFile != 'undefined'?isFile:false);
+    this.isDirectory = (typeof isDirectory != 'undefined'?isDirectory:false);
+    this.name = name || '';
+    this.fullPath = fullPath || '';
+    this.filesystem = fileSystem || null;
+}
+
+/**
+ * Look up the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ */
+Entry.prototype.getMetadata = function(successCallback, errorCallback) {
+  var success = typeof successCallback !== 'function' ? null : function(lastModified) {
+      var metadata = new Metadata(lastModified);
+      successCallback(metadata);
+  };
+  var fail = typeof errorCallback !== 'function' ? null : function(code) {
+      errorCallback(new FileError(code));
+  };
+
+  exec(success, fail, "File", "getMetadata", [this.fullPath]);
+};
+
+/**
+ * Set the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ * @param metadataObject
+ *            {Object} keys and values to set
+ */
+Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
+
+  exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
+};
+
+/**
+ * Move a file or directory to a new location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to move this entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new DirectoryEntry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+    // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Copy a directory to a different location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to copy the entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new Entry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+
+        // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        // success callback
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Return a URL that can be used to identify this entry.
+ */
+Entry.prototype.toURL = function() {
+    // fullPath attribute contains the full URL
+    return this.fullPath;
+};
+
+/**
+ * Returns a URI that can be used to identify this entry.
+ *
+ * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
+ * @return uri
+ */
+Entry.prototype.toURI = function(mimeType) {
+    console.log("DEPRECATED: Update your code to use 'toURL'");
+    // fullPath attribute contains the full URI
+    return this.toURL();
+};
+
+/**
+ * Remove a file or directory. It is an error to attempt to delete a
+ * directory that is not empty. It is an error to attempt to delete a
+ * root directory of a file system.
+ *
+ * @param successCallback {Function} called with no parameters
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.remove = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "remove", [this.fullPath]);
+};
+
+/**
+ * Look up the parent DirectoryEntry of this entry.
+ *
+ * @param successCallback {Function} called with the parent DirectoryEntry object
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.getParent = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getParent", [this.fullPath]);
+};
+
+module.exports = Entry;
+});
+
+// file: lib/common/plugin/File.js
+define("cordova/plugin/File", function(require, exports, module) {
+/**
+ * Constructor.
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+
+var File = function(name, fullPath, type, lastModifiedDate, size){
+    this.name = name || '';
+    this.fullPath = fullPath || null;
+    this.type = type || null;
+    this.lastModifiedDate = lastModifiedDate || null;
+    this.size = size || 0;
+};
+
+module.exports = File;
+});
+
+// file: lib/common/plugin/FileEntry.js
+define("cordova/plugin/FileEntry", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileWriter = require('cordova/plugin/FileWriter'),
+    File = require('cordova/plugin/File'),
+    FileError = require('cordova/plugin/FileError');
+
+/**
+ * An interface representing a file on the file system.
+ *
+ * {boolean} isFile always true (readonly)
+ * {boolean} isDirectory always false (readonly)
+ * {DOMString} name of the file, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the file (readonly)
+ * {FileSystem} filesystem on which the file resides (readonly)
+ */
+var FileEntry = function(name, fullPath) {
+     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
+};
+
+utils.extend(FileEntry, Entry);
+
+/**
+ * Creates a new FileWriter associated with the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new FileWriter
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
+    this.file(function(filePointer) {
+        var writer = new FileWriter(filePointer);
+
+        if (writer.fileName === null || writer.fileName === "") {
+            if (typeof errorCallback === "function") {
+                errorCallback(new FileError(FileError.INVALID_STATE_ERR));
+            }
+        } else {
+            if (typeof successCallback === "function") {
+                successCallback(writer);
+            }
+        }
+    }, errorCallback);
+};
+
+/**
+ * Returns a File that represents the current state of the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new File object
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.file = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(f) {
+        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
+        successCallback(file);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
+};
+
+
+module.exports = FileEntry;
+});
+
+// file: lib/common/plugin/FileError.js
+define("cordova/plugin/FileError", function(require, exports, module) {
+/**
+ * FileError
+ */
+function FileError(error) {
+  this.code = error || null;
+}
+
+// File error codes
+// Found in DOMException
+FileError.NOT_FOUND_ERR = 1;
+FileError.SECURITY_ERR = 2;
+FileError.ABORT_ERR = 3;
+
+// Added by File API specification
+FileError.NOT_READABLE_ERR = 4;
+FileError.ENCODING_ERR = 5;
+FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
+FileError.INVALID_STATE_ERR = 7;
+FileError.SYNTAX_ERR = 8;
+FileError.INVALID_MODIFICATION_ERR = 9;
+FileError.QUOTA_EXCEEDED_ERR = 10;
+FileError.TYPE_MISMATCH_ERR = 11;
+FileError.PATH_EXISTS_ERR = 12;
+
+module.exports = FileError;
+});
+
+// file: lib/common/plugin/FileReader.js
+define("cordova/plugin/FileReader", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class reads the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To read from the SD card, the file name is "sdcard/my_file.txt"
+ * @constructor
+ */
+var FileReader = function() {
+    this.fileName = "";
+
+    this.readyState = 0; // FileReader.EMPTY
+
+    // File data
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onloadstart = null;    // When the read starts.
+    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total)
+    this.onload = null;         // When the read has successfully completed.
+    this.onerror = null;        // When the read has failed (see errors).
+    this.onloadend = null;      // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.
+};
+
+// States
+FileReader.EMPTY = 0;
+FileReader.LOADING = 1;
+FileReader.DONE = 2;
+
+/**
+ * Abort reading file.
+ */
+FileReader.prototype.abort = function() {
+    this.result = null;
+
+    if (this.readyState == FileReader.DONE || this.readyState == FileReader.EMPTY) {
+      return;
+    }
+
+    this.readyState = FileReader.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === 'function') {
+        this.onabort(new ProgressEvent('abort', {target:this}));
+    }
+    // If load end callback
+    if (typeof this.onloadend === 'function') {
+        this.onloadend(new ProgressEvent('loadend', {target:this}));
+    }
+};
+
+/**
+ * Read text file.
+ *
+ * @param file          {File} File object containing file properties
+ * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)
+ */
+FileReader.prototype.readAsText = function(file, encoding) {
+    // Figure out pathing
+    this.fileName = '';
+    if (typeof file.fullPath === 'undefined') {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    // Default encoding is UTF-8
+    var enc = encoding ? encoding : "UTF-8";
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // null result
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsText", [this.fileName, enc]);
+};
+
+
+/**
+ * Read file and return data as a base64 encoded data url.
+ * A data url is of the form:
+ *      data:[<mediatype>][;base64],<data>
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsDataURL = function(file) {
+    this.fileName = "";
+    if (typeof file.fullPath === "undefined") {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsDataURL", [this.fileName]);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsBinaryString = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('method "readAsBinaryString" is not supported at this time.');
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsArrayBuffer = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('This method is not supported at this time.');
+};
+
+module.exports = FileReader;
+});
+
+// file: lib/common/plugin/FileSystem.js
+define("cordova/plugin/FileSystem", function(require, exports, module) {
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+
+/**
+ * An interface representing a file system
+ *
+ * @constructor
+ * {DOMString} name the unique name of the file system (readonly)
+ * {DirectoryEntry} root directory of the file system (readonly)
+ */
+var FileSystem = function(name, root) {
+    this.name = name || null;
+    if (root) {
+        this.root = new DirectoryEntry(root.name, root.fullPath);
+    }
+};
+
+module.exports = FileSystem;
+
+});
+
+// file: lib/common/plugin/FileTransfer.js
+define("cordova/plugin/FileTransfer", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileTransferError = require('cordova/plugin/FileTransferError');
+
+/**
+ * FileTransfer uploads a file to a remote server.
+ * @constructor
+ */
+var FileTransfer = function() {};
+
+/**
+* Given an absolute file path, uploads a file on the device to a remote server
+* using a multipart HTTP request.
+* @param filePath {String}           Full path of the file on the device
+* @param server {String}             URL of the server to receive the file
+* @param successCallback (Function}  Callback to be invoked when upload has completed
+* @param errorCallback {Function}    Callback to be invoked upon error
+* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
+* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+*/
+FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
+    // sanity parameter checking
+    if (!filePath || !server) throw new Error("FileTransfer.upload requires filePath and server URL parameters at the minimum.");
+    // check for options
+    var fileKey = null;
+    var fileName = null;
+    var mimeType = null;
+    var params = null;
+    var chunkedMode = true;
+    if (options) {
+        fileKey = options.fileKey;
+        fileName = options.fileName;
+        mimeType = options.mimeType;
+        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
+            chunkedMode = options.chunkedMode;
+        }
+        if (options.params) {
+            params = options.params;
+        }
+        else {
+            params = {};
+        }
+    }
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]);
+};
+
+/**
+ * Downloads a file form a given URL and saves it to the specified directory.
+ * @param source {String}          URL of the server to receive the file
+ * @param target {String}         Full path of the file on the device
+ * @param successCallback (Function}  Callback to be invoked when upload has completed
+ * @param errorCallback {Function}    Callback to be invoked upon error
+ */
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) {
+    // sanity parameter checking
+    if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum.");
+    var win = function(result) {
+        var entry = null;
+        if (result.isDirectory) {
+            entry = new (require('cordova/plugin/DirectoryEntry'))();
+        }
+        else if (result.isFile) {
+            entry = new (require('cordova/plugin/FileEntry'))();
+        }
+        entry.isDirectory = result.isDirectory;
+        entry.isFile = result.isFile;
+        entry.name = result.name;
+        entry.fullPath = result.fullPath;
+        successCallback(entry);
+    };
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    exec(win, errorCallback, 'FileTransfer', 'download', [source, target]);
+};
+
+module.exports = FileTransfer;
+
+});
+
+// file: lib/common/plugin/FileTransferError.js
+define("cordova/plugin/FileTransferError", function(require, exports, module) {
+/**
+ * FileTransferError
+ * @constructor
+ */
+var FileTransferError = function(code, source, target, status) {
+    this.code = code || null;
+    this.source = source || null;
+    this.target = target || null;
+    this.http_status = status || null;
+};
+
+FileTransferError.FILE_NOT_FOUND_ERR = 1;
+FileTransferError.INVALID_URL_ERR = 2;
+FileTransferError.CONNECTION_ERR = 3;
+
+module.exports = FileTransferError;
+
+});
+
+// file: lib/common/plugin/FileUploadOptions.js
+define("cordova/plugin/FileUploadOptions", function(require, exports, module) {
+/**
+ * Options to customize the HTTP request used to upload files.
+ * @constructor
+ * @param fileKey {String}   Name of file request parameter.
+ * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.
+ * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.
+ * @param params {Object}    Object with key: value params to send to the server.
+ */
+var FileUploadOptions = function(fileKey, fileName, mimeType, params) {
+    this.fileKey = fileKey || null;
+    this.fileName = fileName || null;
+    this.mimeType = mimeType || null;
+    this.params = params || null;
+};
+
+module.exports = FileUploadOptions;
+});
+
+// file: lib/common/plugin/FileUploadResult.js
+define("cordova/plugin/FileUploadResult", function(require, exports, module) {
+/**
+ * FileUploadResult
+ * @constructor
+ */
+var FileUploadResult = function() {
+    this.bytesSent = 0;
+    this.responseCode = null;
+    this.response = null;
+};
+
+module.exports = FileUploadResult;
+});
+
+// file: lib/common/plugin/FileWriter.js
+define("cordova/plugin/FileWriter", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class writes to the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To write to the SD card, the file name is "sdcard/my_file.txt"
+ *
+ * @constructor
+ * @param file {File} File object containing file properties
+ * @param append if true write to the end of the file, otherwise overwrite the file
+ */
+var FileWriter = function(file) {
+    this.fileName = "";
+    this.length = 0;
+    if (file) {
+        this.fileName = file.fullPath || file;
+        this.length = file.size || 0;
+    }
+    // default is to write at the beginning of the file
+    this.position = 0;
+
+    this.readyState = 0; // EMPTY
+
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onwritestart = null;   // When writing starts
+    this.onprogress = null;     // While writing the file, and reporting partial file data
+    this.onwrite = null;        // When the write has successfully completed.
+    this.onwriteend = null;     // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.
+    this.onerror = null;        // When the write has failed (see errors).
+};
+
+// States
+FileWriter.INIT = 0;
+FileWriter.WRITING = 1;
+FileWriter.DONE = 2;
+
+/**
+ * Abort writing file.
+ */
+FileWriter.prototype.abort = function() {
+    // check for invalid state
+    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // set error
+    this.error = new FileError(FileError.ABORT_ERR);
+
+    this.readyState = FileWriter.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === "function") {
+        this.onabort(new ProgressEvent("abort", {"target":this}));
+    }
+
+    // If write end callback
+    if (typeof this.onwriteend === "function") {
+        this.onwriteend(new ProgressEvent("writeend", {"target":this}));
+    }
+};
+
+/**
+ * Writes data to the file
+ *
+ * @param text to be written
+ */
+FileWriter.prototype.write = function(text) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":me}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // position always increases by bytes written because file would be extended
+            me.position += r;
+            // The length of the file is now where we are done writing.
+
+            me.length = me.position;
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "write", [this.fileName, text, this.position]);
+};
+
+/**
+ * Moves the file pointer to the location specified.
+ *
+ * If the offset is a negative number the position of the file
+ * pointer is rewound.  If the offset is greater than the file
+ * size the position is set to the end of the file.
+ *
+ * @param offset is the location to move the file pointer to.
+ */
+FileWriter.prototype.seek = function(offset) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    if (!offset && offset !== 0) {
+        return;
+    }
+
+    // See back from end of file.
+    if (offset < 0) {
+        this.position = Math.max(offset + this.length, 0);
+    }
+    // Offset is bigger then file size so set position
+    // to the end of the file.
+    else if (offset > this.length) {
+        this.position = this.length;
+    }
+    // Offset is between 0 and file size so set the position
+    // to start writing.
+    else {
+        this.position = offset;
+    }
+};
+
+/**
+ * Truncates the file to the size specified.
+ *
+ * @param size to chop the file at.
+ */
+FileWriter.prototype.truncate = function(size) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":this}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Update the length of the file
+            me.length = r;
+            me.position = Math.min(me.position, r);
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "truncate", [this.fileName, size]);
+};
+
+module.exports = FileWriter;
+
+});
+
+// file: lib/common/plugin/Flags.js
+define("cordova/plugin/Flags", function(require, exports, module) {
+/**
+ * Supplies arguments to methods that lookup or create files and directories.
+ *
+ * @param create
+ *            {boolean} file or directory if it doesn't exist
+ * @param exclusive
+ *            {boolean} used with create; if true the command will fail if
+ *            target path exists
+ */
+function Flags(create, exclusive) {
+    this.create = create || false;
+    this.exclusive = exclusive || false;
+}
+
+module.exports = Flags;
+});
+
+// file: lib/common/plugin/LocalFileSystem.js
+define("cordova/plugin/LocalFileSystem", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+/**
+ * Represents a local file system.
+ */
+var LocalFileSystem = function() {
+
+};
+
+LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence
+LocalFileSystem.PERSISTENT = 1; //persistent
+
+module.exports = LocalFileSystem;
+});
+
+// file: lib/common/plugin/Media.js
+define("cordova/plugin/Media", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+var mediaObjects = {};
+
+/**
+ * This class provides access to the device media, interfaces to both sound and video
+ *
+ * @constructor
+ * @param src                   The file name or url to play
+ * @param successCallback       The callback to be called when the file is done playing or recording.
+ *                                  successCallback()
+ * @param errorCallback         The callback to be called if there is an error.
+ *                                  errorCallback(int errorCode) - OPTIONAL
+ * @param statusCallback        The callback to be called when media status has changed.
+ *                                  statusCallback(int statusCode) - OPTIONAL
+ */
+var Media = function(src, successCallback, errorCallback, statusCallback) {
+
+    // successCallback optional
+    if (successCallback && (typeof successCallback !== "function")) {
+        console.log("Media Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Media Error: errorCallback is not a function");
+        return;
+    }
+
+    // statusCallback optional
+    if (statusCallback && (typeof statusCallback !== "function")) {
+        console.log("Media Error: statusCallback is not a function");
+        return;
+    }
+
+    this.id = utils.createUUID();
+    mediaObjects[this.id] = this;
+    this.src = src;
+    this.successCallback = successCallback;
+    this.errorCallback = errorCallback;
+    this.statusCallback = statusCallback;
+    this._duration = -1;
+    this._position = -1;
+    exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
+};
+
+// Media messages
+Media.MEDIA_STATE = 1;
+Media.MEDIA_DURATION = 2;
+Media.MEDIA_POSITION = 3;
+Media.MEDIA_ERROR = 9;
+
+// Media states
+Media.MEDIA_NONE = 0;
+Media.MEDIA_STARTING = 1;
+Media.MEDIA_RUNNING = 2;
+Media.MEDIA_PAUSED = 3;
+Media.MEDIA_STOPPED = 4;
+Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
+
+// "static" function to return existing objs.
+Media.get = function(id) {
+    return mediaObjects[id];
+};
+
+/**
+ * Start or resume playing audio file.
+ */
+Media.prototype.play = function(options) {
+    exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
+};
+
+/**
+ * Stop playing audio file.
+ */
+Media.prototype.stop = function() {
+    var me = this;
+    exec(function() {
+        me._position = 0;
+        me.successCallback();
+    }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
+};
+
+/**
+ * Seek or jump to a new time in the track..
+ */
+Media.prototype.seekTo = function(milliseconds) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+    }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
+};
+
+/**
+ * Pause playing audio file.
+ */
+Media.prototype.pause = function() {
+    exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
+};
+
+/**
+ * Get duration of an audio file.
+ * The duration is only set for audio that is playing, paused or stopped.
+ *
+ * @return      duration or -1 if not known.
+ */
+Media.prototype.getDuration = function() {
+    return this._duration;
+};
+
+/**
+ * Get position of audio.
+ */
+Media.prototype.getCurrentPosition = function(success, fail) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+        success(p);
+    }, fail, "Media", "getCurrentPositionAudio", [this.id]);
+};
+
+/**
+ * Start recording audio file.
+ */
+Media.prototype.startRecord = function() {
+    exec(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
+};
+
+/**
+ * Stop recording audio file.
+ */
+Media.prototype.stopRecord = function() {
+    exec(this.successCallback, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
+};
+
+/**
+ * Release the resources.
+ */
+Media.prototype.release = function() {
+    exec(null, this.errorCallback, "Media", "release", [this.id]);
+};
+
+/**
+ * Adjust the volume.
+ */
+Media.prototype.setVolume = function(volume) {
+    exec(null, null, "Media", "setVolume", [this.id, volume]);
+};
+
+/**
+ * Audio has status update.
+ * PRIVATE
+ *
+ * @param id            The media object id (string)
+ * @param status        The status code (int)
+ * @param msg           The status message (string)
+ */
+Media.onStatus = function(id, msg, value) {
+    var media = mediaObjects[id];
+    // If state update
+    if (msg === Media.MEDIA_STATE) {
+        if (value === Media.MEDIA_STOPPED) {
+            if (media.successCallback) {
+                media.successCallback();
+            }
+        }
+        if (media.statusCallback) {
+            media.statusCallback(value);
+        }
+    }
+    else if (msg === Media.MEDIA_DURATION) {
+        media._duration = value;
+    }
+    else if (msg === Media.MEDIA_ERROR) {
+        if (media.errorCallback) {
+            // value should be a MediaError object when msg == MEDIA_ERROR
+            media.errorCallback(value);
+        }
+    }
+    else if (msg === Media.MEDIA_POSITION) {
+        media._position = value;
+    }
+};
+
+module.exports = Media;
+});
+
+// file: lib/common/plugin/MediaError.js
+define("cordova/plugin/MediaError", function(require, exports, module) {
+/**
+ * This class contains information about any Media errors.
+ * @constructor
+ */
+var MediaError = function(code, msg) {
+    this.code = (code !== undefined ? code : null);
+    this.message = msg || "";
+};
+
+MediaError.MEDIA_ERR_NONE_ACTIVE    = 0;
+MediaError.MEDIA_ERR_ABORTED        = 1;
+MediaError.MEDIA_ERR_NETWORK        = 2;
+MediaError.MEDIA_ERR_DECODE         = 3;
+MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
+
+module.exports = MediaError;
+});
+
+// file: lib/common/plugin/MediaFile.js
+define("cordova/plugin/MediaFile", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    File = require('cordova/plugin/File'),
+    CaptureError = require('cordova/plugin/CaptureError');
+/**
+ * Represents a single file.
+ *
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+var MediaFile = function(name, fullPath, type, lastModifiedDate, size){
+    MediaFile.__super__.constructor.apply(this, arguments);
+};
+
+utils.extend(MediaFile, File);
+
+/**
+ * Request capture format data for a specific file and type
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ */
+MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
+    if (typeof this.fullPath === "undefined" || this.fullPath === null) {
+        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));
+    } else {
+        exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);
+    }
+};
+
+// TODO: can we axe this?
+/**
+ * Casts a PluginResult message property  (array of objects) to an array of MediaFile objects
+ * (used in Objective-C and Android)
+ *
+ * @param {PluginResult} pluginResult
+ */
+MediaFile.cast = function(pluginResult) {
+    var mediaFiles = [];
+    for (var i=0; i<pluginResult.message.length; i++) {
+        var mediaFile = new MediaFile();
+        mediaFile.name = pluginResult.message[i].name;
+        mediaFile.fullPath = pluginResult.message[i].fullPath;
+        mediaFile.type = pluginResult.message[i].type;
+        mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate;
+        mediaFile.size = pluginResult.message[i].size;
+        mediaFiles.push(mediaFile);
+    }
+    pluginResult.message = mediaFiles;
+    return pluginResult;
+};
+
+module.exports = MediaFile;
+
+});
+
+// file: lib/common/plugin/MediaFileData.js
+define("cordova/plugin/MediaFileData", function(require, exports, module) {
+/**
+ * MediaFileData encapsulates format information of a media file.
+ *
+ * @param {DOMString} codecs
+ * @param {long} bitrate
+ * @param {long} height
+ * @param {long} width
+ * @param {float} duration
+ */
+var MediaFileData = function(codecs, bitrate, height, width, duration){
+    this.codecs = codecs || null;
+    this.bitrate = bitrate || 0;
+    this.height = height || 0;
+    this.width = width || 0;
+    this.duration = duration || 0;
+};
+
+module.exports = MediaFileData;
+});
+
+// file: lib/common/plugin/Metadata.js
+define("cordova/plugin/Metadata", function(require, exports, module) {
+/**
+ * Information about the state of the file or directory
+ *
+ * {Date} modificationTime (readonly)
+ */
+var Metadata = function(time) {
+    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);
+};
+
+module.exports = Metadata;
+});
+
+// file: lib/common/plugin/Position.js
+define("cordova/plugin/Position", function(require, exports, module) {
+var Coordinates = require('cordova/plugin/Coordinates');
+
+var Position = function(coords, timestamp) {
+    if (coords) {
+        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);
+    } else {
+        this.coords = new Coordinates();
+    }
+    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();
+};
+
+module.exports = Position;
+
+});
+
+// file: lib/common/plugin/PositionError.js
+define("cordova/plugin/PositionError", function(require, exports, module) {
+/**
+ * Position error object
+ *
+ * @constructor
+ * @param code
+ * @param message
+ */
+var PositionError = function(code, message) {
+    this.code = code || null;
+    this.message = message || '';
+};
+
+PositionError.PERMISSION_DENIED = 1;
+PositionError.POSITION_UNAVAILABLE = 2;
+PositionError.TIMEOUT = 3;
+
+module.exports = PositionError;
+});
+
+// file: lib/common/plugin/ProgressEvent.js
+define("cordova/plugin/ProgressEvent", function(require, exports, module) {
+// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill
+// Feature test: See if we can instantiate a native ProgressEvent;
+// if so, use that approach,
+// otherwise fill-in with our own implementation.
+//
+// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.
+var ProgressEvent = (function() {
+    /*
+    var createEvent = function(data) {
+        var event = document.createEvent('Events');
+        event.initEvent('ProgressEvent', false, false);
+        if (data) {
+            for (var i in data) {
+                if (data.hasOwnProperty(i)) {
+                    event[i] = data[i];
+                }
+            }
+            if (data.target) {
+                // TODO: cannot call <some_custom_object>.dispatchEvent
+                // need to first figure out how to implement EventTarget
+            }
+        }
+        return event;
+    };
+    try {
+        var ev = createEvent({type:"abort",target:document});
+        return function ProgressEvent(type, data) {
+            data.type = type;
+            return createEvent(data);
+        };
+    } catch(e){
+    */
+        return function ProgressEvent(type, dict) {
+            this.type = type;
+            this.bubbles = false;
+            this.cancelBubble = false;
+            this.cancelable = false;
+            this.lengthComputable = false;
+            this.loaded = dict && dict.loaded ? dict.loaded : 0;
+            this.total = dict && dict.total ? dict.total : 0;
+            this.target = dict && dict.target ? dict.target : null;
+        };
+    //}
+})();
+
+module.exports = ProgressEvent;
+});
+
+// file: lib/common/plugin/accelerometer.js
+define("cordova/plugin/accelerometer", function(require, exports, module) {
+/**
+ * This class provides access to device accelerometer data.
+ * @constructor
+ */
+var utils = require("cordova/utils"),
+    exec = require("cordova/exec"),
+    Acceleration = require('cordova/plugin/Acceleration');
+
+// Is the accel sensor running?
+var running = false;
+
+// Keeps reference to watchAcceleration calls.
+var timers = {};
+
+// Array of listeners; used to keep track of when we should call start and stop.
+var listeners = [];
+
+// Last returned acceleration object from native
+var accel = null;
+
+// Tells native to start.
+function start() {
+    exec(function(a) {
+        var tempListeners = listeners.slice(0);
+        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].win(accel);
+        }
+    }, function(e) {
+        var tempListeners = listeners.slice(0);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].fail(e);
+        }
+    }, "Accelerometer", "start", []);
+    running = true;
+}
+
+// Tells native to stop.
+function stop() {
+    exec(null, null, "Accelerometer", "stop", []);
+    running = false;
+}
+
+// Adds a callback pair to the listeners array
+function createCallbackPair(win, fail) {
+    return {win:win, fail:fail};
+}
+
+// Removes a win/fail listener pair from the listeners array
+function removeListeners(l) {
+    var idx = listeners.indexOf(l);
+    if (idx > -1) {
+        listeners.splice(idx, 1);
+        if (listeners.length === 0) {
+            stop();
+        }
+    }
+}
+
+var accelerometer = {
+    /**
+     * Asynchronously aquires the current acceleration.
+     *
+     * @param {Function} successCallback    The function to call when the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     */
+    getCurrentAcceleration: function(successCallback, errorCallback, options) {
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "getCurrentAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        var p;
+        var win = function(a) {
+            removeListeners(p);
+            successCallback(a);
+        };
+        var fail = function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        };
+
+        p = createCallbackPair(win, fail);
+        listeners.push(p);
+
+        if (!running) {
+            start();
+        }
+    },
+
+    /**
+     * Asynchronously aquires the acceleration repeatedly at a given interval.
+     *
+     * @param {Function} successCallback    The function to call each time the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchAcceleration: function(successCallback, errorCallback, options) {
+        // Default interval (10 sec)
+        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;
+
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "watchAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        // Keep reference to watch id, and report accel readings as often as defined in frequency
+        var id = utils.createUUID();
+
+        var p = createCallbackPair(function(){}, function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        });
+        listeners.push(p);
+
+        timers[id] = {
+            timer:window.setInterval(function() {
+                if (accel) {
+                    successCallback(accel);
+                }
+            }, frequency),
+            listeners:p
+        };
+
+        if (running) {
+            // If we're already running then immediately invoke the success callback
+            // but only if we have retreived a value, sample code does not check for null ...
+            if(accel) {
+                successCallback(accel);
+            }
+        } else {
+            start();
+        }
+
+        return id;
+    },
+
+    /**
+     * Clears the specified accelerometer watch.
+     *
+     * @param {String} id       The id of the watch returned from #watchAcceleration.
+     */
+    clearWatch: function(id) {
+        // Stop javascript timer & remove from timer list
+        if (id && timers[id]) {
+            window.clearInterval(timers[id].timer);
+            removeListeners(timers[id].listeners);
+            delete timers[id];
+        }
+    }
+};
+
+module.exports = accelerometer;
+
+});
+
+// file: lib/common/plugin/battery.js
+define("cordova/plugin/battery", function(require, exports, module) {
+/**
+ * This class contains information about the current battery status.
+ * @constructor
+ */
+var cordova = require('cordova'),
+    exec = require('cordova/exec');
+
+function handlers() {
+  return battery.channels.batterystatus.numHandlers +
+         battery.channels.batterylow.numHandlers +
+         battery.channels.batterycritical.numHandlers;
+}
+
+var Battery = function() {
+    this._level = null;
+    this._isPlugged = null;
+    // Create new event handlers on the window (returns a channel instance)
+    var subscriptionEvents = {
+      onSubscribe:this.onSubscribe,
+      onUnsubscribe:this.onUnsubscribe
+    };
+    this.channels = {
+      batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents),
+      batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents),
+      batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents)
+    };
+};
+/**
+ * Event handlers for when callbacks get registered for the battery.
+ * Keep track of how many handlers we have so we can start and stop the native battery listener
+ * appropriately (and hopefully save on battery life!).
+ */
+Battery.prototype.onSubscribe = function() {
+  var me = battery;
+  // If we just registered the first handler, make sure native listener is started.
+  if (handlers() === 1) {
+    exec(me._status, me._error, "Battery", "start", []);
+  }
+};
+
+Battery.prototype.onUnsubscribe = function() {
+  var me = battery;
+
+  // If we just unregistered the last handler, make sure native listener is stopped.
+  if (handlers() === 0) {
+      exec(null, null, "Battery", "stop", []);
+  }
+};
+
+/**
+ * Callback for battery status
+ *
+ * @param {Object} info            keys: level, isPlugged
+ */
+Battery.prototype._status = function(info) {
+    if (info) {
+        var me = battery;
+    var level = info.level;
+        if (me._level !== level || me._isPlugged !== info.isPlugged) {
+            // Fire batterystatus event
+            cordova.fireWindowEvent("batterystatus", info);
+
+            // Fire low battery event
+            if (level === 20 || level === 5) {
+                if (level === 20) {
+                    cordova.fireWindowEvent("batterylow", info);
+                }
+                else {
+                    cordova.fireWindowEvent("batterycritical", info);
+                }
+            }
+        }
+        me._level = level;
+        me._isPlugged = info.isPlugged;
+    }
+};
+
+/**
+ * Error callback for battery start
+ */
+Battery.prototype._error = function(e) {
+    console.log("Error initializing Battery: " + e);
+};
+
+var battery = new Battery();
+
+module.exports = battery;
+});
+
+// file: lib/common/plugin/capture.js
+define("cordova/plugin/capture", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    MediaFile = require('cordova/plugin/MediaFile');
+
+/**
+ * Launches a capture of different types.
+ *
+ * @param (DOMString} type
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+function _capture(type, successCallback, errorCallback, options) {
+    var win = function(pluginResult) {
+        var mediaFiles = [];
+        var i;
+        for (i = 0; i < pluginResult.length; i++) {
+            var mediaFile = new MediaFile();
+            mediaFile.name = pluginResult[i].name;
+            mediaFile.fullPath = pluginResult[i].fullPath;
+            mediaFile.type = pluginResult[i].type;
+            mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;
+            mediaFile.size = pluginResult[i].size;
+            mediaFiles.push(mediaFile);
+        }
+        successCallback(mediaFiles);
+    };
+    exec(win, errorCallback, "Capture", type, [options]);
+}
+/**
+ * The Capture interface exposes an interface to the camera and microphone of the hosting device.
+ */
+function Capture() {
+    this.supportedAudioModes = [];
+    this.supportedImageModes = [];
+    this.supportedVideoModes = [];
+}
+
+/**
+ * Launch audio recorder application for recording audio clip(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureAudioOptions} options
+ */
+Capture.prototype.captureAudio = function(successCallback, errorCallback, options){
+    _capture("captureAudio", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch camera application for taking image(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureImageOptions} options
+ */
+Capture.prototype.captureImage = function(successCallback, errorCallback, options){
+    _capture("captureImage", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch device camera application for recording video(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+Capture.prototype.captureVideo = function(successCallback, errorCallback, options){
+    _capture("captureVideo", successCallback, errorCallback, options);
+};
+
+
+module.exports = new Capture();
+
+});
+
+// file: lib/common/plugin/compass.js
+define("cordova/plugin/compass", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    utils = require('cordova/utils'),
+    CompassHeading = require('cordova/plugin/CompassHeading'),
+    CompassError = require('cordova/plugin/CompassError'),
+    timers = {},
+    compass = {
+        /**
+         * Asynchronously acquires the current heading.
+         * @param {Function} successCallback The function to call when the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {CompassOptions} options The options for getting the heading data (not used).
+         */
+        getCurrentHeading:function(successCallback, errorCallback, options) {
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var win = function(result) {
+                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);
+                successCallback(ch);
+            };
+            var fail = function(code) {
+                var ce = new CompassError(code);
+                errorCallback(ce);
+            };
+
+            // Get heading
+            exec(win, fail, "Compass", "getHeading", [options]);
+        },
+
+        /**
+         * Asynchronously acquires the heading repeatedly at a given interval.
+         * @param {Function} successCallback The function to call each time the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {HeadingOptions} options The options for getting the heading data
+         * such as timeout and the frequency of the watch. For iOS, filter parameter
+         * specifies to watch via a distance filter rather than time.
+         */
+        watchHeading:function(successCallback, errorCallback, options) {
+            // Default interval (100 msec)
+            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;
+            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;
+
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var id = utils.createUUID();
+            if (filter > 0) {
+                // is an iOS request for watch by filter, no timer needed
+                timers[id] = "iOS";
+                compass.getCurrentHeading(successCallback, errorCallback, options);
+            } else {
+                // Start watch timer to get headings
+                timers[id] = window.setInterval(function() {
+                    compass.getCurrentHeading(successCallback, errorCallback);
+                }, frequency);
+            }
+
+            return id;
+        },
+
+        /**
+         * Clears the specified heading watch.
+         * @param {String} watchId The ID of the watch returned from #watchHeading.
+         */
+        clearWatch:function(id) {
+            // Stop javascript timer & remove from timer list
+            if (id && timers[id]) {
+                if (timers[id] != "iOS") {
+                      clearInterval(timers[id]);
+                  } else {
+                    // is iOS watch by filter so call into device to stop
+                    exec(null, null, "Compass", "stopHeading", []);
+                }
+                delete timers[id];
+            }
+        }
+    };
+
+module.exports = compass;
+});
+
+// file: lib/common/plugin/console-via-logger.js
+define("cordova/plugin/console-via-logger", function(require, exports, module) {
+//------------------------------------------------------------------------------
+
+var logger = require("cordova/plugin/logger");
+var utils  = require("cordova/utils");
+
+//------------------------------------------------------------------------------
+// object that we're exporting
+//------------------------------------------------------------------------------
+var console = module.exports;
+
+//------------------------------------------------------------------------------
+// copy of the original console object
+//------------------------------------------------------------------------------
+var WinConsole = window.console;
+
+//------------------------------------------------------------------------------
+// whether to use the logger
+//------------------------------------------------------------------------------
+var UseLogger = false;
+
+//------------------------------------------------------------------------------
+// Timers
+//------------------------------------------------------------------------------
+var Timers = {};
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+function noop() {}
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+console.useLogger = function (value) {
+    if (arguments.length) UseLogger = !!value;
+
+    if (UseLogger) {
+        if (logger.useConsole()) {
+            throw new Error("console and logger are too intertwingly");
+        }
+    }
+
+    return UseLogger;
+};
+
+//------------------------------------------------------------------------------
+console.log = function() {
+    if (logger.useConsole()) return;
+    logger.log.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.error = function() {
+    if (logger.useConsole()) return;
+    logger.error.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.warn = function() {
+    if (logger.useConsole()) return;
+    logger.warn.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.info = function() {
+    if (logger.useConsole()) return;
+    logger.info.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.debug = function() {
+    if (logger.useConsole()) return;
+    logger.debug.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.assert = function(expression) {
+    if (expression) return;
+
+    var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));
+    console.log("ASSERT: " + message);
+};
+
+//------------------------------------------------------------------------------
+console.clear = function() {};
+
+//------------------------------------------------------------------------------
+console.dir = function(object) {
+    console.log("%o", object);
+};
+
+//------------------------------------------------------------------------------
+console.dirxml = function(node) {
+    console.log(node.innerHTML);
+};
+
+//------------------------------------------------------------------------------
+console.trace = noop;
+
+//------------------------------------------------------------------------------
+console.group = console.log;
+
+//------------------------------------------------------------------------------
+console.groupCollapsed = console.log;
+
+//------------------------------------------------------------------------------
+console.groupEnd = noop;
+
+//------------------------------------------------------------------------------
+console.time = function(name) {
+    Timers[name] = new Date().valueOf();
+};
+
+//------------------------------------------------------------------------------
+console.timeEnd = function(name) {
+    var timeStart = Timers[name];
+    if (!timeStart) {
+        console.warn("unknown timer: " + name);
+        return;
+    }
+
+    var timeElapsed = new Date().valueOf() - timeStart;
+    console.log(name + ": " + timeElapsed + "ms");
+};
+
+//------------------------------------------------------------------------------
+console.timeStamp = noop;
+
+//------------------------------------------------------------------------------
+console.profile = noop;
+
+//------------------------------------------------------------------------------
+console.profileEnd = noop;
+
+//------------------------------------------------------------------------------
+console.count = noop;
+
+//------------------------------------------------------------------------------
+console.exception = console.log;
+
+//------------------------------------------------------------------------------
+console.table = function(data, columns) {
+    console.log("%o", data);
+};
+
+//------------------------------------------------------------------------------
+// return a new function that calls both functions passed as args
+//------------------------------------------------------------------------------
+function wrapperedOrigCall(orgFunc, newFunc) {
+    return function() {
+        var args = [].slice.call(arguments);
+        try { orgFunc.apply(WinConsole, args); } catch (e) {}
+        try { newFunc.apply(console,    args); } catch (e) {}
+    };
+}
+
+//------------------------------------------------------------------------------
+// For every function that exists in the original console object, that
+// also exists in the new console object, wrap the new console method
+// with one that calls both
+//------------------------------------------------------------------------------
+for (var key in console) {
+    if (typeof WinConsole[key] == "function") {
+        console[key] = wrapperedOrigCall(WinConsole[key], console[key]);
+    }
+}
+
+});
+
+// file: lib/common/plugin/contacts.js
+define("cordova/plugin/contacts", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+* Represents a group of Contacts.
+* @constructor
+*/
+var contacts = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     * @param fields that should be searched
+     * @param successCB success callback
+     * @param errorCB error callback
+     * @param {ContactFindOptions} options that can be applied to contact searching
+     * @return array of Contacts matching search criteria
+     */
+    find:function(fields, successCB, errorCB, options) {
+        if (!successCB) {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+        if (!fields || (utils.isArray(fields) && fields.length === 0)) {
+            if (typeof errorCB === "function") {
+                errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+        } else {
+            var win = function(result) {
+                var cs = [];
+                for (var i = 0, l = result.length; i < l; i++) {
+                    cs.push(contacts.create(result[i]));
+                }
+                successCB(cs);
+            };
+            exec(win, errorCB, "Contacts", "search", [fields, options]);
+        }
+    },
+
+    /**
+     * This function creates a new contact, but it does not persist the contact
+     * to device storage. To persist the contact to device storage, invoke
+     * contact.save().
+     * @param properties an object who's properties will be examined to create a new Contact
+     * @returns new Contact object
+     */
+    create:function(properties) {
+        var i;
+        var contact = new Contact();
+        for (i in properties) {
+            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {
+                contact[i] = properties[i];
+            }
+        }
+        return contact;
+    }
+};
+
+module.exports = contacts;
+
+});
+
+// file: lib/common/plugin/device.js
+define("cordova/plugin/device", function(require, exports, module) {
+var channel = require('cordova/channel'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+/**
+ * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+function Device() {
+    this.available = false;
+    this.platform = null;
+    this.version = null;
+    this.name = null;
+    this.uuid = null;
+    this.cordova = null;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getInfo(function(info) {
+            me.available = true;
+            me.platform = info.platform;
+            me.version = info.version;
+            me.name = info.name;
+            me.uuid = info.uuid;
+            me.cordova = info.cordova;
+            channel.onCordovaInfoReady.fire();
+        },function(e) {
+            me.available = false;
+            utils.alert("[ERROR] Error initializing Cordova: " + e);
+        });
+    });
+}
+
+/**
+ * Get device info
+ *
+ * @param {Function} successCallback The function to call when the heading data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
+ */
+Device.prototype.getInfo = function(successCallback, errorCallback) {
+
+    // successCallback required
+    if (typeof successCallback !== "function") {
+        console.log("Device Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Device Error: errorCallback is not a function");
+        return;
+    }
+
+    // Get info
+    exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
+};
+
+module.exports = new Device();
+
+});
+
+// file: lib/common/plugin/geolocation.js
+define("cordova/plugin/geolocation", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    PositionError = require('cordova/plugin/PositionError'),
+    Position = require('cordova/plugin/Position');
+
+var timers = {};   // list of timers in use
+
+// Returns default params, overrides if provided with values
+function parseParameters(options) {
+    var opt = {
+        maximumAge: 0,
+        enableHighAccuracy: false,
+        timeout: Infinity
+    };
+
+    if (options) {
+        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {
+            opt.maximumAge = options.maximumAge;
+        }
+        if (options.enableHighAccuracy !== undefined) {
+            opt.enableHighAccuracy = options.enableHighAccuracy;
+        }
+        if (options.timeout !== undefined && !isNaN(options.timeout)) {
+            if (options.timeout < 0) {
+                opt.timeout = 0;
+            } else {
+                opt.timeout = options.timeout;
+            }
+        }
+    }
+
+    return opt;
+}
+
+// Returns a timeout failure, closed over a specified timeout value and error callback.
+function createTimeout(errorCallback, timeout) {
+    var t = setTimeout(function() {
+        clearTimeout(t);
+        t = null;
+        errorCallback({
+            code:PositionError.TIMEOUT,
+            message:"Position retrieval timed out."
+        });
+    }, timeout);
+    return t;
+}
+
+var geolocation = {
+    lastPosition:null, // reference to last known (cached) position returned
+    /**
+   * Asynchronously aquires the current position.
+   *
+   * @param {Function} successCallback    The function to call when the position data is available
+   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)
+   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)
+   */
+    getCurrentPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("getCurrentPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        // Timer var that will fire an error callback if no position is retrieved from native
+        // before the "timeout" param provided expires
+        var timeoutTimer = null;
+
+        var win = function(p) {
+            clearTimeout(timeoutTimer);
+            if (!timeoutTimer) {
+                // Timeout already happened, or native fired error callback for
+                // this geo request.
+                // Don't continue with success callback.
+                return;
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+        var fail = function(e) {
+            clearTimeout(timeoutTimer);
+            timeoutTimer = null;
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just
+        // fire the success callback with the cached position.
+        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {
+            successCallback(geolocation.lastPosition);
+        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.
+        } else if (options.timeout === 0) {
+            fail({
+                code:PositionError.TIMEOUT,
+                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter."
+            });
+        // Otherwise we have to call into native to retrieve a position.
+        } else {
+            if (options.timeout !== Infinity) {
+                // If the timeout value was not set to Infinity (default), then
+                // set up a timeout function that will fire the error callback
+                // if no successful position was retrieved before timeout expired.
+                timeoutTimer = createTimeout(fail, options.timeout);
+            } else {
+                // This is here so the check in the win function doesn't mess stuff up
+                // may seem weird but this guarantees timeoutTimer is
+                // always truthy before we call into native
+                timeoutTimer = true;
+            }
+            exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);
+        }
+        return timeoutTimer;
+    },
+    /**
+     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,
+     * the successCallback is called with the new location.
+     *
+     * @param {Function} successCallback    The function to call each time the location data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)
+     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("watchPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        var id = utils.createUUID();
+
+        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition
+        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);
+
+        var fail = function(e) {
+            clearTimeout(timers[id]);
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        var win = function(p) {
+            clearTimeout(timers[id]);
+            if (options.timeout !== Infinity) {
+                timers[id] = createTimeout(fail, options.timeout);
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+
+        exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);
+
+        return id;
+    },
+    /**
+     * Clears the specified heading watch.
+     *
+     * @param {String} id       The ID of the watch returned from #watchPosition
+     */
+    clearWatch:function(id) {
+        if (id && timers[id] !== undefined) {
+            clearTimeout(timers[id]);
+            delete timers[id];
+            exec(null, null, "Geolocation", "clearWatch", [id]);
+        }
+    }
+};
+
+module.exports = geolocation;
+
+});
+
+// file: lib/common/plugin/logger.js
+define("cordova/plugin/logger", function(require, exports, module) {
+//------------------------------------------------------------------------------
+// The logger module exports the following properties/functions:
+//
+// LOG                          - constant for the level LOG
+// ERROR                        - constant for the level ERROR
+// WARN                         - constant for the level WARN
+// INFO                         - constant for the level INFO
+// DEBUG                        - constant for the level DEBUG
+// logLevel()                   - returns current log level
+// logLevel(value)              - sets and returns a new log level
+// useConsole()                 - returns whether logger is using console
+// useConsole(value)            - sets and returns whether logger is using console
+// log(message,...)             - logs a message at level LOG
+// error(message,...)           - logs a message at level ERROR
+// warn(message,...)            - logs a message at level WARN
+// info(message,...)            - logs a message at level INFO
+// debug(message,...)           - logs a message at level DEBUG
+// logLevel(level,message,...)  - logs a message specified level
+//
+//------------------------------------------------------------------------------
+
+var logger = exports;
+
+var exec    = require('cordova/exec');
+var utils   = require('cordova/utils');
+
+var UseConsole   = true;
+var Queued       = [];
+var DeviceReady  = false;
+var CurrentLevel;
+
+/**
+ * Logging levels
+ */
+
+var Levels = [
+    "LOG",
+    "ERROR",
+    "WARN",
+    "INFO",
+    "DEBUG"
+];
+
+/*
+ * add the logging levels to the logger object and
+ * to a separate levelsMap object for testing
+ */
+
+var LevelsMap = {};
+for (var i=0; i<Levels.length; i++) {
+    var level = Levels[i];
+    LevelsMap[level] = i;
+    logger[level]    = level;
+}
+
+CurrentLevel = LevelsMap.WARN;
+
+/**
+ * Getter/Setter for the logging level
+ *
+ * Returns the current logging level.
+ *
+ * When a value is passed, sets the logging level to that value.
+ * The values should be one of the following constants:
+ *    logger.LOG
+ *    logger.ERROR
+ *    logger.WARN
+ *    logger.INFO
+ *    logger.DEBUG
+ *
+ * The value used determines which messages get printed.  The logging
+ * values above are in order, and only messages logged at the logging
+ * level or above will actually be displayed to the user.  Eg, the
+ * default level is WARN, so only messages logged with LOG, ERROR, or
+ * WARN will be displayed; INFO and DEBUG messages will be ignored.
+ */
+logger.level = function (value) {
+    if (arguments.length) {
+        if (LevelsMap[value] === null) {
+            throw new Error("invalid logging level: " + value);
+        }
+        CurrentLevel = LevelsMap[value];
+    }
+
+    return Levels[CurrentLevel];
+};
+
+/**
+ * Getter/Setter for the useConsole functionality
+ *
+ * When useConsole is true, the logger will log via the
+ * browser 'console' object.  Otherwise, it will use the
+ * native Logger plugin.
+ */
+logger.useConsole = function (value) {
+    if (arguments.length) UseConsole = !!value;
+
+    if (UseConsole) {
+        if (typeof console == "undefined") {
+            throw new Error("global console object is not defined");
+        }
+
+        if (typeof console.log != "function") {
+            throw new Error("global console object does not have a log function");
+        }
+
+        if (typeof console.useLogger == "function") {
+            if (console.useLogger()) {
+                throw new Error("console and logger are too intertwingly");
+            }
+        }
+    }
+
+    return UseConsole;
+};
+
+/**
+ * Logs a message at the LOG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.log   = function(message) { logWithArgs("LOG",   arguments); };
+
+/**
+ * Logs a message at the ERROR level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.error = function(message) { logWithArgs("ERROR", arguments); };
+
+/**
+ * Logs a message at the WARN level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.warn  = function(message) { logWithArgs("WARN",  arguments); };
+
+/**
+ * Logs a message at the INFO level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.info  = function(message) { logWithArgs("INFO",  arguments); };
+
+/**
+ * Logs a message at the DEBUG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.debug = function(message) { logWithArgs("DEBUG", arguments); };
+
+// log at the specified level with args
+function logWithArgs(level, args) {
+    args = [level].concat([].slice.call(args));
+    logger.logLevel.apply(logger, args);
+}
+
+/**
+ * Logs a message at the specified level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.logLevel = function(level, message /* , ... */) {
+    // format the message with the parameters
+    var formatArgs = [].slice.call(arguments, 2);
+    message    = utils.vformat(message, formatArgs);
+
+    if (LevelsMap[level] === null) {
+        throw new Error("invalid logging level: " + level);
+    }
+
+    if (LevelsMap[level] > CurrentLevel) return;
+
+    // queue the message if not yet at deviceready
+    if (!DeviceReady && !UseConsole) {
+        Queued.push([level, message]);
+        return;
+    }
+
+    // if not using the console, use the native logger
+    if (!UseConsole) {
+        exec(null, null, "Logger", "logLevel", [level, message]);
+        return;
+    }
+
+    // make sure console is not using logger
+    if (console.__usingCordovaLogger) {
+        throw new Error("console and logger are too intertwingly");
+    }
+
+    // log to the console
+    switch (level) {
+        case logger.LOG:   console.log(message); break;
+        case logger.ERROR: console.log("ERROR: " + message); break;
+        case logger.WARN:  console.log("WARN: "  + message); break;
+        case logger.INFO:  console.log("INFO: "  + message); break;
+        case logger.DEBUG: console.log("DEBUG: " + message); break;
+    }
+};
+
+// when deviceready fires, log queued messages
+logger.__onDeviceReady = function() {
+    if (DeviceReady) return;
+
+    DeviceReady = true;
+
+    for (var i=0; i<Queued.length; i++) {
+        var messageArgs = Queued[i];
+        logger.logLevel(messageArgs[0], messageArgs[1]);
+    }
+
+    Queued = null;
+};
+
+// add a deviceready event to log queued messages
+document.addEventListener("deviceready", logger.__onDeviceReady, false);
+
+});
+
+// file: lib/common/plugin/network.js
+define("cordova/plugin/network", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    cordova = require('cordova'),
+    channel = require('cordova/channel');
+
+var NetworkConnection = function () {
+    this.type = null;
+    this._firstRun = true;
+    this._timer = null;
+    this.timeout = 500;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getInfo(function (info) {
+            me.type = info;
+            if (info === "none") {
+                // set a timer if still offline at the end of timer send the offline event
+                me._timer = setTimeout(function(){
+                    cordova.fireDocumentEvent("offline");
+                    me._timer = null;
+                    }, me.timeout);
+            } else {
+                // If there is a current offline event pending clear it
+                if (me._timer !== null) {
+                    clearTimeout(me._timer);
+                    me._timer = null;
+                }
+                cordova.fireDocumentEvent("online");
+            }
+
+            // should only fire this once
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+        },
+        function (e) {
+            // If we can't get the network info we should still tell Cordova
+            // to fire the deviceready event.
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+            console.log("Error initializing Network Connection: " + e);
+        });
+    });
+};
+
+/**
+ * Get connection info
+ *
+ * @param {Function} successCallback The function to call when the Connection data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)
+ */
+NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) {
+    // Get info
+    exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []);
+};
+
+module.exports = new NetworkConnection();
+});
+
+// file: lib/common/plugin/notification.js
+define("cordova/plugin/notification", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+/**
+ * Provides access to notifications on the device.
+ */
+
+module.exports = {
+
+    /**
+     * Open a native alert dialog, with a customizable title and button text.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} completeCallback   The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Alert)
+     * @param {String} buttonLabel          Label of the close button (default: OK)
+     */
+    alert: function(message, completeCallback, title, buttonLabel) {
+        var _title = (title || "Alert");
+        var _buttonLabel = (buttonLabel || "OK");
+        exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]);
+    },
+
+    /**
+     * Open a native confirm dialog, with a customizable title and button text.
+     * The result that the user selects is returned to the result callback.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Confirm)
+     * @param {String} buttonLabels         Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+     */
+    confirm: function(message, resultCallback, title, buttonLabels) {
+        var _title = (title || "Confirm");
+        var _buttonLabels = (buttonLabels || "OK,Cancel");
+        exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
+    },
+
+    /**
+     * Causes the device to vibrate.
+     *
+     * @param {Integer} mills       The number of milliseconds to vibrate for.
+     */
+    vibrate: function(mills) {
+        exec(null, null, "Notification", "vibrate", [mills]);
+    },
+
+    /**
+     * Causes the device to beep.
+     * On Android, the default notification ringtone is played "count" times.
+     *
+     * @param {Integer} count       The number of beeps.
+     */
+    beep: function(count) {
+        exec(null, null, "Notification", "beep", [count]);
+    }
+};
+});
+
+// file: lib/common/plugin/requestFileSystem.js
+define("cordova/plugin/requestFileSystem", function(require, exports, module) {
+var FileError = require('cordova/plugin/FileError'),
+    FileSystem = require('cordova/plugin/FileSystem'),
+    exec = require('cordova/exec');
+
+/**
+ * Request a file system in which to store application data.
+ * @param type  local file system type
+ * @param size  indicates how much storage space, in bytes, the application expects to need
+ * @param successCallback  invoked with a FileSystem object
+ * @param errorCallback  invoked if error occurs retrieving file system
+ */
+var requestFileSystem = function(type, size, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    if (type < 0 || type > 3) {
+        fail(FileError.SYNTAX_ERR);
+    } else {
+        // if successful, return a FileSystem object
+        var success = function(file_system) {
+            if (file_system) {
+                if (typeof successCallback === 'function') {
+                    // grab the name and root from the file system object
+                    var result = new FileSystem(file_system.name, file_system.root);
+                    successCallback(result);
+                }
+            }
+            else {
+                // no FileSystem object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+        exec(success, fail, "File", "requestFileSystem", [type, size]);
+    }
+};
+
+module.exports = requestFileSystem;
+});
+
+// file: lib/common/plugin/resolveLocalFileSystemURI.js
+define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) {
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    FileError = require('cordova/plugin/FileError'),
+    exec = require('cordova/exec');
+
+/**
+ * Look up file system Entry referred to by local URI.
+ * @param {DOMString} uri  URI referring to a local file or directory
+ * @param successCallback  invoked with Entry object corresponding to URI
+ * @param errorCallback    invoked if error occurs retrieving file system entry
+ */
+module.exports = function(uri, successCallback, errorCallback) {
+    // error callback
+    var fail = function(error) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(error));
+        }
+    };
+    // sanity check for 'not:valid:filename'
+    if(!uri || uri.split(":").length > 2) {
+        setTimeout( function() {
+            fail(FileError.ENCODING_ERR);
+        },0);
+        return;
+    }
+    // if successful, return either a file or directory entry
+    var success = function(entry) {
+        var result;
+        if (entry) {
+            if (typeof successCallback === 'function') {
+                // create appropriate Entry object
+                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);
+                try {
+                    successCallback(result);
+                }
+                catch (e) {
+                    console.log('Error invoking callback: ' + e);
+                }
+            }
+        }
+        else {
+            // no Entry object returned
+            fail(FileError.NOT_FOUND_ERR);
+        }
+    };
+
+    exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
+};
+
+});
+
+// file: lib/common/plugin/splashscreen.js
+define("cordova/plugin/splashscreen", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+var splashscreen = {
+    show:function() {
+        exec(null, null, "SplashScreen", "show", []);
+    },
+    hide:function() {
+        exec(null, null, "SplashScreen", "hide", []);
+    }
+};
+
+module.exports = splashscreen;
+});
+
+// file: lib/tizen/plugin/tizen/Accelerometer.js
+define("cordova/plugin/tizen/Accelerometer", function(require, exports, module) {
+var callback = null;
+
+module.exports = {
+    start: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+        callback = function (motion) {
+            successCallback({
+                x: motion.accelerationIncludingGravity.x,
+                y: motion.accelerationIncludingGravity.y,
+                z: motion.accelerationIncludingGravity.z,
+                timestamp: motion.timeStamp
+            });
+        };
+        window.addEventListener("devicemotion", callback);
+    },
+    stop: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+    }
+};
+});
+
+// file: lib/tizen/plugin/tizen/Battery.js
+define("cordova/plugin/tizen/Battery", function(require, exports, module) {
+/*global tizen:false */
+var id = null;
+
+module.exports = {
+    start: function(successCallback, errorCallback) {
+        var tizenSuccessCallback = function(power) {
+            if (successCallback) {
+                successCallback({level: Math.round(power.level * 100), isPlugged: power.isCharging});
+            }
+        };
+
+        if (id === null) {
+            id = tizen.systeminfo.addPropertyValueChangeListener("Power", tizenSuccessCallback);
+        }
+        tizen.systeminfo.getPropertyValue("Power", tizenSuccessCallback, errorCallback);
+    },
+
+    stop: function(successCallback, errorCallback) {
+        tizen.systeminfo.removePropertyValueChangeListener(id);
+        id = null;
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/BufferLoader.js
+define("cordova/plugin/tizen/BufferLoader", function(require, exports, module) {
+/*
+ * Buffer Loader Object
+ * This class provides a sound buffer for one or more sounds
+ * holded in a local file located by an url
+ *
+ * uses W3C  Web Audio API
+ *
+ * @constructor
+ *
+ * @param {AudioContext} audio context object
+ * @param {Array} urlList, array of url for sound to load
+ * @param {function} callback , called after buffer was loaded
+ *
+ */
+
+function BufferLoader(context, urlList, callback) {
+    this.context = context;
+    this.urlList = urlList;
+    this.onload = callback;
+    this.bufferList = [];
+    this.loadCount = 0;
+}
+
+/*
+ * This method loads a sound into a buffer
+ * @param {Array} urlList, array of url for sound to load
+ * @param {Number} index, buffer index in the array where to load the url sound
+ *
+ */
+
+BufferLoader.prototype.loadBuffer = function(url, index) {
+    // Load buffer asynchronously
+    var request = null,
+        loader = null;
+
+    request = new XMLHttpRequest();
+
+    if (request === null) {
+        console.log ("BufferLoader.prototype.loadBuffer, cannot allocate XML http request");
+        return;
+    }
+
+    request.open("GET", url, true);
+    request.responseType = "arraybuffer";
+
+    loader = this;
+
+    request.onload = function() {
+    // Asynchronously decode the audio file data in request.response
+    loader.context.decodeAudioData(
+        request.response,
+        function(buffer) {
+                if (!buffer) {
+                    console.log ("BufferLoader.prototype.loadBuffer,error decoding file data: " + url);
+                    return;
+                }
+
+                loader.bufferList[index] = buffer;
+
+                if (++loader.loadCount == loader.urlList.length) {
+                    loader.onload(loader.bufferList);
+                }
+            }
+        );
+    };
+
+    request.onerror = function() {
+        console.log ("BufferLoader.prototype.loadBuffer, XHR error");
+    };
+
+    request.send();
+};
+
+/*
+ * This method loads all sounds identified by their url
+ * and that where given to the object constructor
+ *
+ */
+
+BufferLoader.prototype.load = function() {
+    for (var i = 0; i < this.urlList.length; ++i) {
+        this.loadBuffer(this.urlList[i], i);
+    }
+};
+
+module.exports = BufferLoader;
+
+});
+
+// file: lib/tizen/plugin/tizen/Camera.js
+define("cordova/plugin/tizen/Camera", function(require, exports, module) {
+/*global tizen:false */
+var Camera = require('cordova/plugin/CameraConstants');
+
+function makeReplyCallback(successCallback, errorCallback) {
+    return {
+        onsuccess: function(reply) {
+            if (reply.length > 0) {
+                successCallback(reply[0].value);
+            } else {
+                errorCallback('Picture selection aborted');
+            }
+        },
+        onfail: function() {
+           console.log('The service launch failed');
+        }
+    };
+}
+
+module.exports = {
+    takePicture: function(successCallback, errorCallback, args) {
+        var destinationType = args[1],
+            sourceType = args[2],
+            encodingType = args[5],
+            mediaType = args[6];
+            // Not supported
+            /*
+            quality = args[0]
+            targetWidth = args[3]
+            targetHeight = args[4]
+            allowEdit = args[7]
+            correctOrientation = args[8]
+            saveToPhotoAlbum = args[9]
+            */
+
+        if (destinationType !== Camera.DestinationType.FILE_URI) {
+            errorCallback('DestinationType not supported');
+            return;
+        }
+        if (mediaType !== Camera.MediaType.PICTURE) {
+            errorCallback('MediaType not supported');
+            return;
+        }
+
+        var mimeType;
+        if (encodingType === Camera.EncodingType.JPEG) {
+            mimeType = 'image/jpeg';
+        } else if (encodingType === Camera.EncodingType.PNG) {
+            mimeType = 'image/png';
+        } else {
+            mimeType = 'image/*';
+        }
+
+        var serviceId;
+        if (sourceType === Camera.PictureSourceType.CAMERA) {
+            serviceId = 'http://tizen.org/appsvc/operation/create_content';
+        } else {
+            serviceId = 'http://tizen.org/appsvc/operation/pick';
+        }
+
+        var service = new tizen.ApplicationService(serviceId, null, mimeType, null);
+        tizen.application.launchService(service, null, null,
+                function(error) { errorCallback(error.message); },
+                makeReplyCallback(successCallback, errorCallback));
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Compass.js
+define("cordova/plugin/tizen/Compass", function(require, exports, module) {
+var CompassError = require('cordova/plugin/CompassError'),
+    callback = null, ready = false;
+
+module.exports = {
+    getHeading: function(successCallback, errorCallback) {
+        if (window.DeviceOrientationEvent !== undefined) {
+            callback = function (orientation) {
+                var heading = 360 - orientation.alpha;
+                if (ready) {
+                    successCallback({
+                        magneticHeading: heading,
+                        trueHeading: heading,
+                        headingAccuracy: 0,
+                        timestamp: orientation.timeStamp
+                    });
+                    window.removeEventListener("deviceorientation", callback);
+                }
+                ready = true;
+            };
+            ready = false; // workaround invalid first event value returned by WRT
+            window.addEventListener("deviceorientation", callback);
+        }
+        else {
+            errorCallback(CompassError.COMPASS_NOT_SUPPORTED);
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Contact.js
+define("cordova/plugin/tizen/Contact", function(require, exports, module) {
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// ------------------
+// Utility functions
+// ------------------
+
+
+/**
+ * Retrieves a Tizen Contact object from the device by its unique id.
+ *
+ * @param uid
+ *            Unique id of the contact on the device
+ * @return {tizen.Contact} Tizen Contact object or null if contact with
+ *         specified id is not found
+ */
+var findByUniqueId = function(id) {
+
+    if (!id) {
+        return null;
+    }
+
+    var tizenContact = null;
+
+    tizen.contact.getDefaultAddressBook().find(
+        function _successCallback(contacts){
+            tizenContact = contacts[0];
+        },
+        function _errorCallback(error){
+            console.log("tizen find error " + error);
+        },
+        new tizen.AttributeFilter('id', 'CONTAINS', id),
+        new tizen.SortMode('id', 'ASC'));
+
+    return tizenContact || null;
+};
+
+
+var traceTizenContact = function (tizenContact) {
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.id " + tizenContact.id);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.lastUpdated " + tizenContact.lastUpdated);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.name " + tizenContact.name);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.account " + tizenContact.account);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.addresses " + tizenContact.addresses);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.photoURI " + tizenContact.photoURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.phoneNumbers " + tizenContact.phoneNumbers);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.emails " + tizenContact.emails);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.birthday " + tizenContact.birthday);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.organization " + tizenContact.organization);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.notes " + tizenContact.notes);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.urls " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.isFavorite " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.ringtonesURI " + tizenContact.ringtonesURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.categories " + tizenContact.categories);
+};
+
+
+/**
+ * Creates a Tizen contact object from the W3C Contact object and persists
+ * it to device storage.
+ *
+ * @param {Contact}
+ *            contact The contact to save
+ * @return a new contact object with all properties set
+ */
+var saveToDevice = function(contact) {
+
+    if (!contact) {
+        return;
+    }
+
+    var tizenContact = null;
+    var update = false;
+    var i = 0;
+
+    // if the underlying Tizen Contact object already exists, retrieve it for
+    // update
+    if (contact.id) {
+        // we must attempt to retrieve the BlackBerry contact from the device
+        // because this may be an update operation
+        tizenContact = findByUniqueId(contact.id);
+    }
+
+    // contact not found on device, create a new one
+    if (!tizenContact) {
+        tizenContact = new tizen.Contact();
+    }
+    // update the existing contact
+    else {
+        update = true;
+    }
+
+    // NOTE: The user may be working with a partial Contact object, because only
+    // user-specified Contact fields are returned from a find operation (blame
+    // the W3C spec). If this is an update to an existing Contact, we don't
+    // want to clear an attribute from the contact database simply because the
+    // Contact object that the user passed in contains a null value for that
+    // attribute. So we only copy the non-null Contact attributes to the
+    // Tizen Contact object before saving.
+    //
+    // This means that a user must explicitly set a Contact attribute to a
+    // non-null value in order to update it in the contact database.
+    //
+    traceTizenContact (tizenContact);
+
+    // display name
+    if (contact.displayName !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            tizenContact.name.displayName = contact.displayName;
+        }
+    }
+
+    // name
+    if (contact.name !== null) {
+        if (contact.name.givenName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.firstName = contact.name.givenName;
+            }
+        }
+
+        if  (contact.name.middleName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.middleName = contact.name.middleName;
+            }
+        }
+
+        if (contact.name.familyName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.lastName = contact.name.familyName;
+            }
+        }
+
+        if (contact.name.honorificPrefix) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.prefix = contact.name.honorificPrefix;
+            }
+        }
+    }
+
+    // nickname
+    if (contact.nickname !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            if (!utils.isArray(tizenContact.name.nicknames))
+            {
+                tizenContact.name.nicknames = [];
+            }
+            tizenContact.name.nicknames[0] = contact.nickname;
+        }
+    }
+    else {
+        tizenContact.name.nicknames = [];
+    }
+
+    // note
+    if (contact.note !== null) {
+        if (tizenContact.note === null) {
+            tizenContact.note = [];
+        }
+        if (tizenContact.note !== null) {
+            tizenContact.note[0] = contact.note;
+        }
+    }
+
+    // photos
+    if (contact.photos && utils.isArray(contact.emails) && contact.emails.length > 0) {
+        tizenContact.photoURI = contact.photos[0];
+    }
+
+    if (utils.isDate(contact.birthday)) {
+        if (!utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday = new Date();
+        }
+        if (utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday.setDate(contact.birthday.getDate());
+        }
+    }
+
+    // Tizen supports many addresses
+    if (utils.isArray(contact.emails)) {
+
+        // if this is an update, re initialize email addresses
+        if (update) {
+            // doit on effacer sur un update??????
+        }
+
+        // copy the first three email addresses found
+        var emails = [];
+        for (i = 0; i < contact.emails.length; i += 1) {
+            var emailTypes = [];
+
+            emailTypes.push (contact.emails[i].type);
+
+            if (contact.emails[i].pref) {
+                emailTypes.push ("PREF");
+            }
+
+            emails.push(
+                new tizen.ContactEmailAddress(
+                    contact.emails[i].value,
+                    emailTypes)
+            );
+        }
+        tizenContact.emails = emails.length > 0 ? emails : [];
+    }
+    else {
+        tizenContact.emails = [];
+    }
+
+    // Tizen supports many phone numbers
+    // copy into appropriate fields based on type
+    if (utils.isArray(contact.phoneNumbers)) {
+        // if this is an update, re-initialize phone numbers
+        if (update) {
+        }
+
+        var phoneNumbers = [];
+
+        for (i = 0; i < contact.phoneNumbers.length; i += 1) {
+
+            if (!contact.phoneNumbers[i] || !contact.phoneNumbers[i].value) {
+                continue;
+            }
+
+             var phoneTypes = [];
+             phoneTypes.push (contact.phoneNumbers[i].type);
+
+             if (contact.phoneNumbers[i].pref) {
+                 phoneTypes.push ("PREF");
+             }
+
+            phoneNumbers.push(
+                new tizen.ContactPhoneNumber(
+                    contact.phoneNumbers[i].value,
+                    phoneTypes)
+            );
+        }
+
+        tizenContact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : [];
+    } else {
+        tizenContact.phoneNumbers = [];
+    }
+
+    if (utils.isArray(contact.addresses)) {
+        // if this is an update, re-initialize addresses
+        if (update) {
+        }
+
+        var addresses = [],
+            address = null;
+
+        for ( i = 0; i < contact.addresses.length; i += 1) {
+            address = contact.addresses[i];
+
+            if (!address || address.id === undefined || address.pref === undefined || address.type === undefined || address.formatted === undefined) {
+                continue;
+            }
+
+            var addressTypes = [];
+            addressTypes.push (address.type);
+
+            if (address.pref) {
+                addressTypes.push ("PREF");
+            }
+
+            addresses.push(
+                new tizen.ContactAddress({
+                         country:                   address.country,
+                         region :                   address.region,
+                         city:                      address.locality,
+                         streetAddress:             address.streetAddress,
+                         additionalInformation:     "",
+                         postalCode:                address.postalCode,
+                         types :                    addressTypes
+                }));
+
+        }
+        tizenContact.addresses = addresses.length > 0 ? addresses : [];
+
+    } else{
+        tizenContact.addresses = [];
+    }
+
+    // copy first url found to BlackBerry 'webpage' field
+    if (utils.isArray(contact.urls)) {
+        // if this is an update, re-initialize web page
+        if (update) {
+        }
+
+        var url = null,
+            urls = [];
+
+        for ( i = 0; i< contact.urls.length; i+= 1) {
+            url = contact.urls[i];
+
+            if (!url || !url.value) {
+                continue;
+            }
+
+            urls.push( new tizen.ContactWebSite(url.value, url.type));
+        }
+        tizenContact.urls = urls.length > 0 ? urls : [];
+    } else{
+        tizenContact.urls = [];
+    }
+
+    if (utils.isArray(contact.organizations && contact.organizations.length > 0) ) {
+        // if this is an update, re-initialize org attributes
+        var organization = contact.organizations[0];
+
+         tizenContact.organization = new tizen.ContacOrganization({
+             name:          organization.name,
+             department:    organization.department,
+             office:        "",
+             title:         organization.title,
+             role:          "",
+             logoURI:       ""
+         });
+    }
+
+    // categories
+    if (utils.isArray(contact.categories)) {
+        tizenContact.categories = [];
+
+        var category = null;
+
+        for (i = 0; i < contact.categories.length; i += 1) {
+            category = contact.categories[i];
+
+            if (typeof category === "string") {
+                tizenContact.categories.push(category);
+            }
+        }
+    }
+    else {
+        tizenContact.categories = [];
+    }
+
+    // save to device
+    // in tizen contact mean update or add
+    // later we might use addBatch and updateBatch
+    if (update){
+        tizen.contact.getDefaultAddressBook().update(tizenContact);
+    }
+    else {
+        tizen.contact.getDefaultAddressBook().add(tizenContact);
+    }
+
+    // Use the fully populated Tizen contact object to create a
+    // corresponding W3C contact object.
+    return ContactUtils.createContact(tizenContact, [ "*" ]);
+};
+
+
+/**
+ * Creates a Tizen ContactAddress object from a W3C ContactAddress.
+ *
+ * @return {tizen.ContactAddress} a Tizen ContactAddress object
+ */
+var createTizenAddress = function(address) {
+
+    var type = null,
+        pref = null,
+        typesAr = [];
+
+    if (address === null) {
+        return null;
+    }
+
+
+    var tizenAddress = new tizen.ContactAddress();
+
+    if (tizenAddress === null) {
+        return null;
+    }
+
+    typesAr.push(address.type);
+
+    if (address.pref) {
+        typesAr.push("PREF");
+    }
+
+    tizenAddress.country = address.country || "";
+    tizenAddress.region = address.region || "";
+    tizenAddress.city = address.locality || "";
+    tizenAddress.streetAddress = address.streetAddress || "";
+    tizenAddress.postalCode = address.postalCode || "";
+    tizenAddress.types = typesAr || "";
+
+    return tizenAddress;
+};
+
+module.exports = {
+    /**
+     * Persists contact to device storage.
+     */
+
+    save : function(successCB, failCB) {
+
+        try {
+            // save the contact and store it's unique id
+            var fullContact = saveToDevice(this);
+
+            this.id = fullContact.id;
+
+            // This contact object may only have a subset of properties
+            // if the save was an update of an existing contact. This is
+            // because the existing contact was likely retrieved using a
+            // subset of properties, so only those properties were set in the
+            // object. For this reason, invoke success with the contact object
+            // returned by saveToDevice since it is fully populated.
+
+            if (typeof successCB === 'function') {
+                successCB(fullContact);
+            }
+        }
+        catch (error) {
+            console.log('Error saving contact: ' +  error);
+
+            if (typeof failCB === 'function') {
+                failCB (new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    },
+
+    /**
+     * Removes contact from device storage.
+     *
+     * @param successCB
+     *            successCB callback
+     * @param failCB
+     *            error callback
+     */
+    remove : function (successCB, failCB) {
+
+        try {
+            // retrieve contact from device by id
+            var tizenContact = null;
+
+            if (this.id) {
+                tizenContact = findByUniqueId(this.id);
+            }
+
+
+            // if contact was found, remove it
+            if (tizenContact) {
+
+                tizen.contact.getDefaultAddressBook().remove(tizenContact.id);
+
+                if (typeof success === 'function') {
+                    successCB(this);
+                }
+            }
+            // attempting to remove a contact that hasn't been saved
+            else if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+        catch (error) {
+            console.log('Error removing contact ' + this.id + ": " + error);
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/ContactUtils.js
+define("cordova/plugin/tizen/ContactUtils", function(require, exports, module) {
+/*global tizen:false */
+var ContactAddress = require('cordova/plugin/ContactAddress'),
+    ContactName = require('cordova/plugin/ContactName'),
+    ContactField = require('cordova/plugin/ContactField'),
+    ContactOrganization = require('cordova/plugin/ContactOrganization'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+ * Mappings for each Contact field that may be used in a find operation. Maps
+ * W3C Contact fields to one or more fields in a Tizen contact object.
+ *
+ * Example: user searches with a filter on the Contact 'name' field:
+ *
+ * <code>Contacts.find(['name'], onSuccess, onFail, {filter:'Bob'});</code>
+ *
+ * The 'name' field does not exist in a Tizen contact. Instead, a filter
+ * expression will be built to search the Tizen contacts using the
+ * Tizen 'title', 'firstName' and 'lastName' fields.
+ */
+var fieldMappings = {
+    "id" : ["id"],
+    "displayName" : ["name.displayName"],
+    "nickname": ["name.nicknames"],
+    "name" : [ "name.prefix", "name.firstName", "name.lastName" ],
+    "phoneNumbers" : ["phoneNumbers.number","phoneNumbers.types"],
+    "emails" : ["emails.types", "emails.email"],
+    "addresses" : ["addresses.country","addresses.region","addresses.city","addresses.streetAddress","addresses.postalCode","addresses.country","addresses.types"],
+    "organizations" : ["organization.name","organization.department","organization.office", "organization.title"],
+    "birthday" : ["birthday"],
+    "note" : ["notes"],
+    "photos" : ["photoURI"],
+    "categories" : ["categories"],
+    "urls" : ["urls.url", "urls.type"]
+};
+
+/*
+ * Build an array of all of the valid W3C Contact fields. This is used to
+ * substitute all the fields when ["*"] is specified.
+ */
+var allFields = [];
+
+(function initializeAllFieldsMapping() {
+
+    for ( var key in fieldMappings) {
+        allFields.push(key);
+    }
+    // as we want it to be executed once
+    function initializeAllFieldsMapping() {
+    }
+
+})();
+
+/**
+ * Create a W3C ContactAddress object from a Tizen Address object
+ *
+ * @param {String}
+ *            type the type of address (e.g. work, home)
+ * @param {tizen.ContactAddress}
+ *            tizenAddress a Tizen Address object
+ * @return {ContactAddress} a contact address object or null if the specified
+ *         address is null
+ */
+var createContactAddress = function(type, tizenAddress) {
+    if (!tizenAddress) {
+        return null;
+    }
+
+    var streetAddress = tizenAddress.streetAddress;
+    var locality = tizenAddress.city || "";
+    var region = tizenAddress.region || "";
+    var postalCode = tizenAddress.postalCode || "";
+    var country = tizenAddress.country || "";
+    var formatted = streetAddress + ", " + locality + ", " + region + ", " + postalCode + ", " + country;
+
+    var contact = new ContactAddress(null, type, formatted, streetAddress, locality, region, postalCode, country);
+
+    return contact;
+};
+
+module.exports = {
+    /**
+     * Builds Tizen filter expressions for contact search using the
+     * contact fields and search filter provided.
+     *
+     * @param {String[]}
+     *            fields Array of Contact fields to search
+     * @param {String}
+     *            filter Filter, or search string
+     * @param {Boolean}
+     *                 multiple, one contacts or more wanted as result
+     * @return filter expression or null if fields is empty or filter is null or
+     *         empty
+     */
+
+    buildFilterExpression: function(fields, filter) {
+        // ensure filter exists
+        if (!filter || filter === "") {
+            return null;
+        }
+
+        if ((fields.length === 1) && (fields[0] === "*")) {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // build a filter expression using all Contact fields provided
+        var compositeFilter = null,
+            attributeFilter = null,
+            filterExpression = null,
+            matchFlag = "CONTAINS",
+            matchValue = filter,
+            attributesArray = [];
+
+        if (fields && utils.isArray(fields)) {
+
+            for ( var field in fields) {
+
+                if (!fields[field]) {
+                    continue;
+                }
+
+                // retrieve Tizen contact fields that map Cordova fields specified
+                // (tizenFields is a string or an array of strings)
+                var tizenFields = fieldMappings[fields[field]];
+
+                if (!tizenFields) {
+                    // does something maps
+                    continue;
+                }
+
+                // construct the filter expression using the Tizen fields
+                for ( var index in tizenFields) {
+                    attributeFilter = new tizen.AttributeFilter(tizenFields[index], matchFlag, matchValue);
+                    if (attributeFilter !== null) {
+                        attributesArray.push(attributeFilter);
+                    }
+                }
+            }
+        }
+
+        // fullfil tizen find attribute as a single or a composite attribute
+        if (attributesArray.length == 1 ) {
+            filterExpression = attributeFilter[0];
+        } else if (attributesArray.length > 1) {
+            // combine the filters as a Union
+            filterExpression = new tizen.CompositeFilter("UNION", attributesArray);
+        } else {
+            filterExpression = null;
+        }
+
+        return filterExpression;
+    },
+
+
+
+    /**
+     * Creates a Contact object from a Tizen Contact object, copying only
+     * the fields specified.
+     *
+     * This is intended as a privately used function but it is made globally
+     * available so that a Contact.save can convert a BlackBerry contact object
+     * into its W3C equivalent.
+     *
+     * @param {tizen.Contact}
+     *            tizenContact Tizen Contact object
+     * @param {String[]}
+     *            fields array of contact fields that should be copied
+     * @return {Contact} a contact object containing the specified fields or
+     *         null if the specified contact is null
+     */
+    createContact: function(tizenContact, fields) {
+
+        if (!tizenContact) {
+            return null;
+        }
+
+        // construct a new contact object
+        // always copy the contact id and displayName fields
+        var contact = new Contact(tizenContact.id, tizenContact.name.displayName);
+
+
+        // nothing to do
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            return contact;
+        } else if (fields.length === 1 && fields[0] === "*") {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // add the fields specified
+        for ( var key in fields) {
+
+            var field = fields[key],
+                index = 0;
+
+            if (!field) {
+                continue;
+            }
+
+            // name
+            if (field.indexOf('name') === 0) {
+
+                var formattedName = (tizenContact.name.prefix || "");
+
+                if (tizenContact.name.firstName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.firstName || "");
+                }
+
+                if (tizenContact.name.middleName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.middleName || "");
+                }
+
+                if (tizenContact.name.lastName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.lastName || "");
+                }
+
+                contact.name = new ContactName(
+                        formattedName,
+                        tizenContact.name.lastName,
+                        tizenContact.name.firstName,
+                        tizenContact.name.middleName,
+                        tizenContact.name.prefix,
+                        null);
+            }
+
+            // phoneNumbers
+            else if (field.indexOf('phoneNumbers') === 0) {
+
+                var phoneNumbers = [];
+
+                for (index = 0 ; index < tizenContact.phoneNumbers.length ; ++index) {
+
+                    phoneNumbers.push(
+                            new ContactField(
+                                    'PHONE',
+                                    tizenContact.phoneNumbers[index].number,
+                                    ((tizenContact.phoneNumbers[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+
+
+                contact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : null;
+            }
+
+            // emails
+            else if (field.indexOf('emails') === 0) {
+
+                var emails = [];
+
+                for (index = 0 ; index < tizenContact.emails.length ; ++index) {
+
+                    emails.push(
+                        new ContactField(
+                            'EMAILS',
+                            tizenContact.emails[index].email,
+                            ((tizenContact.emails[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+                contact.emails = emails.length > 0 ? emails : null;
+            }
+
+            // addresses
+            else if (field.indexOf('addresses') === 0) {
+
+                var addresses = [];
+                for (index = 0 ; index < tizenContact.addresses.length ; ++index) {
+
+                    addresses.push(
+                            new ContactAddress(
+                                    ((tizenContact.addresses[index].types[1] &&  tizenContact.addresses[index].types[1] === "PREF") ? true : false),
+                                    tizenContact.addresses[index].types[0] ? tizenContact.addresses[index].types[0] : "HOME",
+                                    null,
+                                    tizenContact.addresses[index].streetAddress,
+                                    tizenContact.addresses[index].city,
+                                    tizenContact.addresses[index].region,
+                                    tizenContact.addresses[index].postalCode,
+                                    tizenContact.addresses[index].country ));
+                }
+
+                contact.addresses = addresses.length > 0 ? addresses : null;
+            }
+
+            // birthday
+            else if (field.indexOf('birthday') === 0) {
+                if (utils.isDate(tizenContact.birthday)) {
+                    contact.birthday = tizenContact.birthday;
+                }
+            }
+
+            // note only one in Tizen Contact
+            else if (field.indexOf('note') === 0) {
+                if (tizenContact.note) {
+                    contact.note = tizenContact.note[0];
+                }
+            }
+
+            // organizations
+            else if (field.indexOf('organizations') === 0) {
+
+                var organizations = [];
+
+                // there's only one organization in a Tizen Address
+
+                if (tizenContact.organization) {
+                    organizations.push(
+                            new ContactOrganization(
+                                    true,
+                                    'WORK',
+                                    tizenContact.organization.name,
+                                    tizenContact.organization.department,
+                                    tizenContact.organization.jobTitle));
+                }
+
+                contact.organizations = organizations.length > 0 ? organizations : null;
+            }
+
+            // categories
+            else if (field.indexOf('categories') === 0) {
+
+                var categories = [];
+
+                if (tizenContact.categories) {
+
+                    for (index = 0 ; index < tizenContact.categories.length ; ++index) {
+                        categories.push(
+                                new ContactField(
+                                        'MAIN',
+                                        tizenContact.categories,
+                                        (index === 0) ));
+                    }
+
+                    contact.categories = categories.length > 0 ? categories : null;
+                }
+            }
+
+            // urls
+            else if (field.indexOf('urls') === 0) {
+                var urls = [];
+
+                if (tizenContact.urls) {
+                    for (index = 0 ; index <tizenContact.urls.length ; ++index) {
+                        urls.push(
+                                new ContactField(
+                                        tizenContact.urls[index].type,
+                                        tizenContact.urls[index].url,
+                                        (index === 0)));
+                    }
+                }
+
+                contact.urls = urls.length > 0 ? urls : null;
+            }
+
+            // photos
+            else if (field.indexOf('photos') === 0) {
+                var photos = [];
+
+                if (tizenContact.photoURI) {
+                    photos.push(new ContactField('URI', tizenContact.photoURI, true));
+                }
+
+                contact.photos = photos.length > 0 ? photos : null;
+            }
+        }
+
+        return contact;
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Device.js
+define("cordova/plugin/tizen/Device", function(require, exports, module) {
+/*global tizen:false */
+var channel = require('cordova/channel');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+function Device() {
+    this.version = null;
+    this.uuid = null;
+    this.name = null;
+    this.cordova =  "2.0.0";
+    this.platform = "Tizen";
+
+    var me = this;
+
+    function onSuccessCallback(sysInfoProp) {
+        me.name = sysInfoProp.model;
+        me.uuid = sysInfoProp.imei;
+        me.version = sysInfoProp.version;
+        channel.onCordovaInfoReady.fire();
+    }
+
+    function onErrorCallback(error) {
+        console.log("error initializing cordova: " + error);
+    }
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getDeviceInfo(onSuccessCallback, onErrorCallback);
+    });
+}
+
+Device.prototype.getDeviceInfo = function(success, fail, args) {
+    tizen.systeminfo.getPropertyValue("Device", success, fail);
+};
+
+module.exports = new Device();
+
+});
+
+// file: lib/tizen/plugin/tizen/File.js
+define("cordova/plugin/tizen/File", function(require, exports, module) {
+/*global WebKitBlobBuilder:false */
+var FileError = require('cordova/plugin/FileError'),
+    DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    File = require('cordova/plugin/File'),
+    FileSystem = require('cordova/plugin/FileSystem');
+
+var nativeRequestFileSystem = window.webkitRequestFileSystem,
+    nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL,
+    NativeFileReader = window.FileReader;
+
+function getFileSystemName(nativeFs) {
+    return (nativeFs.name.indexOf("Persistent") != -1) ? "persistent" : "temporary";
+}
+
+function makeEntry(entry) {
+    if (entry.isDirectory) {
+        return new DirectoryEntry(entry.name, decodeURI(entry.toURL()));
+    }
+    else {
+        return new FileEntry(entry.name, decodeURI(entry.toURL()));
+    }
+}
+
+module.exports = {
+    /* requestFileSystem */
+    requestFileSystem: function(successCallback, errorCallback, args) {
+        var type = args[0],
+            size = args[1];
+
+        nativeRequestFileSystem(type, size, function(nativeFs) {
+            successCallback(new FileSystem(getFileSystemName(nativeFs), makeEntry(nativeFs.root)));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* resolveLocalFileSystemURI */
+    resolveLocalFileSystemURI: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            successCallback(makeEntry(entry));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryReader */
+    readEntries: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(dirEntry) {
+            var reader = dirEntry.createReader();
+            reader.readEntries(function(entries) {
+                var retVal = [];
+                for (var i = 0; i < entries.length; i++) {
+                    retVal.push(makeEntry(entries[i]));
+                }
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* Entry */
+    getMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getMetadata(function(metaData) {
+                successCallback(metaData.modificationTime);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    moveTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.moveTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    copyTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.copyTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    remove: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.remove(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getParent: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getParent(function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileEntry */
+    getFileMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.file(function(file) {
+                var retVal = new File(file.name, decodeURI(entry.toURL()), file.type, file.lastModifiedDate, file.size);
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryEntry */
+    getDirectory: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getDirectory(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    removeRecursively: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.removeRecursively(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getFile: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getFile(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileReader */
+    readAsText: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            encoding = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsText(file, encoding);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    readAsDataURL: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsDataURL(file);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileWriter */
+    write: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            text = args[1],
+            position = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.position - position);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                var blob = new WebKitBlobBuilder();
+                blob.append(text);
+
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.seek(position);
+                writer.write(blob.getBlob('text/plain'));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    truncate: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            size = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.length);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.truncate(size);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/FileTransfer.js
+define("cordova/plugin/tizen/FileTransfer", function(require, exports, module) {
+/*global WebKitBlobBuilder:false */
+var FileEntry = require('cordova/plugin/FileEntry'),
+    FileTransferError = require('cordova/plugin/FileTransferError'),
+    FileUploadResult = require('cordova/plugin/FileUploadResult');
+
+var nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL;
+
+function getParentPath(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(0, pos + 1);
+}
+
+function getFileName(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(pos + 1);
+}
+
+module.exports = {
+    upload: function(successCallback, errorCallback, args) {
+        var filePath = args[0],
+            server = args[1],
+            fileKey = args[2],
+            fileName = args[3],
+            mimeType = args[4],
+            params = args[5],
+            /*trustAllHosts = args[6],*/
+            chunkedMode = args[7];
+
+        nativeResolveLocalFileSystemURI(filePath, function(entry) {
+            entry.file(function(file) {
+                function uploadFile(blobFile) {
+                    var fd = new FormData();
+
+                    fd.append(fileKey, blobFile, fileName);
+                    for (var prop in params) {
+                        if(params.hasOwnProperty(prop)) {
+                            fd.append(prop, params[prop]);
+                        }
+                    }
+
+                    var xhr = new XMLHttpRequest();
+                    xhr.open("POST", server);
+                    xhr.onload = function(evt) {
+                        if (xhr.status == 200) {
+                            var result = new FileUploadResult();
+                            result.bytesSent = file.size;
+                            result.responseCode = xhr.status;
+                            result.response = xhr.response;
+                            successCallback(result);
+                        } else if (xhr.status == 404) {
+                            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                        } else {
+                            errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                        }
+                    };
+                    xhr.ontimeout = function(evt) {
+                        errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                    };
+
+                    xhr.send(fd);
+                }
+
+                var bytesPerChunk;
+                if (chunkedMode === true) {
+                    bytesPerChunk = 1024 * 1024; // 1MB chunk sizes.
+                } else {
+                    bytesPerChunk = file.size;
+                }
+                var start = 0;
+                var end = bytesPerChunk;
+                while (start < file.size) {
+                    var chunk = file.webkitSlice(start, end, mimeType);
+                    uploadFile(chunk);
+                    start = end;
+                    end = start + bytesPerChunk;
+                }
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            }
+            );
+        },
+        function(error) {
+            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+        }
+        );
+    },
+
+    download: function(successCallback, errorCallback, args) {
+        var url = args[0],
+            filePath = args[1];
+
+        var xhr = new XMLHttpRequest();
+
+        function writeFile(fileEntry) {
+            fileEntry.createWriter(function(writer) {
+                writer.onwriteend = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(new FileEntry(fileEntry.name, fileEntry.toURL()));
+                    } else {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    }
+                };
+
+                writer.onerror = function(evt) {
+                    errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                };
+
+                var builder = new WebKitBlobBuilder();
+                builder.append(xhr.response);
+                var blob = builder.getBlob();
+                writer.write(blob);
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            });
+        }
+
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == xhr.DONE) {
+                if (xhr.status == 200 && xhr.response) {
+                    nativeResolveLocalFileSystemURI(getParentPath(filePath), function(dir) {
+                        dir.getFile(getFileName(filePath), {create: true}, writeFile, function(error) {
+                            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                        });
+                    }, function(error) {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    });
+                } else if (xhr.status == 404) {
+                    errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                } else {
+                    errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                }
+            }
+        };
+
+        xhr.open("GET", url, true);
+        xhr.responseType = "arraybuffer";
+        xhr.send();
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Media.js
+define("cordova/plugin/tizen/Media", function(require, exports, module) {
+/*global Media:false, webkitURL:false */
+var MediaError = require('cordova/plugin/MediaError'),
+    audioObjects = {};
+
+module.exports = {
+    create: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::create() - id =" + id + ", src =" + src);
+        audioObjects[id] = new Audio(src);
+        audioObjects[id].onStalledCB = function () {
+            console.log("media::onStalled()");
+             audioObjects[id].timer = window.setTimeout(function () {
+                    audioObjects[id].pause();
+                    if (audioObjects[id].currentTime !== 0)
+                        audioObjects[id].currentTime = 0;
+                    console.log("media::onStalled() - MEDIA_ERROR -> " + MediaError.MEDIA_ERR_ABORTED);
+                    var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, "Stalled");
+                    Media.onStatus(id, Media.MEDIA_ERROR, err);
+                }, 2000);
+        };
+        audioObjects[id].onEndedCB = function () {
+            console.log("media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        };
+        audioObjects[id].onErrorCB = function () {
+            console.log("media::onErrorCB() - MEDIA_ERROR -> " + event.srcElement.error);
+            Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error);
+        };
+        audioObjects[id].onPlayCB = function () {
+            console.log("media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
+        };
+        audioObjects[id].onPlayingCB = function () {
+            console.log("media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);
+        };
+        audioObjects[id].onDurationChangeCB = function () {
+            console.log("media::onDurationChangeCB() - MEDIA_DURATION -> " +  audioObjects[id].duration);
+            Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration);
+        };
+        audioObjects[id].onTimeUpdateCB = function () {
+            console.log("media::onTimeUpdateCB() - MEDIA_POSITION -> " +  audioObjects[id].currentTime);
+            Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime);
+        };
+        audioObjects[id].onCanPlayCB = function () {
+            console.log("media::onCanPlayCB()");
+            window.clearTimeout(audioObjects[id].timer);
+            audioObjects[id].play();
+        };
+      },
+    startPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1], options = args[2];
+        console.log("media::startPlayingAudio() - id =" + id + ", src =" + src + ", options =" + options);
+        audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB);
+        audioObjects[id].play();
+    },
+    stopPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        audioObjects[id].pause();
+        if (audioObjects[id].currentTime !== 0)
+            audioObjects[id].currentTime = 0;
+        console.log("media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED");
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB);
+    },
+    seekToAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], milliseconds = args[1];
+        console.log("media::seekToAudio()");
+         audioObjects[id].currentTime = milliseconds;
+        successCallback( audioObjects[id].currentTime);
+    },
+    pausePlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED");
+        audioObjects[id].pause();
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
+    },
+    getCurrentPositionAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::getCurrentPositionAudio()");
+        successCallback(audioObjects[id].currentTime);
+    },
+    release: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        console.log("media::release()");
+    },
+    setVolume: function (successCallback, errorCallback, args) {
+        var id = args[0], volume = args[1];
+        console.log("media::setVolume()");
+        audioObjects[id].volume = volume;
+    },
+    startRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::startRecordingAudio() - id =" + id + ", src =" + src);
+
+        function gotStreamCB(stream) {
+            audioObjects[id].src = webkitURL.createObjectURL(stream);
+            console.log("media::startRecordingAudio() - stream CB");
+        }
+
+        function gotStreamFailedCB(error) {
+            console.log("media::startRecordingAudio() - error CB:" + error.toString());
+        }
+
+        if (navigator.webkitGetUserMedia) {
+            audioObjects[id] = new Audio();
+            navigator.webkitGetUserMedia('audio', gotStreamCB, gotStreamFailedCB);
+        } else {
+            console.log("webkitGetUserMedia not supported");
+        }
+        successCallback();
+    },
+    stopRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::stopRecordingAudio() - id =" + id);
+        audioObjects[id].pause();
+        successCallback();
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/MediaError.js
+define("cordova/plugin/tizen/MediaError", function(require, exports, module) {
+
+// The MediaError object already exists on Tizen. This prevents the Cordova
+// version from being defined. This object is used to merge in differences
+// between Tizen and Cordova MediaError objects.
+module.exports = {
+        MEDIA_ERR_NONE_ACTIVE : 0,
+        MEDIA_ERR_NONE_SUPPORTED : 4
+};
+});
+
+// file: lib/tizen/plugin/tizen/NetworkStatus.js
+define("cordova/plugin/tizen/NetworkStatus", function(require, exports, module) {
+/*global tizen:false */
+var Connection = require('cordova/plugin/Connection');
+
+module.exports = {
+    getConnectionInfo: function (successCallback, errorCallback) {
+        var cncType = Connection.NONE;
+        var infoCount = 0;
+
+        function infoCB() {
+            infoCount++;
+            if (infoCount > 1)
+               successCallback(cncType);
+        }
+
+        function errorCB(error) {
+           console.log("Error: " + error.code + "," + error.name + "," + error.message);
+           infoCB();
+        }
+
+        function wifiSuccessCB(wifi) {
+            if ((wifi.status === "ON")  && (wifi.ipAddress.length !== 0))
+                cncType = Connection.WIFI;
+            infoCB();
+        }
+
+        function cellularSuccessCB(cell) {
+            if ((cncType === Connection.NONE) && (cell.status === "ON") && (cell.ipAddress.length !== 0))
+                cncType = Connection.CELL_2G;
+            infoCB();
+        }
+
+        if (tizen.systeminfo.isSupported('WifiNetwork')) {
+            tizen.systeminfo.getPropertyValue('WifiNetwork', wifiSuccessCB, errorCB);
+        }
+
+        if (tizen.systeminfo.isSupported('CellularNetwork')) {
+            tizen.systeminfo.getPropertyValue('CellularNetwork', cellularSuccessCB, errorCB);
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Notification.js
+define("cordova/plugin/tizen/Notification", function(require, exports, module) {
+var SoundBeat = require('cordova/plugin/tizen/SoundBeat');
+
+/* TODO: get resource path from app environment? */
+var soundBeat = new SoundBeat(["./sounds/beep.wav"]);
+
+module.exports = {
+
+    alert: function(message, alertCallback, title, buttonName) {
+        return this.confirm(message, alertCallback, title, buttonName);
+    },
+
+    confirm: function(message, confirmCallback, title, buttonLabels) {
+        var index            =    null,
+            overlayElement    =    null,
+            popup            =    null,
+            element         =    null,
+            titleString        =     null,
+            messageString    =    null,
+            buttonString    =    null,
+            buttonsArray    =    null;
+
+
+        console.log ("message" , message);
+        console.log ("confirmCallback" , confirmCallback);
+        console.log ("title" , title);
+        console.log ("buttonLabels" , buttonLabels);
+
+        titleString = '<div class="popup-title"><p>' + title + '</p></div>';
+        messageString = '<div class="popup-text"><p>' + message + '</p></div>';
+        buttonString = '<div class="popup-button-bg"><ul>';
+
+        switch(typeof(buttonLabels))
+        {
+        case "string":
+            buttonsArray = buttonLabels.split(",");
+
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+
+        case "array":
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+        default:
+            console.log ("cordova/plugin/tizen/Notification, default, buttonLabels: ", buttonLabels);
+            break;
+        }
+
+        buttonString += '</ul></div>';
+
+        overlayElement = document.createElement("div");
+        overlayElement.className = 'ui-popupwindow-screen';
+
+        overlayElement.style.zIndex = 1001;
+        overlayElement.style.width = "100%";
+        overlayElement.style.height = "100%";
+        overlayElement.style.top = 0;
+        overlayElement.style.left = 0;
+        overlayElement.style.margin = 0;
+        overlayElement.style.padding = 0;
+        overlayElement.style.position = "absolute";
+
+        popup = document.createElement("div");
+        popup.className = "ui-popupwindow";
+        popup.style.position = "fixed";
+        popup.style.zIndex = 1002;
+        popup.innerHTML = titleString + messageString + buttonString;
+
+        document.body.appendChild(overlayElement);
+        document.body.appendChild(popup);
+
+        function createListener(button) {
+            return function() {
+                document.body.removeChild(overlayElement);
+                document.body.removeChild(popup);
+                confirmCallback(button.value);
+            };
+        }
+
+       for (index in buttonsArray) {
+           console.log ("index: ", index);
+
+           element = document.getElementById("popup-button-" + buttonsArray[index]);
+           element.addEventListener("click", createListener(element), false);
+       }
+    },
+
+    vibrate: function(milliseconds) {
+        console.log ("milliseconds" , milliseconds);
+
+        if (navigator.vibrate) {
+            navigator.vibrate(milliseconds);
+        }
+        else {
+            console.log ("cordova/plugin/tizen/Notification, vibrate API does not exists");
+        }
+    },
+
+    beep: function(count) {
+        console.log ("count" , count);
+        soundBeat.play(count);
+    }
+};
+
+
+
+});
+
+// file: lib/tizen/plugin/tizen/SoundBeat.js
+define("cordova/plugin/tizen/SoundBeat", function(require, exports, module) {
+/*global webkitAudioContext:false */
+/*
+ *  SoundBeat
+ * used by Notification Manager beep method
+ *
+ * This class provides sounds play
+ *
+ * uses W3C  Web Audio API
+ * uses BufferLoader object
+ *
+ * NOTE: the W3C Web Audio doc tells we do not need to recreate the audio
+ *       context to play a sound but only the audiosourcenode (createBufferSource)
+ *       in the webkit implementation we have to.
+ *
+ */
+
+var BufferLoader = require('cordova/plugin/tizen/BufferLoader');
+
+function SoundBeat(urlList) {
+    this.context = null;
+    this.urlList = urlList || null;
+    this.buffers = null;
+}
+
+/*
+ * This method play a loaded sounds on the Device
+ * @param {Number} times Number of times to play loaded sounds.
+ *
+ */
+SoundBeat.prototype.play = function(times) {
+
+    var i = 0, sources = [], that = this;
+
+    function finishedLoading (bufferList) {
+        that.buffers = bufferList;
+
+        for (i = 0; i < that.buffers.length ; i +=1) {
+            if (that.context) {
+                sources[i] = that.context.createBufferSource();
+
+                sources[i].buffer = that.buffers[i];
+                sources[i].connect (that.context.destination);
+
+                sources[i].loop = true;
+                sources[i].noteOn (0);
+                sources[i].noteOff(sources[i].buffer.duration * times);
+            }
+        }
+    }
+
+    if (webkitAudioContext !== null) {
+        this.context = new webkitAudioContext();
+    }
+    else {
+        console.log ("SoundBeat.prototype.play, w3c web audio api not supported");
+        this.context = null;
+    }
+
+    if (this.context === null) {
+        console.log ("SoundBeat.prototype.play, cannot create audio context object");
+        return;
+    }
+
+    this.bufferLoader = new BufferLoader (this.context, this.urlList, finishedLoading);
+    if (this.bufferLoader === null) {
+        console.log ("SoundBeat.prototype.play, cannot create buffer loader object");
+        return;
+    }
+
+    this.bufferLoader.load();
+};
+
+module.exports = SoundBeat;
+
+});
+
+// file: lib/tizen/plugin/tizen/contacts.js
+define("cordova/plugin/tizen/contacts", function(require, exports, module) {
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils');
+
+module.exports = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     *
+     * @return array of Contacts matching search criteria
+     */
+    find : function(fields, successCB, failCB, options) {
+
+        // Success callback is required. Throw exception if not specified.
+        if (typeof successCB !== 'function') {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+
+        // Search qualifier is required and cannot be empty.
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+            return;
+        }
+
+        // options are optional
+        var filter ="",
+            multiple = false,
+            contacts = [],
+            tizenFilter = null;
+
+        if (options) {
+            filter = options.filter || "";
+            multiple =  options.multiple || false;
+        }
+
+        if (filter){
+            tizenFilter = ContactUtils.buildFilterExpression(fields, filter);
+        }
+
+        tizen.contact.getDefaultAddressBook().find(
+            function(tizenContacts) {
+                if (multiple) {
+                    for (var index in tizenContacts) {
+                        contacts.push(ContactUtils.createContact(tizenContacts[index], fields));
+                    }
+                }
+                else {
+                    contacts.push(ContactUtils.createContact(tizenContacts[0], fields));
+                }
+
+                // return results
+                successCB(contacts);
+            },
+            function(error) {
+                if (typeof failCB === 'function') {
+                    failCB(ContactError.UNKNOWN_ERROR);
+                }
+            },
+            tizenFilter,
+            null);
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/manager.js
+define("cordova/plugin/tizen/manager", function(require, exports, module) {
+var cordova = require('cordova');
+
+module.exports = {
+    exec: function (successCallback, errorCallback, clazz, action, args) {
+        var plugin = require('cordova/plugin/tizen/' + clazz);
+
+        if (plugin && typeof plugin[action] === 'function') {
+            var result = plugin[action](successCallback, errorCallback, args);
+            return result || {status: cordova.callbackStatus.NO_RESULT};
+        }
+
+        return {"status" : cordova.callbackStatus.CLASS_NOT_FOUND_EXCEPTION, "message" : "Function " + clazz + "::" + action + " cannot be found"};
+    },
+    resume: function () {},
+    pause: function () {},
+    destroy: function () {}
+};
+
+});
+
+// file: lib/common/utils.js
+define("cordova/utils", function(require, exports, module) {
+var utils = exports;
+
+/**
+ * Returns an indication of whether the argument is an array or not
+ */
+utils.isArray = function(a) {
+    return Object.prototype.toString.call(a) == '[object Array]';
+};
+
+/**
+ * Returns an indication of whether the argument is a Date or not
+ */
+utils.isDate = function(d) {
+    return Object.prototype.toString.call(d) == '[object Date]';
+};
+
+/**
+ * Does a deep clone of the object.
+ */
+utils.clone = function(obj) {
+    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
+        return obj;
+    }
+
+    var retVal, i;
+
+    if(utils.isArray(obj)){
+        retVal = [];
+        for(i = 0; i < obj.length; ++i){
+            retVal.push(utils.clone(obj[i]));
+        }
+        return retVal;
+    }
+
+    retVal = {};
+    for(i in obj){
+        if(!(i in retVal) || retVal[i] != obj[i]) {
+            retVal[i] = utils.clone(obj[i]);
+        }
+    }
+    return retVal;
+};
+
+/**
+ * Returns a wrappered version of the function
+ */
+utils.close = function(context, func, params) {
+    if (typeof params == 'undefined') {
+        return function() {
+            return func.apply(context, arguments);
+        };
+    } else {
+        return function() {
+            return func.apply(context, params);
+        };
+    }
+};
+
+/**
+ * Create a UUID
+ */
+utils.createUUID = function() {
+    return UUIDcreatePart(4) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(6);
+};
+
+/**
+ * Extends a child object from a parent object using classical inheritance
+ * pattern.
+ */
+utils.extend = (function() {
+    // proxy used to establish prototype chain
+    var F = function() {};
+    // extend Child from Parent
+    return function(Child, Parent) {
+        F.prototype = Parent.prototype;
+        Child.prototype = new F();
+        Child.__super__ = Parent.prototype;
+        Child.prototype.constructor = Child;
+    };
+}());
+
+/**
+ * Alerts a message in any available way: alert or console.log.
+ */
+utils.alert = function(msg) {
+    if (alert) {
+        alert(msg);
+    } else if (console && console.log) {
+        console.log(msg);
+    }
+};
+
+/**
+ * Formats a string and arguments following it ala sprintf()
+ *
+ * see utils.vformat() for more information
+ */
+utils.format = function(formatString /* ,... */) {
+    var args = [].slice.call(arguments, 1);
+    return utils.vformat(formatString, args);
+};
+
+/**
+ * Formats a string and arguments following it ala vsprintf()
+ *
+ * format chars:
+ *   %j - format arg as JSON
+ *   %o - format arg as JSON
+ *   %c - format arg as ''
+ *   %% - replace with '%'
+ * any other char following % will format it's
+ * arg via toString().
+ *
+ * for rationale, see FireBug's Console API:
+ *    http://getfirebug.com/wiki/index.php/Console_API
+ */
+utils.vformat = function(formatString, args) {
+    if (formatString === null || formatString === undefined) return "";
+    if (arguments.length == 1) return formatString.toString();
+    if (typeof formatString != "string") return formatString.toString();
+
+    var pattern = /(.*?)%(.)(.*)/;
+    var rest    = formatString;
+    var result  = [];
+
+    while (args.length) {
+        var arg   = args.shift();
+        var match = pattern.exec(rest);
+
+        if (!match) break;
+
+        rest = match[3];
+
+        result.push(match[1]);
+
+        if (match[2] == '%') {
+            result.push('%');
+            args.unshift(arg);
+            continue;
+        }
+
+        result.push(formatted(arg, match[2]));
+    }
+
+    result.push(rest);
+
+    return result.join('');
+};
+
+//------------------------------------------------------------------------------
+function UUIDcreatePart(length) {
+    var uuidpart = "";
+    for (var i=0; i<length; i++) {
+        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
+        if (uuidchar.length == 1) {
+            uuidchar = "0" + uuidchar;
+        }
+        uuidpart += uuidchar;
+    }
+    return uuidpart;
+}
+
+//------------------------------------------------------------------------------
+function formatted(object, formatChar) {
+
+    try {
+        switch(formatChar) {
+            case 'j':
+            case 'o': return JSON.stringify(object);
+            case 'c': return '';
+        }
+    }
+    catch (e) {
+        return "error JSON.stringify()ing argument: " + e;
+    }
+
+    if ((object === null) || (object === undefined)) {
+        return Object.prototype.toString.call(object);
+    }
+
+    return object.toString();
+}
+
+});
+
+
+window.cordova = require('cordova');
+
+// file: lib/scripts/bootstrap.js
+(function (context) {
+    var channel = require("cordova/channel"),
+        _self = {
+            boot: function () {
+                /**
+                 * Create all cordova objects once page has fully loaded and native side is ready.
+                 */
+                channel.join(function() {
+                    var builder = require('cordova/builder'),
+                        base = require('cordova/common'),
+                        platform = require('cordova/platform');
+
+                    // Drop the common globals into the window object, but be nice and don't overwrite anything.
+                    builder.build(base.objects).intoButDontClobber(window);
+
+                    // Drop the platform-specific globals into the window object
+                    // and clobber any existing object.
+                    builder.build(platform.objects).intoAndClobber(window);
+
+                    // Merge the platform-specific overrides/enhancements into
+                    // the window object.
+                    if (typeof platform.merges !== 'undefined') {
+                        builder.build(platform.merges).intoAndMerge(window);
+                    }
+
+                    // Call the platform-specific initialization
+                    platform.initialize();
+
+                    // Fire event to notify that all objects are created
+                    channel.onCordovaReady.fire();
+
+                    // Fire onDeviceReady event once all constructors have run and
+                    // cordova info has been received from native side.
+                    channel.join(function() {
+                        require('cordova').fireDocumentEvent('deviceready');
+                    }, channel.deviceReadyChannelsArray);
+
+                }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);
+            }
+        };
+
+    // boot up once native side is ready
+    channel.onNativeReady.subscribeOnce(_self.boot);
+
+    // _nativeReady is global variable that the native side can set
+    // to signify that the native code is ready. It is a global since
+    // it may be called before any cordova JS is ready.
+    if (window._nativeReady) {
+        channel.onNativeReady.fire();
+    }
+
+}(window));
+
+// file: lib/scripts/bootstrap-tizen.js
+require('cordova/channel').onNativeReady.fire();
+
+
+})();
\ No newline at end of file
diff --git a/framework/cordova.tizen-debug.js b/framework/cordova.tizen-debug.js
new file mode 100644
index 0000000..d16ed8e
--- /dev/null
+++ b/framework/cordova.tizen-debug.js
@@ -0,0 +1,114 @@
+// commit 7dd17b00544742d14ecdeff2148a66480680f12b
+
+// File generated at :: Fri Jul 27 2012 11:40:36 GMT+0200 (CEST)
+
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+;(function() {
+
+try {eval("var require,\n    define;\n\n(function () {\n    var modules = {};\n\n    function build(module) {\n        var factory = module.factory;\n        module.exports = {};\n        delete module.factory;\n        factory(require, module.exports, module);\n        return module.exports;\n    }\n\n    require = function (id) {\n        if (!modules[id]) {\n            throw \"module \" + id + \" not found\";\n        }\n        return modules[id].factory ? build(modules[id]) : modules[id].exports;\n    };\n\n    define = function (id, factory) {\n        if (modules[id]) {\n            throw \"module \" + id + \" already defined\";\n        }\n\n        modules[id] = {\n            id: id,\n            factory: factory\n        };\n    };\n\n    define.remove = function (id) {\n        delete modules[id];\n    };\n\n})();\n\n//Export for use in node\nif (typeof module === \"object\" && typeof require === \"function\") {\n    module.exports.require = require;\n    module.exports.define = define;\n}\n//@ sourceURL=lib/scripts/require.js")} catch(e) {console.log("exception: in lib/scripts/require.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova\", function(require, exports, module) {\nvar channel = require('cordova/channel');\n\n/**\n * Listen for DOMContentLoaded and notify our channel subscribers.\n */\ndocument.addEventListener('DOMContentLoaded', function() {\n    channel.onDOMContentLoaded.fire();\n}, false);\nif (document.readyState == 'complete' || document.readyState == 'interactive') {\n    channel.onDOMContentLoaded.fire();\n}\n\n/**\n * Intercept calls to addEventListener + removeEventListener and handle deviceready,\n * resume, and pause events.\n */\nvar m_document_addEventListener = document.addEventListener;\nvar m_document_removeEventListener = document.removeEventListener;\nvar m_window_addEventListener = window.addEventListener;\nvar m_window_removeEventListener = window.removeEventListener;\n\n/**\n * Houses custom event handlers to intercept on document + window event listeners.\n */\nvar documentEventHandlers = {},\n    windowEventHandlers = {};\n\ndocument.addEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    if (typeof documentEventHandlers[e] != 'undefined') {\n        if (evt === 'deviceready') {\n            documentEventHandlers[e].subscribeOnce(handler);\n        } else {\n            documentEventHandlers[e].subscribe(handler);\n        }\n    } else {\n        m_document_addEventListener.call(document, evt, handler, capture);\n    }\n};\n\nwindow.addEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    if (typeof windowEventHandlers[e] != 'undefined') {\n        windowEventHandlers[e].subscribe(handler);\n    } else {\n        m_window_addEventListener.call(window, evt, handler, capture);\n    }\n};\n\ndocument.removeEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    // If unsubcribing from an event that is handled by a plugin\n    if (typeof documentEventHandlers[e] != \"undefined\") {\n        documentEventHandlers[e].unsubscribe(handler);\n    } else {\n        m_document_removeEventListener.call(document, evt, handler, capture);\n    }\n};\n\nwindow.removeEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    // If unsubcribing from an event that is handled by a plugin\n    if (typeof windowEventHandlers[e] != \"undefined\") {\n        windowEventHandlers[e].unsubscribe(handler);\n    } else {\n        m_window_removeEventListener.call(window, evt, handler, capture);\n    }\n};\n\nfunction createEvent(type, data) {\n    var event = document.createEvent('Events');\n    event.initEvent(type, false, false);\n    if (data) {\n        for (var i in data) {\n            if (data.hasOwnProperty(i)) {\n                event[i] = data[i];\n            }\n        }\n    }\n    return event;\n}\n\nif(typeof window.console === \"undefined\") {\n    window.console = {\n        log:function(){}\n    };\n}\n\nvar cordova = {\n    define:define,\n    require:require,\n    /**\n     * Methods to add/remove your own addEventListener hijacking on document + window.\n     */\n    addWindowEventHandler:function(event, opts) {\n        return (windowEventHandlers[event] = channel.create(event, opts));\n    },\n    addDocumentEventHandler:function(event, opts) {\n        return (documentEventHandlers[event] = channel.create(event, opts));\n    },\n    removeWindowEventHandler:function(event) {\n        delete windowEventHandlers[event];\n    },\n    removeDocumentEventHandler:function(event) {\n        delete documentEventHandlers[event];\n    },\n    /**\n     * Retreive original event handlers that were replaced by Cordova\n     *\n     * @return object\n     */\n    getOriginalHandlers: function() {\n        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},\n        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};\n    },\n    /**\n     * Method to fire event from native code\n     */\n    fireDocumentEvent: function(type, data) {\n        var evt = createEvent(type, data);\n        if (typeof documentEventHandlers[type] != 'undefined') {\n            setTimeout(function() {\n                documentEventHandlers[type].fire(evt);\n            }, 0);\n        } else {\n            document.dispatchEvent(evt);\n        }\n    },\n    fireWindowEvent: function(type, data) {\n        var evt = createEvent(type,data);\n        if (typeof windowEventHandlers[type] != 'undefined') {\n            setTimeout(function() {\n                windowEventHandlers[type].fire(evt);\n            }, 0);\n        } else {\n            window.dispatchEvent(evt);\n        }\n    },\n    // TODO: this is Android only; think about how to do this better\n    shuttingDown:false,\n    UsePolling:false,\n    // END TODO\n\n    // TODO: iOS only\n    // This queue holds the currently executing command and all pending\n    // commands executed with cordova.exec().\n    commandQueue:[],\n    // Indicates if we're currently in the middle of flushing the command\n    // queue on the native side.\n    commandQueueFlushing:false,\n    // END TODO\n    /**\n     * Plugin callback mechanism.\n     */\n    callbackId: 0,\n    callbacks:  {},\n    callbackStatus: {\n        NO_RESULT: 0,\n        OK: 1,\n        CLASS_NOT_FOUND_EXCEPTION: 2,\n        ILLEGAL_ACCESS_EXCEPTION: 3,\n        INSTANTIATION_EXCEPTION: 4,\n        MALFORMED_URL_EXCEPTION: 5,\n        IO_EXCEPTION: 6,\n        INVALID_ACTION: 7,\n        JSON_EXCEPTION: 8,\n        ERROR: 9\n    },\n\n    /**\n     * Called by native code when returning successful result from an action.\n     *\n     * @param callbackId\n     * @param args\n     */\n    callbackSuccess: function(callbackId, args) {\n        if (cordova.callbacks[callbackId]) {\n\n            // If result is to be sent to callback\n            if (args.status == cordova.callbackStatus.OK) {\n                try {\n                    if (cordova.callbacks[callbackId].success) {\n                        cordova.callbacks[callbackId].success(args.message);\n                    }\n                }\n                catch (e) {\n                    console.log(\"Error in success callback: \"+callbackId+\" = \"+e);\n                }\n            }\n\n            // Clear callback if not expecting any more results\n            if (!args.keepCallback) {\n                delete cordova.callbacks[callbackId];\n            }\n        }\n    },\n\n    /**\n     * Called by native code when returning error result from an action.\n     *\n     * @param callbackId\n     * @param args\n     */\n    callbackError: function(callbackId, args) {\n        if (cordova.callbacks[callbackId]) {\n            try {\n                if (cordova.callbacks[callbackId].fail) {\n                    cordova.callbacks[callbackId].fail(args.message);\n                }\n            }\n            catch (e) {\n                console.log(\"Error in error callback: \"+callbackId+\" = \"+e);\n            }\n\n            // Clear callback if not expecting any more results\n            if (!args.keepCallback) {\n                delete cordova.callbacks[callbackId];\n            }\n        }\n    },\n    addConstructor: function(func) {\n        channel.onCordovaReady.subscribeOnce(function() {\n            try {\n                func();\n            } catch(e) {\n                console.log(\"Failed to run constructor: \" + e);\n            }\n        });\n    }\n};\n\n// Register pause, resume and deviceready channels as events on document.\nchannel.onPause = cordova.addDocumentEventHandler('pause');\nchannel.onResume = cordova.addDocumentEventHandler('resume');\nchannel.onDeviceReady = cordova.addDocumentEventHandler('deviceready');\n\nmodule.exports = cordova;\n\n});\n\n//@ sourceURL=lib/cordova.js")} catch(e) {console.log("exception: in lib/cordova.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/builder\", function(require, exports, module) {\nvar utils = require('cordova/utils');\n\nfunction each(objects, func, context) {\n    for (var prop in objects) {\n        if (objects.hasOwnProperty(prop)) {\n            func.apply(context, [objects[prop], prop]);\n        }\n    }\n}\n\nfunction include(parent, objects, clobber, merge) {\n    each(objects, function (obj, key) {\n        try {\n          var result = obj.path ? require(obj.path) : {};\n\n          if (clobber) {\n              // Clobber if it doesn't exist.\n              if (typeof parent[key] === 'undefined') {\n                  parent[key] = result;\n              } else if (typeof obj.path !== 'undefined') {\n                  // If merging, merge properties onto parent, otherwise, clobber.\n                  if (merge) {\n                      recursiveMerge(parent[key], result);\n                  } else {\n                      parent[key] = result;\n                  }\n              }\n              result = parent[key];\n          } else {\n            // Overwrite if not currently defined.\n            if (typeof parent[key] == 'undefined') {\n              parent[key] = result;\n            } else if (merge && typeof obj.path !== 'undefined') {\n              // If merging, merge parent onto result\n              recursiveMerge(result, parent[key]);\n              parent[key] = result;\n            } else {\n              // Set result to what already exists, so we can build children into it if they exist.\n              result = parent[key];\n            }\n          }\n\n          if (obj.children) {\n            include(result, obj.children, clobber, merge);\n          }\n        } catch(e) {\n          utils.alert('Exception building cordova JS globals: ' + e + ' for key \"' + key + '\"');\n        }\n    });\n}\n\n/**\n * Merge properties from one object onto another recursively.  Properties from\n * the src object will overwrite existing target property.\n *\n * @param target Object to merge properties into.\n * @param src Object to merge properties from.\n */\nfunction recursiveMerge(target, src) {\n    for (var prop in src) {\n        if (src.hasOwnProperty(prop)) {\n            if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) {\n                // If the target object is a constructor override off prototype.\n                target.prototype[prop] = src[prop];\n            } else {\n                target[prop] = typeof src[prop] === 'object' ? recursiveMerge(\n                        target[prop], src[prop]) : src[prop];\n            }\n        }\n    }\n    return target;\n}\n\nmodule.exports = {\n    build: function (objects) {\n        return {\n            intoButDontClobber: function (target) {\n                include(target, objects, false, false);\n            },\n            intoAndClobber: function(target) {\n                include(target, objects, true, false);\n            },\n            intoAndMerge: function(target) {\n                include(target, objects, true, true);\n            }\n        };\n    }\n};\n\n});\n\n//@ sourceURL=lib/common/builder.js")} catch(e) {console.log("exception: in lib/common/builder.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/channel\", function(require, exports, module) {\nvar utils = require('cordova/utils');\n\n/**\n * Custom pub-sub \"channel\" that can have functions subscribed to it\n * This object is used to define and control firing of events for\n * cordova initialization.\n *\n * The order of events during page load and Cordova startup is as follows:\n *\n * onDOMContentLoaded         Internal event that is received when the web page is loaded and parsed.\n * onNativeReady              Internal event that indicates the Cordova native side is ready.\n * onCordovaReady             Internal event fired when all Cordova JavaScript objects have been created.\n * onCordovaInfoReady         Internal event fired when device properties are available.\n * onCordovaConnectionReady   Internal event fired when the connection property has been set.\n * onDeviceReady              User event fired to indicate that Cordova is ready\n * onResume                   User event fired to indicate a start/resume lifecycle event\n * onPause                    User event fired to indicate a pause lifecycle event\n * onDestroy                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).\n *\n * The only Cordova events that user code should register for are:\n *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript\n *      pause                 App has moved to background\n *      resume                App has returned to foreground\n *\n * Listeners can be registered as:\n *      document.addEventListener(\"deviceready\", myDeviceReadyListener, false);\n *      document.addEventListener(\"resume\", myResumeListener, false);\n *      document.addEventListener(\"pause\", myPauseListener, false);\n *\n * The DOM lifecycle events should be used for saving and restoring state\n *      window.onload\n *      window.onunload\n *\n */\n\n/**\n * Channel\n * @constructor\n * @param type  String the channel name\n * @param opts  Object options to pass into the channel, currently\n *                     supports:\n *                     onSubscribe: callback that fires when\n *                       something subscribes to the Channel. Sets\n *                       context to the Channel.\n *                     onUnsubscribe: callback that fires when\n *                       something unsubscribes to the Channel. Sets\n *                       context to the Channel.\n */\nvar Channel = function(type, opts) {\n    this.type = type;\n    this.handlers = {};\n    this.numHandlers = 0;\n    this.guid = 1;\n    this.fired = false;\n    this.enabled = true;\n    this.events = {\n        onSubscribe:null,\n        onUnsubscribe:null\n    };\n    if (opts) {\n        if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe;\n        if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe;\n    }\n},\n    channel = {\n        /**\n         * Calls the provided function only after all of the channels specified\n         * have been fired.\n         */\n        join: function (h, c) {\n            var i = c.length;\n            var len = i;\n            var f = function() {\n                if (!(--i)) h();\n            };\n            for (var j=0; j<len; j++) {\n                !c[j].fired?c[j].subscribeOnce(f):i--;\n            }\n            if (!i) h();\n        },\n        create: function (type, opts) {\n            channel[type] = new Channel(type, opts);\n            return channel[type];\n        },\n\n        /**\n         * cordova Channels that must fire before \"deviceready\" is fired.\n         */\n        deviceReadyChannelsArray: [],\n        deviceReadyChannelsMap: {},\n\n        /**\n         * Indicate that a feature needs to be initialized before it is ready to be used.\n         * This holds up Cordova's \"deviceready\" event until the feature has been initialized\n         * and Cordova.initComplete(feature) is called.\n         *\n         * @param feature {String}     The unique feature name\n         */\n        waitForInitialization: function(feature) {\n            if (feature) {\n                var c = null;\n                if (this[feature]) {\n                    c = this[feature];\n                }\n                else {\n                    c = this.create(feature);\n                }\n                this.deviceReadyChannelsMap[feature] = c;\n                this.deviceReadyChannelsArray.push(c);\n            }\n        },\n\n        /**\n         * Indicate that initialization code has completed and the feature is ready to be used.\n         *\n         * @param feature {String}     The unique feature name\n         */\n        initializationComplete: function(feature) {\n            var c = this.deviceReadyChannelsMap[feature];\n            if (c) {\n                c.fire();\n            }\n        }\n    };\n\nfunction forceFunction(f) {\n    if (f === null || f === undefined || typeof f != 'function') throw \"Function required as first argument!\";\n}\n\n/**\n * Subscribes the given function to the channel. Any time that\n * Channel.fire is called so too will the function.\n * Optionally specify an execution context for the function\n * and a guid that can be used to stop subscribing to the channel.\n * Returns the guid.\n */\nChannel.prototype.subscribe = function(f, c, g) {\n    // need a function to call\n    forceFunction(f);\n\n    var func = f;\n    if (typeof c == \"object\") { func = utils.close(c, f); }\n\n    g = g || func.observer_guid || f.observer_guid;\n    if (!g) {\n        // first time we've seen this subscriber\n        g = this.guid++;\n    }\n    else {\n        // subscriber already handled; dont set it twice\n        return g;\n    }\n    func.observer_guid = g;\n    f.observer_guid = g;\n    this.handlers[g] = func;\n    this.numHandlers++;\n    if (this.events.onSubscribe) this.events.onSubscribe.call(this);\n    if (this.fired) func.call(this);\n    return g;\n};\n\n/**\n * Like subscribe but the function is only called once and then it\n * auto-unsubscribes itself.\n */\nChannel.prototype.subscribeOnce = function(f, c) {\n    // need a function to call\n    forceFunction(f);\n\n    var g = null;\n    var _this = this;\n    var m = function() {\n        f.apply(c || null, arguments);\n        _this.unsubscribe(g);\n    };\n    if (this.fired) {\n        if (typeof c == \"object\") { f = utils.close(c, f); }\n        f.apply(this, this.fireArgs);\n    } else {\n        g = this.subscribe(m);\n    }\n    return g;\n};\n\n/**\n * Unsubscribes the function with the given guid from the channel.\n */\nChannel.prototype.unsubscribe = function(g) {\n    // need a function to unsubscribe\n    if (g === null || g === undefined) { throw \"You must pass _something_ into Channel.unsubscribe\"; }\n\n    if (typeof g == 'function') { g = g.observer_guid; }\n    var handler = this.handlers[g];\n    if (handler) {\n        if (handler.observer_guid) handler.observer_guid=null;\n        this.handlers[g] = null;\n        delete this.handlers[g];\n        this.numHandlers--;\n        if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);\n    }\n};\n\n/**\n * Calls all functions subscribed to this channel.\n */\nChannel.prototype.fire = function(e) {\n    if (this.enabled) {\n        var fail = false;\n        this.fired = true;\n        for (var item in this.handlers) {\n            var handler = this.handlers[item];\n            if (typeof handler == 'function') {\n                var rv = (handler.apply(this, arguments)===false);\n                fail = fail || rv;\n            }\n        }\n        this.fireArgs = arguments;\n        return !fail;\n    }\n    return true;\n};\n\n// defining them here so they are ready super fast!\n// DOM event that is received when the web page is loaded and parsed.\nchannel.create('onDOMContentLoaded');\n\n// Event to indicate the Cordova native side is ready.\nchannel.create('onNativeReady');\n\n// Event to indicate that all Cordova JavaScript objects have been created\n// and it's time to run plugin constructors.\nchannel.create('onCordovaReady');\n\n// Event to indicate that device properties are available\nchannel.create('onCordovaInfoReady');\n\n// Event to indicate that the connection property has been set.\nchannel.create('onCordovaConnectionReady');\n\n// Event to indicate that Cordova is ready\nchannel.create('onDeviceReady');\n\n// Event to indicate a resume lifecycle event\nchannel.create('onResume');\n\n// Event to indicate a pause lifecycle event\nchannel.create('onPause');\n\n// Event to indicate a destroy lifecycle event\nchannel.create('onDestroy');\n\n// Channels that must fire before \"deviceready\" is fired.\nchannel.waitForInitialization('onCordovaReady');\nchannel.waitForInitialization('onCordovaConnectionReady');\n\nmodule.exports = channel;\n\n});\n\n//@ sourceURL=lib/common/channel.js")} catch(e) {console.log("exception: in lib/common/channel.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/common\", function(require, exports, module) {\nmodule.exports = {\n    objects: {\n        cordova: {\n            path: 'cordova',\n            children: {\n                exec: {\n                    path: 'cordova/exec'\n                },\n                logger: {\n                    path: 'cordova/plugin/logger'\n                }\n            }\n        },\n        Cordova: {\n            children: {\n                exec: {\n                    path: 'cordova/exec'\n                }\n            }\n        },\n        PhoneGap:{\n            children: {\n                exec: {\n                    path: 'cordova/exec'\n                }\n            }\n        },\n        navigator: {\n            children: {\n                notification: {\n                    path: 'cordova/plugin/notification'\n                },\n                accelerometer: {\n                    path: 'cordova/plugin/accelerometer'\n                },\n                battery: {\n                    path: 'cordova/plugin/battery'\n                },\n                camera:{\n                    path: 'cordova/plugin/Camera'\n                },\n                compass:{\n                    path: 'cordova/plugin/compass'\n                },\n                contacts: {\n                    path: 'cordova/plugin/contacts'\n                },\n                device:{\n                    children:{\n                        capture: {\n                            path: 'cordova/plugin/capture'\n                        }\n                    }\n                },\n                geolocation: {\n                    path: 'cordova/plugin/geolocation'\n                },\n                network: {\n                    children: {\n                        connection: {\n                            path: 'cordova/plugin/network'\n                        }\n                    }\n                },\n                splashscreen: {\n                    path: 'cordova/plugin/splashscreen'\n                }\n            }\n        },\n        Acceleration: {\n            path: 'cordova/plugin/Acceleration'\n        },\n        Camera:{\n            path: 'cordova/plugin/CameraConstants'\n        },\n        CameraPopoverOptions: {\n            path: 'cordova/plugin/CameraPopoverOptions'\n        },\n        CaptureError: {\n            path: 'cordova/plugin/CaptureError'\n        },\n        CaptureAudioOptions:{\n            path: 'cordova/plugin/CaptureAudioOptions'\n        },\n        CaptureImageOptions: {\n            path: 'cordova/plugin/CaptureImageOptions'\n        },\n        CaptureVideoOptions: {\n            path: 'cordova/plugin/CaptureVideoOptions'\n        },\n        CompassHeading:{\n            path: 'cordova/plugin/CompassHeading'\n        },\n        CompassError:{\n            path: 'cordova/plugin/CompassError'\n        },\n        ConfigurationData: {\n            path: 'cordova/plugin/ConfigurationData'\n        },\n        Connection: {\n            path: 'cordova/plugin/Connection'\n        },\n        Contact: {\n            path: 'cordova/plugin/Contact'\n        },\n        ContactAddress: {\n            path: 'cordova/plugin/ContactAddress'\n        },\n        ContactError: {\n            path: 'cordova/plugin/ContactError'\n        },\n        ContactField: {\n            path: 'cordova/plugin/ContactField'\n        },\n        ContactFindOptions: {\n            path: 'cordova/plugin/ContactFindOptions'\n        },\n        ContactName: {\n            path: 'cordova/plugin/ContactName'\n        },\n        ContactOrganization: {\n            path: 'cordova/plugin/ContactOrganization'\n        },\n        Coordinates: {\n            path: 'cordova/plugin/Coordinates'\n        },\n        device: {\n            path: 'cordova/plugin/device'\n        },\n        DirectoryEntry: {\n            path: 'cordova/plugin/DirectoryEntry'\n        },\n        DirectoryReader: {\n            path: 'cordova/plugin/DirectoryReader'\n        },\n        Entry: {\n            path: 'cordova/plugin/Entry'\n        },\n        File: {\n            path: 'cordova/plugin/File'\n        },\n        FileEntry: {\n            path: 'cordova/plugin/FileEntry'\n        },\n        FileError: {\n            path: 'cordova/plugin/FileError'\n        },\n        FileReader: {\n            path: 'cordova/plugin/FileReader'\n        },\n        FileSystem: {\n            path: 'cordova/plugin/FileSystem'\n        },\n        FileTransfer: {\n            path: 'cordova/plugin/FileTransfer'\n        },\n        FileTransferError: {\n            path: 'cordova/plugin/FileTransferError'\n        },\n        FileUploadOptions: {\n            path: 'cordova/plugin/FileUploadOptions'\n        },\n        FileUploadResult: {\n            path: 'cordova/plugin/FileUploadResult'\n        },\n        FileWriter: {\n            path: 'cordova/plugin/FileWriter'\n        },\n        Flags: {\n            path: 'cordova/plugin/Flags'\n        },\n        LocalFileSystem: {\n            path: 'cordova/plugin/LocalFileSystem'\n        },\n        Media: {\n            path: 'cordova/plugin/Media'\n        },\n        MediaError: {\n            path: 'cordova/plugin/MediaError'\n        },\n        MediaFile: {\n            path: 'cordova/plugin/MediaFile'\n        },\n        MediaFileData:{\n            path: 'cordova/plugin/MediaFileData'\n        },\n        Metadata:{\n            path: 'cordova/plugin/Metadata'\n        },\n        Position: {\n            path: 'cordova/plugin/Position'\n        },\n        PositionError: {\n            path: 'cordova/plugin/PositionError'\n        },\n        ProgressEvent: {\n            path: 'cordova/plugin/ProgressEvent'\n        },\n        requestFileSystem:{\n            path: 'cordova/plugin/requestFileSystem'\n        },\n        resolveLocalFileSystemURI:{\n            path: 'cordova/plugin/resolveLocalFileSystemURI'\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/common/common.js")} catch(e) {console.log("exception: in lib/common/common.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/exec\", function(require, exports, module) {\n/**\n * Execute a cordova command.  It is up to the native side whether this action\n * is synchronous or asynchronous.  The native side can return:\n *      Synchronous: PluginResult object as a JSON string\n *      Asynchrounous: Empty string \"\"\n * If async, the native side will cordova.callbackSuccess or cordova.callbackError,\n * depending upon the result of the action.\n *\n * @param {Function} successCB  The success callback\n * @param {Function} failCB     The fail callback\n * @param {String} service      The name of the service to use\n * @param {String} action       Action to be run in cordova\n * @param {String[]} [args]     Zero or more arguments to pass to the method\n */\n\nvar tizen = require('cordova/plugin/tizen/manager'),\n    cordova = require('cordova'),\n    utils = require('cordova/utils');\n\nmodule.exports = function(successCB, failCB, service, action, args) {\n\n    try {\n        var v = tizen.exec(successCB, failCB, service, action, args);\n\n        // If status is OK, then return value back to caller\n        if (v.status == cordova.callbackStatus.OK) {\n\n            // If there is a success callback, then call it now with returned value\n            if (successCB) {\n                try {\n                    successCB(v.message);\n                }\n                catch (e) {\n                    console.log(\"Error in success callback: \"+ service + \".\" + action + \" = \" + e);\n                }\n\n            }\n            return v.message;\n        } else if (v.status == cordova.callbackStatus.NO_RESULT) {\n            // Nothing to do here\n        } else {\n            // If error, then display error\n            console.log(\"Error: \" + service + \".\" + action + \" Status=\" + v.status + \" Message=\" + v.message);\n\n            // If there is a fail callback, then call it now with returned value\n            if (failCB) {\n                try {\n                    failCB(v.message);\n                }\n                catch (e) {\n                    console.log(\"Error in error callback: \" + service + \".\" + action + \" = \"+e);\n                }\n            }\n            return null;\n        }\n    } catch (e) {\n        utils.alert(\"Error: \" + e);\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/exec.js")} catch(e) {console.log("exception: in lib/tizen/exec.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/platform\", function(require, exports, module) {\nmodule.exports = {\n    id: \"tizen\",\n    initialize: function() {},\n    objects: {\n        device: {\n            path: \"cordova/plugin/tizen/Device\"\n        },\n        File: { // exists natively, override\n            path: \"cordova/plugin/File\"\n        },\n        FileReader: { // exists natively, override\n            path: \"cordova/plugin/FileReader\"\n        },\n        FileError: { //exists natively, override\n            path: \"cordova/plugin/FileError\"\n        }\n    },\n    merges: {\n        MediaError: { // exists natively\n            path: \"cordova/plugin/tizen/MediaError\"\n        },\n        navigator: {\n            children: {\n                device: {\n                    path: \"cordova/plugin/tizen/Device\"\n                },\n                contacts: {\n                    path: \"cordova/plugin/tizen/contacts\"\n                },\n               notification: {\n                   path: \"cordova/plugin/tizen/Notification\"\n               }\n            }\n        },\n        Contact: {\n            path: \"cordova/plugin/tizen/Contact\"\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/platform.js")} catch(e) {console.log("exception: in lib/tizen/platform.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Acceleration\", function(require, exports, module) {\nvar Acceleration = function(x, y, z, timestamp) {\n    this.x = x;\n    this.y = y;\n    this.z = z;\n    this.timestamp = timestamp || (new Date()).getTime();\n};\n\nmodule.exports = Acceleration;\n\n});\n\n//@ sourceURL=lib/common/plugin/Acceleration.js")} catch(e) {console.log("exception: in lib/common/plugin/Acceleration.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Camera\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    Camera = require('cordova/plugin/CameraConstants');\n\nvar cameraExport = {};\n\n// Tack on the Camera Constants to the base camera plugin.\nfor (var key in Camera) {\n    cameraExport[key] = Camera[key];\n}\n\n/**\n * Gets a picture from source defined by \"options.sourceType\", and returns the\n * image as defined by the \"options.destinationType\" option.\n\n * The defaults are sourceType=CAMERA and destinationType=FILE_URI.\n *\n * @param {Function} successCallback\n * @param {Function} errorCallback\n * @param {Object} options\n */\ncameraExport.getPicture = function(successCallback, errorCallback, options) {\n    // successCallback required\n    if (typeof successCallback != \"function\") {\n        console.log(\"Camera Error: successCallback is not a function\");\n        return;\n    }\n\n    // errorCallback optional\n    if (errorCallback && (typeof errorCallback != \"function\")) {\n        console.log(\"Camera Error: errorCallback is not a function\");\n        return;\n    }\n\n    var quality = 50;\n    if (options && typeof options.quality == \"number\") {\n        quality = options.quality;\n    } else if (options && typeof options.quality == \"string\") {\n        var qlity = parseInt(options.quality, 10);\n        if (isNaN(qlity) === false) {\n            quality = qlity.valueOf();\n        }\n    }\n\n    var destinationType = Camera.DestinationType.FILE_URI;\n    if (typeof options.destinationType == \"number\") {\n        destinationType = options.destinationType;\n    }\n\n    var sourceType = Camera.PictureSourceType.CAMERA;\n    if (typeof options.sourceType == \"number\") {\n        sourceType = options.sourceType;\n    }\n\n    var targetWidth = -1;\n    if (typeof options.targetWidth == \"number\") {\n        targetWidth = options.targetWidth;\n    } else if (typeof options.targetWidth == \"string\") {\n        var width = parseInt(options.targetWidth, 10);\n        if (isNaN(width) === false) {\n            targetWidth = width.valueOf();\n        }\n    }\n\n    var targetHeight = -1;\n    if (typeof options.targetHeight == \"number\") {\n        targetHeight = options.targetHeight;\n    } else if (typeof options.targetHeight == \"string\") {\n        var height = parseInt(options.targetHeight, 10);\n        if (isNaN(height) === false) {\n            targetHeight = height.valueOf();\n        }\n    }\n\n    var encodingType = Camera.EncodingType.JPEG;\n    if (typeof options.encodingType == \"number\") {\n        encodingType = options.encodingType;\n    }\n\n    var mediaType = Camera.MediaType.PICTURE;\n    if (typeof options.mediaType == \"number\") {\n        mediaType = options.mediaType;\n    }\n    var allowEdit = false;\n    if (typeof options.allowEdit == \"boolean\") {\n        allowEdit = options.allowEdit;\n    } else if (typeof options.allowEdit == \"number\") {\n        allowEdit = options.allowEdit <= 0 ? false : true;\n    }\n    var correctOrientation = false;\n    if (typeof options.correctOrientation == \"boolean\") {\n        correctOrientation = options.correctOrientation;\n    } else if (typeof options.correctOrientation == \"number\") {\n        correctOrientation = options.correctOrientation <=0 ? false : true;\n    }\n    var saveToPhotoAlbum = false;\n    if (typeof options.saveToPhotoAlbum == \"boolean\") {\n        saveToPhotoAlbum = options.saveToPhotoAlbum;\n    } else if (typeof options.saveToPhotoAlbum == \"number\") {\n        saveToPhotoAlbum = options.saveToPhotoAlbum <=0 ? false : true;\n    }\n    var popoverOptions = null;\n    if (typeof options.popoverOptions == \"object\") {\n        popoverOptions = options.popoverOptions;\n    }\n\n    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,\n                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];\n\n    exec(successCallback, errorCallback, \"Camera\", \"takePicture\", args);\n};\n\ncameraExport.cleanup = function(successCallback, errorCallback) {\n    exec(successCallback, errorCallback, \"Camera\", \"cleanup\", []);\n};\n\nmodule.exports = cameraExport;\n});\n\n//@ sourceURL=lib/common/plugin/Camera.js")} catch(e) {console.log("exception: in lib/common/plugin/Camera.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CameraConstants\", function(require, exports, module) {\nmodule.exports = {\n  DestinationType:{\n    DATA_URL: 0,         // Return base64 encoded string\n    FILE_URI: 1          // Return file uri (content://media/external/images/media/2 for Android)\n  },\n  EncodingType:{\n    JPEG: 0,             // Return JPEG encoded image\n    PNG: 1               // Return PNG encoded image\n  },\n  MediaType:{\n    PICTURE: 0,          // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType\n    VIDEO: 1,            // allow selection of video only, ONLY RETURNS URL\n    ALLMEDIA : 2         // allow selection from all media types\n  },\n  PictureSourceType:{\n    PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)\n    CAMERA : 1,          // Take picture from camera\n    SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)\n  },\n  PopoverArrowDirection:{\n      ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover\n      ARROW_DOWN : 2,\n      ARROW_LEFT : 4,\n      ARROW_RIGHT : 8,\n      ARROW_ANY : 15\n  }\n};\n});\n\n//@ sourceURL=lib/common/plugin/CameraConstants.js")} catch(e) {console.log("exception: in lib/common/plugin/CameraConstants.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CameraPopoverOptions\", function(require, exports, module) {\nvar Camera = require('cordova/plugin/CameraConstants');\n\n/**\n * Encapsulates options for iOS Popover image picker\n */\nvar CameraPopoverOptions = function(x,y,width,height,arrowDir){\n    // information of rectangle that popover should be anchored to\n    this.x = x || 0;\n    this.y = y || 32;\n    this.width = width || 320;\n    this.height = height || 480;\n    // The direction of the popover arrow\n    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;\n};\n\nmodule.exports = CameraPopoverOptions;\n});\n\n//@ sourceURL=lib/common/plugin/CameraPopoverOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/CameraPopoverOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureAudioOptions\", function(require, exports, module) {\n/**\n * Encapsulates all audio capture operation configuration options.\n */\nvar CaptureAudioOptions = function(){\n    // Upper limit of sound clips user can record. Value must be equal or greater than 1.\n    this.limit = 1;\n    // Maximum duration of a single sound clip in seconds.\n    this.duration = 0;\n    // The selected audio mode. Must match with one of the elements in supportedAudioModes array.\n    this.mode = null;\n};\n\nmodule.exports = CaptureAudioOptions;\n});\n\n//@ sourceURL=lib/common/plugin/CaptureAudioOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/CaptureAudioOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureError\", function(require, exports, module) {\n/**\n * The CaptureError interface encapsulates all errors in the Capture API.\n */\nvar CaptureError = function(c) {\n   this.code = c || null;\n};\n\n// Camera or microphone failed to capture image or sound.\nCaptureError.CAPTURE_INTERNAL_ERR = 0;\n// Camera application or audio capture application is currently serving other capture request.\nCaptureError.CAPTURE_APPLICATION_BUSY = 1;\n// Invalid use of the API (e.g. limit parameter has value less than one).\nCaptureError.CAPTURE_INVALID_ARGUMENT = 2;\n// User exited camera application or audio capture application before capturing anything.\nCaptureError.CAPTURE_NO_MEDIA_FILES = 3;\n// The requested capture operation is not supported.\nCaptureError.CAPTURE_NOT_SUPPORTED = 20;\n\nmodule.exports = CaptureError;\n});\n\n//@ sourceURL=lib/common/plugin/CaptureError.js")} catch(e) {console.log("exception: in lib/common/plugin/CaptureError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureImageOptions\", function(require, exports, module) {\n/**\n * Encapsulates all image capture operation configuration options.\n */\nvar CaptureImageOptions = function(){\n    // Upper limit of images user can take. Value must be equal or greater than 1.\n    this.limit = 1;\n    // The selected image mode. Must match with one of the elements in supportedImageModes array.\n    this.mode = null;\n};\n\nmodule.exports = CaptureImageOptions;\n});\n\n//@ sourceURL=lib/common/plugin/CaptureImageOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/CaptureImageOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureVideoOptions\", function(require, exports, module) {\n/**\n * Encapsulates all video capture operation configuration options.\n */\nvar CaptureVideoOptions = function(){\n    // Upper limit of videos user can record. Value must be equal or greater than 1.\n    this.limit = 1;\n    // Maximum duration of a single video clip in seconds.\n    this.duration = 0;\n    // The selected video mode. Must match with one of the elements in supportedVideoModes array.\n    this.mode = null;\n};\n\nmodule.exports = CaptureVideoOptions;\n});\n\n//@ sourceURL=lib/common/plugin/CaptureVideoOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/CaptureVideoOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CompassError\", function(require, exports, module) {\n/**\n *  CompassError.\n *  An error code assigned by an implementation when an error has occured\n * @constructor\n */\nvar CompassError = function(err) {\n    this.code = (err !== undefined ? err : null);\n};\n\nCompassError.COMPASS_INTERNAL_ERR = 0;\nCompassError.COMPASS_NOT_SUPPORTED = 20;\n\nmodule.exports = CompassError;\n});\n\n//@ sourceURL=lib/common/plugin/CompassError.js")} catch(e) {console.log("exception: in lib/common/plugin/CompassError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CompassHeading\", function(require, exports, module) {\nvar CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {\n  this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null);\n  this.trueHeading = (trueHeading !== undefined ? trueHeading : null);\n  this.headingAccuracy = (headingAccuracy !== undefined ? headingAccuracy : null);\n  this.timestamp = (timestamp !== undefined ? timestamp : new Date().getTime());\n};\n\nmodule.exports = CompassHeading;\n});\n\n//@ sourceURL=lib/common/plugin/CompassHeading.js")} catch(e) {console.log("exception: in lib/common/plugin/CompassHeading.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ConfigurationData\", function(require, exports, module) {\n/**\n * Encapsulates a set of parameters that the capture device supports.\n */\nfunction ConfigurationData() {\n    // The ASCII-encoded string in lower case representing the media type.\n    this.type = null;\n    // The height attribute represents height of the image or video in pixels.\n    // In the case of a sound clip this attribute has value 0.\n    this.height = 0;\n    // The width attribute represents width of the image or video in pixels.\n    // In the case of a sound clip this attribute has value 0\n    this.width = 0;\n}\n\nmodule.exports = ConfigurationData;\n});\n\n//@ sourceURL=lib/common/plugin/ConfigurationData.js")} catch(e) {console.log("exception: in lib/common/plugin/ConfigurationData.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Connection\", function(require, exports, module) {\n/**\n * Network status\n */\nmodule.exports = {\n        UNKNOWN: \"unknown\",\n        ETHERNET: \"ethernet\",\n        WIFI: \"wifi\",\n        CELL_2G: \"2g\",\n        CELL_3G: \"3g\",\n        CELL_4G: \"4g\",\n        NONE: \"none\"\n};\n});\n\n//@ sourceURL=lib/common/plugin/Connection.js")} catch(e) {console.log("exception: in lib/common/plugin/Connection.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Contact\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    ContactError = require('cordova/plugin/ContactError'),\n    utils = require('cordova/utils');\n\n/**\n* Converts primitives into Complex Object\n* Currently only used for Date fields\n*/\nfunction convertIn(contact) {\n    var value = contact.birthday;\n    try {\n      contact.birthday = new Date(parseFloat(value));\n    } catch (exception){\n      console.log(\"Cordova Contact convertIn error: exception creating date.\");\n    }\n    return contact;\n}\n\n/**\n* Converts Complex objects into primitives\n* Only conversion at present is for Dates.\n**/\n\nfunction convertOut(contact) {\n    var value = contact.birthday;\n    if (value !== null) {\n        // try to make it a Date object if it is not already\n        if (!utils.isDate(value)){\n            try {\n                value = new Date(value);\n            } catch(exception){\n                value = null;\n            }\n        }\n        if (utils.isDate(value)){\n            value = value.valueOf(); // convert to milliseconds\n        }\n        contact.birthday = value;\n    }\n    return contact;\n}\n\n/**\n* Contains information about a single contact.\n* @constructor\n* @param {DOMString} id unique identifier\n* @param {DOMString} displayName\n* @param {ContactName} name\n* @param {DOMString} nickname\n* @param {Array.<ContactField>} phoneNumbers array of phone numbers\n* @param {Array.<ContactField>} emails array of email addresses\n* @param {Array.<ContactAddress>} addresses array of addresses\n* @param {Array.<ContactField>} ims instant messaging user ids\n* @param {Array.<ContactOrganization>} organizations\n* @param {DOMString} birthday contact's birthday\n* @param {DOMString} note user notes about contact\n* @param {Array.<ContactField>} photos\n* @param {Array.<ContactField>} categories\n* @param {Array.<ContactField>} urls contact's web sites\n*/\nvar Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,\n    ims, organizations, birthday, note, photos, categories, urls) {\n    this.id = id || null;\n    this.rawId = null;\n    this.displayName = displayName || null;\n    this.name = name || null; // ContactName\n    this.nickname = nickname || null;\n    this.phoneNumbers = phoneNumbers || null; // ContactField[]\n    this.emails = emails || null; // ContactField[]\n    this.addresses = addresses || null; // ContactAddress[]\n    this.ims = ims || null; // ContactField[]\n    this.organizations = organizations || null; // ContactOrganization[]\n    this.birthday = birthday || null;\n    this.note = note || null;\n    this.photos = photos || null; // ContactField[]\n    this.categories = categories || null; // ContactField[]\n    this.urls = urls || null; // ContactField[]\n};\n\n/**\n* Removes contact from device storage.\n* @param successCB success callback\n* @param errorCB error callback\n*/\nContact.prototype.remove = function(successCB, errorCB) {\n    var fail = function(code) {\n        errorCB(new ContactError(code));\n    };\n    if (this.id === null) {\n        fail(ContactError.UNKNOWN_ERROR);\n    }\n    else {\n        exec(successCB, fail, \"Contacts\", \"remove\", [this.id]);\n    }\n};\n\n/**\n* Creates a deep copy of this Contact.\n* With the contact ID set to null.\n* @return copy of this Contact\n*/\nContact.prototype.clone = function() {\n    var clonedContact = utils.clone(this);\n    var i;\n    clonedContact.id = null;\n    clonedContact.rawId = null;\n    // Loop through and clear out any id's in phones, emails, etc.\n    if (clonedContact.phoneNumbers) {\n        for (i = 0; i < clonedContact.phoneNumbers.length; i++) {\n            clonedContact.phoneNumbers[i].id = null;\n        }\n    }\n    if (clonedContact.emails) {\n        for (i = 0; i < clonedContact.emails.length; i++) {\n            clonedContact.emails[i].id = null;\n        }\n    }\n    if (clonedContact.addresses) {\n        for (i = 0; i < clonedContact.addresses.length; i++) {\n            clonedContact.addresses[i].id = null;\n        }\n    }\n    if (clonedContact.ims) {\n        for (i = 0; i < clonedContact.ims.length; i++) {\n            clonedContact.ims[i].id = null;\n        }\n    }\n    if (clonedContact.organizations) {\n        for (i = 0; i < clonedContact.organizations.length; i++) {\n            clonedContact.organizations[i].id = null;\n        }\n    }\n    if (clonedContact.categories) {\n        for (i = 0; i < clonedContact.categories.length; i++) {\n            clonedContact.categories[i].id = null;\n        }\n    }\n    if (clonedContact.photos) {\n        for (i = 0; i < clonedContact.photos.length; i++) {\n            clonedContact.photos[i].id = null;\n        }\n    }\n    if (clonedContact.urls) {\n        for (i = 0; i < clonedContact.urls.length; i++) {\n            clonedContact.urls[i].id = null;\n        }\n    }\n    return clonedContact;\n};\n\n/**\n* Persists contact to device storage.\n* @param successCB success callback\n* @param errorCB error callback\n*/\nContact.prototype.save = function(successCB, errorCB) {\n  var fail = function(code) {\n      errorCB(new ContactError(code));\n  };\n    var success = function(result) {\n      if (result) {\n          if (typeof successCB === 'function') {\n              var fullContact = require('cordova/plugin/contacts').create(result);\n              successCB(convertIn(fullContact));\n          }\n      }\n      else {\n          // no Entry object returned\n          fail(ContactError.UNKNOWN_ERROR);\n      }\n  };\n    var dupContact = convertOut(utils.clone(this));\n    exec(success, fail, \"Contacts\", \"save\", [dupContact]);\n};\n\n\nmodule.exports = Contact;\n\n});\n\n//@ sourceURL=lib/common/plugin/Contact.js")} catch(e) {console.log("exception: in lib/common/plugin/Contact.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactAddress\", function(require, exports, module) {\n/**\n* Contact address.\n* @constructor\n* @param {DOMString} id unique identifier, should only be set by native code\n* @param formatted // NOTE: not a W3C standard\n* @param streetAddress\n* @param locality\n* @param region\n* @param postalCode\n* @param country\n*/\n\nvar ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {\n    this.id = null;\n    this.pref = (typeof pref != 'undefined' ? pref : false);\n    this.type = type || null;\n    this.formatted = formatted || null;\n    this.streetAddress = streetAddress || null;\n    this.locality = locality || null;\n    this.region = region || null;\n    this.postalCode = postalCode || null;\n    this.country = country || null;\n};\n\nmodule.exports = ContactAddress;\n});\n\n//@ sourceURL=lib/common/plugin/ContactAddress.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactAddress.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactError\", function(require, exports, module) {\n/**\n *  ContactError.\n *  An error code assigned by an implementation when an error has occured\n * @constructor\n */\nvar ContactError = function(err) {\n    this.code = (typeof err != 'undefined' ? err : null);\n};\n\n/**\n * Error codes\n */\nContactError.UNKNOWN_ERROR = 0;\nContactError.INVALID_ARGUMENT_ERROR = 1;\nContactError.TIMEOUT_ERROR = 2;\nContactError.PENDING_OPERATION_ERROR = 3;\nContactError.IO_ERROR = 4;\nContactError.NOT_SUPPORTED_ERROR = 5;\nContactError.PERMISSION_DENIED_ERROR = 20;\n\nmodule.exports = ContactError;\n});\n\n//@ sourceURL=lib/common/plugin/ContactError.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactField\", function(require, exports, module) {\n/**\n* Generic contact field.\n* @constructor\n* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard\n* @param type\n* @param value\n* @param pref\n*/\nvar ContactField = function(type, value, pref) {\n    this.id = null;\n    this.type = (type && type.toString()) || null;\n    this.value = (value && value.toString()) || null;\n    this.pref = (typeof pref != 'undefined' ? pref : false);\n};\n\nmodule.exports = ContactField;\n});\n\n//@ sourceURL=lib/common/plugin/ContactField.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactField.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactFindOptions\", function(require, exports, module) {\n/**\n * ContactFindOptions.\n * @constructor\n * @param filter used to match contacts against\n * @param multiple boolean used to determine if more than one contact should be returned\n */\n\nvar ContactFindOptions = function(filter, multiple) {\n    this.filter = filter || '';\n    this.multiple = (typeof multiple != 'undefined' ? multiple : false);\n};\n\nmodule.exports = ContactFindOptions;\n});\n\n//@ sourceURL=lib/common/plugin/ContactFindOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactFindOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactName\", function(require, exports, module) {\n/**\n* Contact name.\n* @constructor\n* @param formatted // NOTE: not part of W3C standard\n* @param familyName\n* @param givenName\n* @param middle\n* @param prefix\n* @param suffix\n*/\nvar ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {\n    this.formatted = formatted || null;\n    this.familyName = familyName || null;\n    this.givenName = givenName || null;\n    this.middleName = middle || null;\n    this.honorificPrefix = prefix || null;\n    this.honorificSuffix = suffix || null;\n};\n\nmodule.exports = ContactName;\n});\n\n//@ sourceURL=lib/common/plugin/ContactName.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactName.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactOrganization\", function(require, exports, module) {\n/**\n* Contact organization.\n* @constructor\n* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard\n* @param name\n* @param dept\n* @param title\n* @param startDate\n* @param endDate\n* @param location\n* @param desc\n*/\n\nvar ContactOrganization = function(pref, type, name, dept, title) {\n    this.id = null;\n    this.pref = (typeof pref != 'undefined' ? pref : false);\n    this.type = type || null;\n    this.name = name || null;\n    this.department = dept || null;\n    this.title = title || null;\n};\n\nmodule.exports = ContactOrganization;\n});\n\n//@ sourceURL=lib/common/plugin/ContactOrganization.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactOrganization.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Coordinates\", function(require, exports, module) {\n/**\n * This class contains position information.\n * @param {Object} lat\n * @param {Object} lng\n * @param {Object} alt\n * @param {Object} acc\n * @param {Object} head\n * @param {Object} vel\n * @param {Object} altacc\n * @constructor\n */\nvar Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {\n    /**\n     * The latitude of the position.\n     */\n    this.latitude = lat;\n    /**\n     * The longitude of the position,\n     */\n    this.longitude = lng;\n    /**\n     * The accuracy of the position.\n     */\n    this.accuracy = acc;\n    /**\n     * The altitude of the position.\n     */\n    this.altitude = (alt !== undefined ? alt : null);\n    /**\n     * The direction the device is moving at the position.\n     */\n    this.heading = (head !== undefined ? head : null);\n    /**\n     * The velocity with which the device is moving at the position.\n     */\n    this.speed = (vel !== undefined ? vel : null);\n\n    if (this.speed === 0 || this.speed === null) {\n        this.heading = NaN;\n    }\n\n    /**\n     * The altitude accuracy of the position.\n     */\n    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;\n};\n\nmodule.exports = Coordinates;\n\n});\n\n//@ sourceURL=lib/common/plugin/Coordinates.js")} catch(e) {console.log("exception: in lib/common/plugin/Coordinates.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/DirectoryEntry\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    Entry = require('cordova/plugin/Entry'),\n    FileError = require('cordova/plugin/FileError'),\n    DirectoryReader = require('cordova/plugin/DirectoryReader');\n\n/**\n * An interface representing a directory on the file system.\n *\n * {boolean} isFile always false (readonly)\n * {boolean} isDirectory always true (readonly)\n * {DOMString} name of the directory, excluding the path leading to it (readonly)\n * {DOMString} fullPath the absolute full path to the directory (readonly)\n * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)\n */\nvar DirectoryEntry = function(name, fullPath) {\n     DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]);\n};\n\nutils.extend(DirectoryEntry, Entry);\n\n/**\n * Creates a new DirectoryReader to read entries from this directory\n */\nDirectoryEntry.prototype.createReader = function() {\n    return new DirectoryReader(this.fullPath);\n};\n\n/**\n * Creates or looks up a directory\n *\n * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory\n * @param {Flags} options to create or excluively create the directory\n * @param {Function} successCallback is called with the new entry\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var entry = new DirectoryEntry(result.name, result.fullPath);\n        successCallback(entry);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getDirectory\", [this.fullPath, path, options]);\n};\n\n/**\n * Deletes a directory and all of it's contents\n *\n * @param {Function} successCallback is called with no parameters\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(successCallback, fail, \"File\", \"removeRecursively\", [this.fullPath]);\n};\n\n/**\n * Creates or looks up a file\n *\n * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file\n * @param {Flags} options to create or excluively create the file\n * @param {Function} successCallback is called with the new entry\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var FileEntry = require('cordova/plugin/FileEntry');\n        var entry = new FileEntry(result.name, result.fullPath);\n        successCallback(entry);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getFile\", [this.fullPath, path, options]);\n};\n\nmodule.exports = DirectoryEntry;\n\n});\n\n//@ sourceURL=lib/common/plugin/DirectoryEntry.js")} catch(e) {console.log("exception: in lib/common/plugin/DirectoryEntry.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/DirectoryReader\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError') ;\n\n/**\n * An interface that lists the files and directories in a directory.\n */\nfunction DirectoryReader(path) {\n    this.path = path || null;\n}\n\n/**\n * Returns a list of entries from a directory.\n *\n * @param {Function} successCallback is called with a list of entries\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var retVal = [];\n        for (var i=0; i<result.length; i++) {\n            var entry = null;\n            if (result[i].isDirectory) {\n                entry = new (require('cordova/plugin/DirectoryEntry'))();\n            }\n            else if (result[i].isFile) {\n                entry = new (require('cordova/plugin/FileEntry'))();\n            }\n            entry.isDirectory = result[i].isDirectory;\n            entry.isFile = result[i].isFile;\n            entry.name = result[i].name;\n            entry.fullPath = result[i].fullPath;\n            retVal.push(entry);\n        }\n        successCallback(retVal);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"readEntries\", [this.path]);\n};\n\nmodule.exports = DirectoryReader;\n\n});\n\n//@ sourceURL=lib/common/plugin/DirectoryReader.js")} catch(e) {console.log("exception: in lib/common/plugin/DirectoryReader.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Entry\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError'),\n    Metadata = require('cordova/plugin/Metadata');\n\n/**\n * Represents a file or directory on the local file system.\n *\n * @param isFile\n *            {boolean} true if Entry is a file (readonly)\n * @param isDirectory\n *            {boolean} true if Entry is a directory (readonly)\n * @param name\n *            {DOMString} name of the file or directory, excluding the path\n *            leading to it (readonly)\n * @param fullPath\n *            {DOMString} the absolute full path to the file or directory\n *            (readonly)\n */\nfunction Entry(isFile, isDirectory, name, fullPath, fileSystem) {\n    this.isFile = (typeof isFile != 'undefined'?isFile:false);\n    this.isDirectory = (typeof isDirectory != 'undefined'?isDirectory:false);\n    this.name = name || '';\n    this.fullPath = fullPath || '';\n    this.filesystem = fileSystem || null;\n}\n\n/**\n * Look up the metadata of the entry.\n *\n * @param successCallback\n *            {Function} is called with a Metadata object\n * @param errorCallback\n *            {Function} is called with a FileError\n */\nEntry.prototype.getMetadata = function(successCallback, errorCallback) {\n  var success = typeof successCallback !== 'function' ? null : function(lastModified) {\n      var metadata = new Metadata(lastModified);\n      successCallback(metadata);\n  };\n  var fail = typeof errorCallback !== 'function' ? null : function(code) {\n      errorCallback(new FileError(code));\n  };\n\n  exec(success, fail, \"File\", \"getMetadata\", [this.fullPath]);\n};\n\n/**\n * Set the metadata of the entry.\n *\n * @param successCallback\n *            {Function} is called with a Metadata object\n * @param errorCallback\n *            {Function} is called with a FileError\n * @param metadataObject\n *            {Object} keys and values to set\n */\nEntry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {\n\n  exec(successCallback, errorCallback, \"File\", \"setMetadata\", [this.fullPath, metadataObject]);\n};\n\n/**\n * Move a file or directory to a new location.\n *\n * @param parent\n *            {DirectoryEntry} the directory to which to move this entry\n * @param newName\n *            {DOMString} new name of the entry, defaults to the current name\n * @param successCallback\n *            {Function} called with the new DirectoryEntry object\n * @param errorCallback\n *            {Function} called with a FileError\n */\nEntry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {\n    var fail = function(code) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(code));\n        }\n    };\n    // user must specify parent Entry\n    if (!parent) {\n        fail(FileError.NOT_FOUND_ERR);\n        return;\n    }\n    // source path\n    var srcPath = this.fullPath,\n        // entry name\n        name = newName || this.name,\n        success = function(entry) {\n            if (entry) {\n                if (typeof successCallback === 'function') {\n                    // create appropriate Entry object\n                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);\n                    try {\n                        successCallback(result);\n                    }\n                    catch (e) {\n                        console.log('Error invoking callback: ' + e);\n                    }\n                }\n            }\n            else {\n                // no Entry object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n\n    // copy\n    exec(success, fail, \"File\", \"moveTo\", [srcPath, parent.fullPath, name]);\n};\n\n/**\n * Copy a directory to a different location.\n *\n * @param parent\n *            {DirectoryEntry} the directory to which to copy the entry\n * @param newName\n *            {DOMString} new name of the entry, defaults to the current name\n * @param successCallback\n *            {Function} called with the new Entry object\n * @param errorCallback\n *            {Function} called with a FileError\n */\nEntry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {\n    var fail = function(code) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(code));\n        }\n    };\n\n    // user must specify parent Entry\n    if (!parent) {\n        fail(FileError.NOT_FOUND_ERR);\n        return;\n    }\n\n        // source path\n    var srcPath = this.fullPath,\n        // entry name\n        name = newName || this.name,\n        // success callback\n        success = function(entry) {\n            if (entry) {\n                if (typeof successCallback === 'function') {\n                    // create appropriate Entry object\n                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);\n                    try {\n                        successCallback(result);\n                    }\n                    catch (e) {\n                        console.log('Error invoking callback: ' + e);\n                    }\n                }\n            }\n            else {\n                // no Entry object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n\n    // copy\n    exec(success, fail, \"File\", \"copyTo\", [srcPath, parent.fullPath, name]);\n};\n\n/**\n * Return a URL that can be used to identify this entry.\n */\nEntry.prototype.toURL = function() {\n    // fullPath attribute contains the full URL\n    return this.fullPath;\n};\n\n/**\n * Returns a URI that can be used to identify this entry.\n *\n * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.\n * @return uri\n */\nEntry.prototype.toURI = function(mimeType) {\n    console.log(\"DEPRECATED: Update your code to use 'toURL'\");\n    // fullPath attribute contains the full URI\n    return this.toURL();\n};\n\n/**\n * Remove a file or directory. It is an error to attempt to delete a\n * directory that is not empty. It is an error to attempt to delete a\n * root directory of a file system.\n *\n * @param successCallback {Function} called with no parameters\n * @param errorCallback {Function} called with a FileError\n */\nEntry.prototype.remove = function(successCallback, errorCallback) {\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(successCallback, fail, \"File\", \"remove\", [this.fullPath]);\n};\n\n/**\n * Look up the parent DirectoryEntry of this entry.\n *\n * @param successCallback {Function} called with the parent DirectoryEntry object\n * @param errorCallback {Function} called with a FileError\n */\nEntry.prototype.getParent = function(successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');\n        var entry = new DirectoryEntry(result.name, result.fullPath);\n        successCallback(entry);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getParent\", [this.fullPath]);\n};\n\nmodule.exports = Entry;\n});\n\n//@ sourceURL=lib/common/plugin/Entry.js")} catch(e) {console.log("exception: in lib/common/plugin/Entry.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/File\", function(require, exports, module) {\n/**\n * Constructor.\n * name {DOMString} name of the file, without path information\n * fullPath {DOMString} the full path of the file, including the name\n * type {DOMString} mime type\n * lastModifiedDate {Date} last modified date\n * size {Number} size of the file in bytes\n */\n\nvar File = function(name, fullPath, type, lastModifiedDate, size){\n    this.name = name || '';\n    this.fullPath = fullPath || null;\n    this.type = type || null;\n    this.lastModifiedDate = lastModifiedDate || null;\n    this.size = size || 0;\n};\n\nmodule.exports = File;\n});\n\n//@ sourceURL=lib/common/plugin/File.js")} catch(e) {console.log("exception: in lib/common/plugin/File.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileEntry\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    Entry = require('cordova/plugin/Entry'),\n    FileWriter = require('cordova/plugin/FileWriter'),\n    File = require('cordova/plugin/File'),\n    FileError = require('cordova/plugin/FileError');\n\n/**\n * An interface representing a file on the file system.\n *\n * {boolean} isFile always true (readonly)\n * {boolean} isDirectory always false (readonly)\n * {DOMString} name of the file, excluding the path leading to it (readonly)\n * {DOMString} fullPath the absolute full path to the file (readonly)\n * {FileSystem} filesystem on which the file resides (readonly)\n */\nvar FileEntry = function(name, fullPath) {\n     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);\n};\n\nutils.extend(FileEntry, Entry);\n\n/**\n * Creates a new FileWriter associated with the file that this FileEntry represents.\n *\n * @param {Function} successCallback is called with the new FileWriter\n * @param {Function} errorCallback is called with a FileError\n */\nFileEntry.prototype.createWriter = function(successCallback, errorCallback) {\n    this.file(function(filePointer) {\n        var writer = new FileWriter(filePointer);\n\n        if (writer.fileName === null || writer.fileName === \"\") {\n            if (typeof errorCallback === \"function\") {\n                errorCallback(new FileError(FileError.INVALID_STATE_ERR));\n            }\n        } else {\n            if (typeof successCallback === \"function\") {\n                successCallback(writer);\n            }\n        }\n    }, errorCallback);\n};\n\n/**\n * Returns a File that represents the current state of the file that this FileEntry represents.\n *\n * @param {Function} successCallback is called with the new File object\n * @param {Function} errorCallback is called with a FileError\n */\nFileEntry.prototype.file = function(successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(f) {\n        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);\n        successCallback(file);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getFileMetadata\", [this.fullPath]);\n};\n\n\nmodule.exports = FileEntry;\n});\n\n//@ sourceURL=lib/common/plugin/FileEntry.js")} catch(e) {console.log("exception: in lib/common/plugin/FileEntry.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileError\", function(require, exports, module) {\n/**\n * FileError\n */\nfunction FileError(error) {\n  this.code = error || null;\n}\n\n// File error codes\n// Found in DOMException\nFileError.NOT_FOUND_ERR = 1;\nFileError.SECURITY_ERR = 2;\nFileError.ABORT_ERR = 3;\n\n// Added by File API specification\nFileError.NOT_READABLE_ERR = 4;\nFileError.ENCODING_ERR = 5;\nFileError.NO_MODIFICATION_ALLOWED_ERR = 6;\nFileError.INVALID_STATE_ERR = 7;\nFileError.SYNTAX_ERR = 8;\nFileError.INVALID_MODIFICATION_ERR = 9;\nFileError.QUOTA_EXCEEDED_ERR = 10;\nFileError.TYPE_MISMATCH_ERR = 11;\nFileError.PATH_EXISTS_ERR = 12;\n\nmodule.exports = FileError;\n});\n\n//@ sourceURL=lib/common/plugin/FileError.js")} catch(e) {console.log("exception: in lib/common/plugin/FileError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileReader\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError'),\n    ProgressEvent = require('cordova/plugin/ProgressEvent');\n\n/**\n * This class reads the mobile device file system.\n *\n * For Android:\n *      The root directory is the root of the file system.\n *      To read from the SD card, the file name is \"sdcard/my_file.txt\"\n * @constructor\n */\nvar FileReader = function() {\n    this.fileName = \"\";\n\n    this.readyState = 0; // FileReader.EMPTY\n\n    // File data\n    this.result = null;\n\n    // Error\n    this.error = null;\n\n    // Event handlers\n    this.onloadstart = null;    // When the read starts.\n    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total)\n    this.onload = null;         // When the read has successfully completed.\n    this.onerror = null;        // When the read has failed (see errors).\n    this.onloadend = null;      // When the request has completed (either in success or failure).\n    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.\n};\n\n// States\nFileReader.EMPTY = 0;\nFileReader.LOADING = 1;\nFileReader.DONE = 2;\n\n/**\n * Abort reading file.\n */\nFileReader.prototype.abort = function() {\n    this.result = null;\n\n    if (this.readyState == FileReader.DONE || this.readyState == FileReader.EMPTY) {\n      return;\n    }\n\n    this.readyState = FileReader.DONE;\n\n    // If abort callback\n    if (typeof this.onabort === 'function') {\n        this.onabort(new ProgressEvent('abort', {target:this}));\n    }\n    // If load end callback\n    if (typeof this.onloadend === 'function') {\n        this.onloadend(new ProgressEvent('loadend', {target:this}));\n    }\n};\n\n/**\n * Read text file.\n *\n * @param file          {File} File object containing file properties\n * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)\n */\nFileReader.prototype.readAsText = function(file, encoding) {\n    // Figure out pathing\n    this.fileName = '';\n    if (typeof file.fullPath === 'undefined') {\n        this.fileName = file;\n    } else {\n        this.fileName = file.fullPath;\n    }\n\n    // Already loading something\n    if (this.readyState == FileReader.LOADING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // LOADING state\n    this.readyState = FileReader.LOADING;\n\n    // If loadstart callback\n    if (typeof this.onloadstart === \"function\") {\n        this.onloadstart(new ProgressEvent(\"loadstart\", {target:this}));\n    }\n\n    // Default encoding is UTF-8\n    var enc = encoding ? encoding : \"UTF-8\";\n\n    var me = this;\n\n    // Read file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // Save result\n            me.result = r;\n\n            // If onload callback\n            if (typeof me.onload === \"function\") {\n                me.onload(new ProgressEvent(\"load\", {target:me}));\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            // null result\n            me.result = null;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {target:me}));\n            }\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        }, \"File\", \"readAsText\", [this.fileName, enc]);\n};\n\n\n/**\n * Read file and return data as a base64 encoded data url.\n * A data url is of the form:\n *      data:[<mediatype>][;base64],<data>\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsDataURL = function(file) {\n    this.fileName = \"\";\n    if (typeof file.fullPath === \"undefined\") {\n        this.fileName = file;\n    } else {\n        this.fileName = file.fullPath;\n    }\n\n    // Already loading something\n    if (this.readyState == FileReader.LOADING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // LOADING state\n    this.readyState = FileReader.LOADING;\n\n    // If loadstart callback\n    if (typeof this.onloadstart === \"function\") {\n        this.onloadstart(new ProgressEvent(\"loadstart\", {target:this}));\n    }\n\n    var me = this;\n\n    // Read file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            // Save result\n            me.result = r;\n\n            // If onload callback\n            if (typeof me.onload === \"function\") {\n                me.onload(new ProgressEvent(\"load\", {target:me}));\n            }\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            me.result = null;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {target:me}));\n            }\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        }, \"File\", \"readAsDataURL\", [this.fileName]);\n};\n\n/**\n * Read file and return data as a binary data.\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsBinaryString = function(file) {\n    // TODO - Can't return binary data to browser.\n    console.log('method \"readAsBinaryString\" is not supported at this time.');\n};\n\n/**\n * Read file and return data as a binary data.\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsArrayBuffer = function(file) {\n    // TODO - Can't return binary data to browser.\n    console.log('This method is not supported at this time.');\n};\n\nmodule.exports = FileReader;\n});\n\n//@ sourceURL=lib/common/plugin/FileReader.js")} catch(e) {console.log("exception: in lib/common/plugin/FileReader.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileSystem\", function(require, exports, module) {\nvar DirectoryEntry = require('cordova/plugin/DirectoryEntry');\n\n/**\n * An interface representing a file system\n *\n * @constructor\n * {DOMString} name the unique name of the file system (readonly)\n * {DirectoryEntry} root directory of the file system (readonly)\n */\nvar FileSystem = function(name, root) {\n    this.name = name || null;\n    if (root) {\n        this.root = new DirectoryEntry(root.name, root.fullPath);\n    }\n};\n\nmodule.exports = FileSystem;\n\n});\n\n//@ sourceURL=lib/common/plugin/FileSystem.js")} catch(e) {console.log("exception: in lib/common/plugin/FileSystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileTransfer\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileTransferError = require('cordova/plugin/FileTransferError');\n\n/**\n * FileTransfer uploads a file to a remote server.\n * @constructor\n */\nvar FileTransfer = function() {};\n\n/**\n* Given an absolute file path, uploads a file on the device to a remote server\n* using a multipart HTTP request.\n* @param filePath {String}           Full path of the file on the device\n* @param server {String}             URL of the server to receive the file\n* @param successCallback (Function}  Callback to be invoked when upload has completed\n* @param errorCallback {Function}    Callback to be invoked upon error\n* @param options {FileUploadOptions} Optional parameters such as file name and mimetype\n* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n*/\nFileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {\n    // sanity parameter checking\n    if (!filePath || !server) throw new Error(\"FileTransfer.upload requires filePath and server URL parameters at the minimum.\");\n    // check for options\n    var fileKey = null;\n    var fileName = null;\n    var mimeType = null;\n    var params = null;\n    var chunkedMode = true;\n    if (options) {\n        fileKey = options.fileKey;\n        fileName = options.fileName;\n        mimeType = options.mimeType;\n        if (options.chunkedMode !== null || typeof options.chunkedMode != \"undefined\") {\n            chunkedMode = options.chunkedMode;\n        }\n        if (options.params) {\n            params = options.params;\n        }\n        else {\n            params = {};\n        }\n    }\n\n    var fail = function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);\n        errorCallback(error);\n    };\n\n    exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]);\n};\n\n/**\n * Downloads a file form a given URL and saves it to the specified directory.\n * @param source {String}          URL of the server to receive the file\n * @param target {String}         Full path of the file on the device\n * @param successCallback (Function}  Callback to be invoked when upload has completed\n * @param errorCallback {Function}    Callback to be invoked upon error\n */\nFileTransfer.prototype.download = function(source, target, successCallback, errorCallback) {\n    // sanity parameter checking\n    if (!source || !target) throw new Error(\"FileTransfer.download requires source URI and target URI parameters at the minimum.\");\n    var win = function(result) {\n        var entry = null;\n        if (result.isDirectory) {\n            entry = new (require('cordova/plugin/DirectoryEntry'))();\n        }\n        else if (result.isFile) {\n            entry = new (require('cordova/plugin/FileEntry'))();\n        }\n        entry.isDirectory = result.isDirectory;\n        entry.isFile = result.isFile;\n        entry.name = result.name;\n        entry.fullPath = result.fullPath;\n        successCallback(entry);\n    };\n\n    var fail = function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);\n        errorCallback(error);\n    };\n\n    exec(win, errorCallback, 'FileTransfer', 'download', [source, target]);\n};\n\nmodule.exports = FileTransfer;\n\n});\n\n//@ sourceURL=lib/common/plugin/FileTransfer.js")} catch(e) {console.log("exception: in lib/common/plugin/FileTransfer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileTransferError\", function(require, exports, module) {\n/**\n * FileTransferError\n * @constructor\n */\nvar FileTransferError = function(code, source, target, status) {\n    this.code = code || null;\n    this.source = source || null;\n    this.target = target || null;\n    this.http_status = status || null;\n};\n\nFileTransferError.FILE_NOT_FOUND_ERR = 1;\nFileTransferError.INVALID_URL_ERR = 2;\nFileTransferError.CONNECTION_ERR = 3;\n\nmodule.exports = FileTransferError;\n\n});\n\n//@ sourceURL=lib/common/plugin/FileTransferError.js")} catch(e) {console.log("exception: in lib/common/plugin/FileTransferError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileUploadOptions\", function(require, exports, module) {\n/**\n * Options to customize the HTTP request used to upload files.\n * @constructor\n * @param fileKey {String}   Name of file request parameter.\n * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.\n * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.\n * @param params {Object}    Object with key: value params to send to the server.\n */\nvar FileUploadOptions = function(fileKey, fileName, mimeType, params) {\n    this.fileKey = fileKey || null;\n    this.fileName = fileName || null;\n    this.mimeType = mimeType || null;\n    this.params = params || null;\n};\n\nmodule.exports = FileUploadOptions;\n});\n\n//@ sourceURL=lib/common/plugin/FileUploadOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/FileUploadOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileUploadResult\", function(require, exports, module) {\n/**\n * FileUploadResult\n * @constructor\n */\nvar FileUploadResult = function() {\n    this.bytesSent = 0;\n    this.responseCode = null;\n    this.response = null;\n};\n\nmodule.exports = FileUploadResult;\n});\n\n//@ sourceURL=lib/common/plugin/FileUploadResult.js")} catch(e) {console.log("exception: in lib/common/plugin/FileUploadResult.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileWriter\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError'),\n    ProgressEvent = require('cordova/plugin/ProgressEvent');\n\n/**\n * This class writes to the mobile device file system.\n *\n * For Android:\n *      The root directory is the root of the file system.\n *      To write to the SD card, the file name is \"sdcard/my_file.txt\"\n *\n * @constructor\n * @param file {File} File object containing file properties\n * @param append if true write to the end of the file, otherwise overwrite the file\n */\nvar FileWriter = function(file) {\n    this.fileName = \"\";\n    this.length = 0;\n    if (file) {\n        this.fileName = file.fullPath || file;\n        this.length = file.size || 0;\n    }\n    // default is to write at the beginning of the file\n    this.position = 0;\n\n    this.readyState = 0; // EMPTY\n\n    this.result = null;\n\n    // Error\n    this.error = null;\n\n    // Event handlers\n    this.onwritestart = null;   // When writing starts\n    this.onprogress = null;     // While writing the file, and reporting partial file data\n    this.onwrite = null;        // When the write has successfully completed.\n    this.onwriteend = null;     // When the request has completed (either in success or failure).\n    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.\n    this.onerror = null;        // When the write has failed (see errors).\n};\n\n// States\nFileWriter.INIT = 0;\nFileWriter.WRITING = 1;\nFileWriter.DONE = 2;\n\n/**\n * Abort writing file.\n */\nFileWriter.prototype.abort = function() {\n    // check for invalid state\n    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // set error\n    this.error = new FileError(FileError.ABORT_ERR);\n\n    this.readyState = FileWriter.DONE;\n\n    // If abort callback\n    if (typeof this.onabort === \"function\") {\n        this.onabort(new ProgressEvent(\"abort\", {\"target\":this}));\n    }\n\n    // If write end callback\n    if (typeof this.onwriteend === \"function\") {\n        this.onwriteend(new ProgressEvent(\"writeend\", {\"target\":this}));\n    }\n};\n\n/**\n * Writes data to the file\n *\n * @param text to be written\n */\nFileWriter.prototype.write = function(text) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // WRITING state\n    this.readyState = FileWriter.WRITING;\n\n    var me = this;\n\n    // If onwritestart callback\n    if (typeof me.onwritestart === \"function\") {\n        me.onwritestart(new ProgressEvent(\"writestart\", {\"target\":me}));\n    }\n\n    // Write file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // position always increases by bytes written because file would be extended\n            me.position += r;\n            // The length of the file is now where we are done writing.\n\n            me.length = me.position;\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // If onwrite callback\n            if (typeof me.onwrite === \"function\") {\n                me.onwrite(new ProgressEvent(\"write\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        }, \"File\", \"write\", [this.fileName, text, this.position]);\n};\n\n/**\n * Moves the file pointer to the location specified.\n *\n * If the offset is a negative number the position of the file\n * pointer is rewound.  If the offset is greater than the file\n * size the position is set to the end of the file.\n *\n * @param offset is the location to move the file pointer to.\n */\nFileWriter.prototype.seek = function(offset) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    if (!offset && offset !== 0) {\n        return;\n    }\n\n    // See back from end of file.\n    if (offset < 0) {\n        this.position = Math.max(offset + this.length, 0);\n    }\n    // Offset is bigger then file size so set position\n    // to the end of the file.\n    else if (offset > this.length) {\n        this.position = this.length;\n    }\n    // Offset is between 0 and file size so set the position\n    // to start writing.\n    else {\n        this.position = offset;\n    }\n};\n\n/**\n * Truncates the file to the size specified.\n *\n * @param size to chop the file at.\n */\nFileWriter.prototype.truncate = function(size) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // WRITING state\n    this.readyState = FileWriter.WRITING;\n\n    var me = this;\n\n    // If onwritestart callback\n    if (typeof me.onwritestart === \"function\") {\n        me.onwritestart(new ProgressEvent(\"writestart\", {\"target\":this}));\n    }\n\n    // Write file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Update the length of the file\n            me.length = r;\n            me.position = Math.min(me.position, r);\n\n            // If onwrite callback\n            if (typeof me.onwrite === \"function\") {\n                me.onwrite(new ProgressEvent(\"write\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        }, \"File\", \"truncate\", [this.fileName, size]);\n};\n\nmodule.exports = FileWriter;\n\n});\n\n//@ sourceURL=lib/common/plugin/FileWriter.js")} catch(e) {console.log("exception: in lib/common/plugin/FileWriter.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Flags\", function(require, exports, module) {\n/**\n * Supplies arguments to methods that lookup or create files and directories.\n *\n * @param create\n *            {boolean} file or directory if it doesn't exist\n * @param exclusive\n *            {boolean} used with create; if true the command will fail if\n *            target path exists\n */\nfunction Flags(create, exclusive) {\n    this.create = create || false;\n    this.exclusive = exclusive || false;\n}\n\nmodule.exports = Flags;\n});\n\n//@ sourceURL=lib/common/plugin/Flags.js")} catch(e) {console.log("exception: in lib/common/plugin/Flags.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/LocalFileSystem\", function(require, exports, module) {\nvar exec = require('cordova/exec');\n\n/**\n * Represents a local file system.\n */\nvar LocalFileSystem = function() {\n\n};\n\nLocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence\nLocalFileSystem.PERSISTENT = 1; //persistent\n\nmodule.exports = LocalFileSystem;\n});\n\n//@ sourceURL=lib/common/plugin/LocalFileSystem.js")} catch(e) {console.log("exception: in lib/common/plugin/LocalFileSystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Media\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec');\n\nvar mediaObjects = {};\n\n/**\n * This class provides access to the device media, interfaces to both sound and video\n *\n * @constructor\n * @param src                   The file name or url to play\n * @param successCallback       The callback to be called when the file is done playing or recording.\n *                                  successCallback()\n * @param errorCallback         The callback to be called if there is an error.\n *                                  errorCallback(int errorCode) - OPTIONAL\n * @param statusCallback        The callback to be called when media status has changed.\n *                                  statusCallback(int statusCode) - OPTIONAL\n */\nvar Media = function(src, successCallback, errorCallback, statusCallback) {\n\n    // successCallback optional\n    if (successCallback && (typeof successCallback !== \"function\")) {\n        console.log(\"Media Error: successCallback is not a function\");\n        return;\n    }\n\n    // errorCallback optional\n    if (errorCallback && (typeof errorCallback !== \"function\")) {\n        console.log(\"Media Error: errorCallback is not a function\");\n        return;\n    }\n\n    // statusCallback optional\n    if (statusCallback && (typeof statusCallback !== \"function\")) {\n        console.log(\"Media Error: statusCallback is not a function\");\n        return;\n    }\n\n    this.id = utils.createUUID();\n    mediaObjects[this.id] = this;\n    this.src = src;\n    this.successCallback = successCallback;\n    this.errorCallback = errorCallback;\n    this.statusCallback = statusCallback;\n    this._duration = -1;\n    this._position = -1;\n    exec(null, this.errorCallback, \"Media\", \"create\", [this.id, this.src]);\n};\n\n// Media messages\nMedia.MEDIA_STATE = 1;\nMedia.MEDIA_DURATION = 2;\nMedia.MEDIA_POSITION = 3;\nMedia.MEDIA_ERROR = 9;\n\n// Media states\nMedia.MEDIA_NONE = 0;\nMedia.MEDIA_STARTING = 1;\nMedia.MEDIA_RUNNING = 2;\nMedia.MEDIA_PAUSED = 3;\nMedia.MEDIA_STOPPED = 4;\nMedia.MEDIA_MSG = [\"None\", \"Starting\", \"Running\", \"Paused\", \"Stopped\"];\n\n// \"static\" function to return existing objs.\nMedia.get = function(id) {\n    return mediaObjects[id];\n};\n\n/**\n * Start or resume playing audio file.\n */\nMedia.prototype.play = function(options) {\n    exec(null, null, \"Media\", \"startPlayingAudio\", [this.id, this.src, options]);\n};\n\n/**\n * Stop playing audio file.\n */\nMedia.prototype.stop = function() {\n    var me = this;\n    exec(function() {\n        me._position = 0;\n        me.successCallback();\n    }, this.errorCallback, \"Media\", \"stopPlayingAudio\", [this.id]);\n};\n\n/**\n * Seek or jump to a new time in the track..\n */\nMedia.prototype.seekTo = function(milliseconds) {\n    var me = this;\n    exec(function(p) {\n        me._position = p;\n    }, this.errorCallback, \"Media\", \"seekToAudio\", [this.id, milliseconds]);\n};\n\n/**\n * Pause playing audio file.\n */\nMedia.prototype.pause = function() {\n    exec(null, this.errorCallback, \"Media\", \"pausePlayingAudio\", [this.id]);\n};\n\n/**\n * Get duration of an audio file.\n * The duration is only set for audio that is playing, paused or stopped.\n *\n * @return      duration or -1 if not known.\n */\nMedia.prototype.getDuration = function() {\n    return this._duration;\n};\n\n/**\n * Get position of audio.\n */\nMedia.prototype.getCurrentPosition = function(success, fail) {\n    var me = this;\n    exec(function(p) {\n        me._position = p;\n        success(p);\n    }, fail, \"Media\", \"getCurrentPositionAudio\", [this.id]);\n};\n\n/**\n * Start recording audio file.\n */\nMedia.prototype.startRecord = function() {\n    exec(this.successCallback, this.errorCallback, \"Media\", \"startRecordingAudio\", [this.id, this.src]);\n};\n\n/**\n * Stop recording audio file.\n */\nMedia.prototype.stopRecord = function() {\n    exec(this.successCallback, this.errorCallback, \"Media\", \"stopRecordingAudio\", [this.id]);\n};\n\n/**\n * Release the resources.\n */\nMedia.prototype.release = function() {\n    exec(null, this.errorCallback, \"Media\", \"release\", [this.id]);\n};\n\n/**\n * Adjust the volume.\n */\nMedia.prototype.setVolume = function(volume) {\n    exec(null, null, \"Media\", \"setVolume\", [this.id, volume]);\n};\n\n/**\n * Audio has status update.\n * PRIVATE\n *\n * @param id            The media object id (string)\n * @param status        The status code (int)\n * @param msg           The status message (string)\n */\nMedia.onStatus = function(id, msg, value) {\n    var media = mediaObjects[id];\n    // If state update\n    if (msg === Media.MEDIA_STATE) {\n        if (value === Media.MEDIA_STOPPED) {\n            if (media.successCallback) {\n                media.successCallback();\n            }\n        }\n        if (media.statusCallback) {\n            media.statusCallback(value);\n        }\n    }\n    else if (msg === Media.MEDIA_DURATION) {\n        media._duration = value;\n    }\n    else if (msg === Media.MEDIA_ERROR) {\n        if (media.errorCallback) {\n            // value should be a MediaError object when msg == MEDIA_ERROR\n            media.errorCallback(value);\n        }\n    }\n    else if (msg === Media.MEDIA_POSITION) {\n        media._position = value;\n    }\n};\n\nmodule.exports = Media;\n});\n\n//@ sourceURL=lib/common/plugin/Media.js")} catch(e) {console.log("exception: in lib/common/plugin/Media.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/MediaError\", function(require, exports, module) {\n/**\n * This class contains information about any Media errors.\n * @constructor\n */\nvar MediaError = function(code, msg) {\n    this.code = (code !== undefined ? code : null);\n    this.message = msg || \"\";\n};\n\nMediaError.MEDIA_ERR_NONE_ACTIVE    = 0;\nMediaError.MEDIA_ERR_ABORTED        = 1;\nMediaError.MEDIA_ERR_NETWORK        = 2;\nMediaError.MEDIA_ERR_DECODE         = 3;\nMediaError.MEDIA_ERR_NONE_SUPPORTED = 4;\n\nmodule.exports = MediaError;\n});\n\n//@ sourceURL=lib/common/plugin/MediaError.js")} catch(e) {console.log("exception: in lib/common/plugin/MediaError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/MediaFile\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    File = require('cordova/plugin/File'),\n    CaptureError = require('cordova/plugin/CaptureError');\n/**\n * Represents a single file.\n *\n * name {DOMString} name of the file, without path information\n * fullPath {DOMString} the full path of the file, including the name\n * type {DOMString} mime type\n * lastModifiedDate {Date} last modified date\n * size {Number} size of the file in bytes\n */\nvar MediaFile = function(name, fullPath, type, lastModifiedDate, size){\n    MediaFile.__super__.constructor.apply(this, arguments);\n};\n\nutils.extend(MediaFile, File);\n\n/**\n * Request capture format data for a specific file and type\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n */\nMediaFile.prototype.getFormatData = function(successCallback, errorCallback) {\n    if (typeof this.fullPath === \"undefined\" || this.fullPath === null) {\n        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));\n    } else {\n        exec(successCallback, errorCallback, \"Capture\", \"getFormatData\", [this.fullPath, this.type]);\n    }\n};\n\n// TODO: can we axe this?\n/**\n * Casts a PluginResult message property  (array of objects) to an array of MediaFile objects\n * (used in Objective-C and Android)\n *\n * @param {PluginResult} pluginResult\n */\nMediaFile.cast = function(pluginResult) {\n    var mediaFiles = [];\n    for (var i=0; i<pluginResult.message.length; i++) {\n        var mediaFile = new MediaFile();\n        mediaFile.name = pluginResult.message[i].name;\n        mediaFile.fullPath = pluginResult.message[i].fullPath;\n        mediaFile.type = pluginResult.message[i].type;\n        mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate;\n        mediaFile.size = pluginResult.message[i].size;\n        mediaFiles.push(mediaFile);\n    }\n    pluginResult.message = mediaFiles;\n    return pluginResult;\n};\n\nmodule.exports = MediaFile;\n\n});\n\n//@ sourceURL=lib/common/plugin/MediaFile.js")} catch(e) {console.log("exception: in lib/common/plugin/MediaFile.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/MediaFileData\", function(require, exports, module) {\n/**\n * MediaFileData encapsulates format information of a media file.\n *\n * @param {DOMString} codecs\n * @param {long} bitrate\n * @param {long} height\n * @param {long} width\n * @param {float} duration\n */\nvar MediaFileData = function(codecs, bitrate, height, width, duration){\n    this.codecs = codecs || null;\n    this.bitrate = bitrate || 0;\n    this.height = height || 0;\n    this.width = width || 0;\n    this.duration = duration || 0;\n};\n\nmodule.exports = MediaFileData;\n});\n\n//@ sourceURL=lib/common/plugin/MediaFileData.js")} catch(e) {console.log("exception: in lib/common/plugin/MediaFileData.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Metadata\", function(require, exports, module) {\n/**\n * Information about the state of the file or directory\n *\n * {Date} modificationTime (readonly)\n */\nvar Metadata = function(time) {\n    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);\n};\n\nmodule.exports = Metadata;\n});\n\n//@ sourceURL=lib/common/plugin/Metadata.js")} catch(e) {console.log("exception: in lib/common/plugin/Metadata.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Position\", function(require, exports, module) {\nvar Coordinates = require('cordova/plugin/Coordinates');\n\nvar Position = function(coords, timestamp) {\n    if (coords) {\n        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);\n    } else {\n        this.coords = new Coordinates();\n    }\n    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();\n};\n\nmodule.exports = Position;\n\n});\n\n//@ sourceURL=lib/common/plugin/Position.js")} catch(e) {console.log("exception: in lib/common/plugin/Position.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/PositionError\", function(require, exports, module) {\n/**\n * Position error object\n *\n * @constructor\n * @param code\n * @param message\n */\nvar PositionError = function(code, message) {\n    this.code = code || null;\n    this.message = message || '';\n};\n\nPositionError.PERMISSION_DENIED = 1;\nPositionError.POSITION_UNAVAILABLE = 2;\nPositionError.TIMEOUT = 3;\n\nmodule.exports = PositionError;\n});\n\n//@ sourceURL=lib/common/plugin/PositionError.js")} catch(e) {console.log("exception: in lib/common/plugin/PositionError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ProgressEvent\", function(require, exports, module) {\n// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill\n// Feature test: See if we can instantiate a native ProgressEvent;\n// if so, use that approach,\n// otherwise fill-in with our own implementation.\n//\n// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.\nvar ProgressEvent = (function() {\n    /*\n    var createEvent = function(data) {\n        var event = document.createEvent('Events');\n        event.initEvent('ProgressEvent', false, false);\n        if (data) {\n            for (var i in data) {\n                if (data.hasOwnProperty(i)) {\n                    event[i] = data[i];\n                }\n            }\n            if (data.target) {\n                // TODO: cannot call <some_custom_object>.dispatchEvent\n                // need to first figure out how to implement EventTarget\n            }\n        }\n        return event;\n    };\n    try {\n        var ev = createEvent({type:\"abort\",target:document});\n        return function ProgressEvent(type, data) {\n            data.type = type;\n            return createEvent(data);\n        };\n    } catch(e){\n    */\n        return function ProgressEvent(type, dict) {\n            this.type = type;\n            this.bubbles = false;\n            this.cancelBubble = false;\n            this.cancelable = false;\n            this.lengthComputable = false;\n            this.loaded = dict && dict.loaded ? dict.loaded : 0;\n            this.total = dict && dict.total ? dict.total : 0;\n            this.target = dict && dict.target ? dict.target : null;\n        };\n    //}\n})();\n\nmodule.exports = ProgressEvent;\n});\n\n//@ sourceURL=lib/common/plugin/ProgressEvent.js")} catch(e) {console.log("exception: in lib/common/plugin/ProgressEvent.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/accelerometer\", function(require, exports, module) {\n/**\n * This class provides access to device accelerometer data.\n * @constructor\n */\nvar utils = require(\"cordova/utils\"),\n    exec = require(\"cordova/exec\"),\n    Acceleration = require('cordova/plugin/Acceleration');\n\n// Is the accel sensor running?\nvar running = false;\n\n// Keeps reference to watchAcceleration calls.\nvar timers = {};\n\n// Array of listeners; used to keep track of when we should call start and stop.\nvar listeners = [];\n\n// Last returned acceleration object from native\nvar accel = null;\n\n// Tells native to start.\nfunction start() {\n    exec(function(a) {\n        var tempListeners = listeners.slice(0);\n        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);\n        for (var i = 0, l = tempListeners.length; i < l; i++) {\n            tempListeners[i].win(accel);\n        }\n    }, function(e) {\n        var tempListeners = listeners.slice(0);\n        for (var i = 0, l = tempListeners.length; i < l; i++) {\n            tempListeners[i].fail(e);\n        }\n    }, \"Accelerometer\", \"start\", []);\n    running = true;\n}\n\n// Tells native to stop.\nfunction stop() {\n    exec(null, null, \"Accelerometer\", \"stop\", []);\n    running = false;\n}\n\n// Adds a callback pair to the listeners array\nfunction createCallbackPair(win, fail) {\n    return {win:win, fail:fail};\n}\n\n// Removes a win/fail listener pair from the listeners array\nfunction removeListeners(l) {\n    var idx = listeners.indexOf(l);\n    if (idx > -1) {\n        listeners.splice(idx, 1);\n        if (listeners.length === 0) {\n            stop();\n        }\n    }\n}\n\nvar accelerometer = {\n    /**\n     * Asynchronously aquires the current acceleration.\n     *\n     * @param {Function} successCallback    The function to call when the acceleration data is available\n     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)\n     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)\n     */\n    getCurrentAcceleration: function(successCallback, errorCallback, options) {\n        // successCallback required\n        if (typeof successCallback !== \"function\") {\n            throw \"getCurrentAcceleration must be called with at least a success callback function as first parameter.\";\n        }\n\n        var p;\n        var win = function(a) {\n            removeListeners(p);\n            successCallback(a);\n        };\n        var fail = function(e) {\n            removeListeners(p);\n            errorCallback(e);\n        };\n\n        p = createCallbackPair(win, fail);\n        listeners.push(p);\n\n        if (!running) {\n            start();\n        }\n    },\n\n    /**\n     * Asynchronously aquires the acceleration repeatedly at a given interval.\n     *\n     * @param {Function} successCallback    The function to call each time the acceleration data is available\n     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)\n     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)\n     * @return String                       The watch id that must be passed to #clearWatch to stop watching.\n     */\n    watchAcceleration: function(successCallback, errorCallback, options) {\n        // Default interval (10 sec)\n        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;\n\n        // successCallback required\n        if (typeof successCallback !== \"function\") {\n            throw \"watchAcceleration must be called with at least a success callback function as first parameter.\";\n        }\n\n        // Keep reference to watch id, and report accel readings as often as defined in frequency\n        var id = utils.createUUID();\n\n        var p = createCallbackPair(function(){}, function(e) {\n            removeListeners(p);\n            errorCallback(e);\n        });\n        listeners.push(p);\n\n        timers[id] = {\n            timer:window.setInterval(function() {\n                if (accel) {\n                    successCallback(accel);\n                }\n            }, frequency),\n            listeners:p\n        };\n\n        if (running) {\n            // If we're already running then immediately invoke the success callback\n            // but only if we have retreived a value, sample code does not check for null ...\n            if(accel) {\n                successCallback(accel);\n            }\n        } else {\n            start();\n        }\n\n        return id;\n    },\n\n    /**\n     * Clears the specified accelerometer watch.\n     *\n     * @param {String} id       The id of the watch returned from #watchAcceleration.\n     */\n    clearWatch: function(id) {\n        // Stop javascript timer & remove from timer list\n        if (id && timers[id]) {\n            window.clearInterval(timers[id].timer);\n            removeListeners(timers[id].listeners);\n            delete timers[id];\n        }\n    }\n};\n\nmodule.exports = accelerometer;\n\n});\n\n//@ sourceURL=lib/common/plugin/accelerometer.js")} catch(e) {console.log("exception: in lib/common/plugin/accelerometer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/battery\", function(require, exports, module) {\n/**\n * This class contains information about the current battery status.\n * @constructor\n */\nvar cordova = require('cordova'),\n    exec = require('cordova/exec');\n\nfunction handlers() {\n  return battery.channels.batterystatus.numHandlers +\n         battery.channels.batterylow.numHandlers +\n         battery.channels.batterycritical.numHandlers;\n}\n\nvar Battery = function() {\n    this._level = null;\n    this._isPlugged = null;\n    // Create new event handlers on the window (returns a channel instance)\n    var subscriptionEvents = {\n      onSubscribe:this.onSubscribe,\n      onUnsubscribe:this.onUnsubscribe\n    };\n    this.channels = {\n      batterystatus:cordova.addWindowEventHandler(\"batterystatus\", subscriptionEvents),\n      batterylow:cordova.addWindowEventHandler(\"batterylow\", subscriptionEvents),\n      batterycritical:cordova.addWindowEventHandler(\"batterycritical\", subscriptionEvents)\n    };\n};\n/**\n * Event handlers for when callbacks get registered for the battery.\n * Keep track of how many handlers we have so we can start and stop the native battery listener\n * appropriately (and hopefully save on battery life!).\n */\nBattery.prototype.onSubscribe = function() {\n  var me = battery;\n  // If we just registered the first handler, make sure native listener is started.\n  if (handlers() === 1) {\n    exec(me._status, me._error, \"Battery\", \"start\", []);\n  }\n};\n\nBattery.prototype.onUnsubscribe = function() {\n  var me = battery;\n\n  // If we just unregistered the last handler, make sure native listener is stopped.\n  if (handlers() === 0) {\n      exec(null, null, \"Battery\", \"stop\", []);\n  }\n};\n\n/**\n * Callback for battery status\n *\n * @param {Object} info            keys: level, isPlugged\n */\nBattery.prototype._status = function(info) {\n    if (info) {\n        var me = battery;\n    var level = info.level;\n        if (me._level !== level || me._isPlugged !== info.isPlugged) {\n            // Fire batterystatus event\n            cordova.fireWindowEvent(\"batterystatus\", info);\n\n            // Fire low battery event\n            if (level === 20 || level === 5) {\n                if (level === 20) {\n                    cordova.fireWindowEvent(\"batterylow\", info);\n                }\n                else {\n                    cordova.fireWindowEvent(\"batterycritical\", info);\n                }\n            }\n        }\n        me._level = level;\n        me._isPlugged = info.isPlugged;\n    }\n};\n\n/**\n * Error callback for battery start\n */\nBattery.prototype._error = function(e) {\n    console.log(\"Error initializing Battery: \" + e);\n};\n\nvar battery = new Battery();\n\nmodule.exports = battery;\n});\n\n//@ sourceURL=lib/common/plugin/battery.js")} catch(e) {console.log("exception: in lib/common/plugin/battery.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/capture\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    MediaFile = require('cordova/plugin/MediaFile');\n\n/**\n * Launches a capture of different types.\n *\n * @param (DOMString} type\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureVideoOptions} options\n */\nfunction _capture(type, successCallback, errorCallback, options) {\n    var win = function(pluginResult) {\n        var mediaFiles = [];\n        var i;\n        for (i = 0; i < pluginResult.length; i++) {\n            var mediaFile = new MediaFile();\n            mediaFile.name = pluginResult[i].name;\n            mediaFile.fullPath = pluginResult[i].fullPath;\n            mediaFile.type = pluginResult[i].type;\n            mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;\n            mediaFile.size = pluginResult[i].size;\n            mediaFiles.push(mediaFile);\n        }\n        successCallback(mediaFiles);\n    };\n    exec(win, errorCallback, \"Capture\", type, [options]);\n}\n/**\n * The Capture interface exposes an interface to the camera and microphone of the hosting device.\n */\nfunction Capture() {\n    this.supportedAudioModes = [];\n    this.supportedImageModes = [];\n    this.supportedVideoModes = [];\n}\n\n/**\n * Launch audio recorder application for recording audio clip(s).\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureAudioOptions} options\n */\nCapture.prototype.captureAudio = function(successCallback, errorCallback, options){\n    _capture(\"captureAudio\", successCallback, errorCallback, options);\n};\n\n/**\n * Launch camera application for taking image(s).\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureImageOptions} options\n */\nCapture.prototype.captureImage = function(successCallback, errorCallback, options){\n    _capture(\"captureImage\", successCallback, errorCallback, options);\n};\n\n/**\n * Launch device camera application for recording video(s).\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureVideoOptions} options\n */\nCapture.prototype.captureVideo = function(successCallback, errorCallback, options){\n    _capture(\"captureVideo\", successCallback, errorCallback, options);\n};\n\n\nmodule.exports = new Capture();\n\n});\n\n//@ sourceURL=lib/common/plugin/capture.js")} catch(e) {console.log("exception: in lib/common/plugin/capture.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/compass\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    utils = require('cordova/utils'),\n    CompassHeading = require('cordova/plugin/CompassHeading'),\n    CompassError = require('cordova/plugin/CompassError'),\n    timers = {},\n    compass = {\n        /**\n         * Asynchronously acquires the current heading.\n         * @param {Function} successCallback The function to call when the heading\n         * data is available\n         * @param {Function} errorCallback The function to call when there is an error\n         * getting the heading data.\n         * @param {CompassOptions} options The options for getting the heading data (not used).\n         */\n        getCurrentHeading:function(successCallback, errorCallback, options) {\n            // successCallback required\n            if (typeof successCallback !== \"function\") {\n              console.log(\"Compass Error: successCallback is not a function\");\n              return;\n            }\n\n            // errorCallback optional\n            if (errorCallback && (typeof errorCallback !== \"function\")) {\n              console.log(\"Compass Error: errorCallback is not a function\");\n              return;\n            }\n\n            var win = function(result) {\n                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);\n                successCallback(ch);\n            };\n            var fail = function(code) {\n                var ce = new CompassError(code);\n                errorCallback(ce);\n            };\n\n            // Get heading\n            exec(win, fail, \"Compass\", \"getHeading\", [options]);\n        },\n\n        /**\n         * Asynchronously acquires the heading repeatedly at a given interval.\n         * @param {Function} successCallback The function to call each time the heading\n         * data is available\n         * @param {Function} errorCallback The function to call when there is an error\n         * getting the heading data.\n         * @param {HeadingOptions} options The options for getting the heading data\n         * such as timeout and the frequency of the watch. For iOS, filter parameter\n         * specifies to watch via a distance filter rather than time.\n         */\n        watchHeading:function(successCallback, errorCallback, options) {\n            // Default interval (100 msec)\n            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;\n            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;\n\n            // successCallback required\n            if (typeof successCallback !== \"function\") {\n              console.log(\"Compass Error: successCallback is not a function\");\n              return;\n            }\n\n            // errorCallback optional\n            if (errorCallback && (typeof errorCallback !== \"function\")) {\n              console.log(\"Compass Error: errorCallback is not a function\");\n              return;\n            }\n\n            var id = utils.createUUID();\n            if (filter > 0) {\n                // is an iOS request for watch by filter, no timer needed\n                timers[id] = \"iOS\";\n                compass.getCurrentHeading(successCallback, errorCallback, options);\n            } else {\n                // Start watch timer to get headings\n                timers[id] = window.setInterval(function() {\n                    compass.getCurrentHeading(successCallback, errorCallback);\n                }, frequency);\n            }\n\n            return id;\n        },\n\n        /**\n         * Clears the specified heading watch.\n         * @param {String} watchId The ID of the watch returned from #watchHeading.\n         */\n        clearWatch:function(id) {\n            // Stop javascript timer & remove from timer list\n            if (id && timers[id]) {\n                if (timers[id] != \"iOS\") {\n                      clearInterval(timers[id]);\n                  } else {\n                    // is iOS watch by filter so call into device to stop\n                    exec(null, null, \"Compass\", \"stopHeading\", []);\n                }\n                delete timers[id];\n            }\n        }\n    };\n\nmodule.exports = compass;\n});\n\n//@ sourceURL=lib/common/plugin/compass.js")} catch(e) {console.log("exception: in lib/common/plugin/compass.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/console-via-logger\", function(require, exports, module) {\n//------------------------------------------------------------------------------\n\nvar logger = require(\"cordova/plugin/logger\");\nvar utils  = require(\"cordova/utils\");\n\n//------------------------------------------------------------------------------\n// object that we're exporting\n//------------------------------------------------------------------------------\nvar console = module.exports;\n\n//------------------------------------------------------------------------------\n// copy of the original console object\n//------------------------------------------------------------------------------\nvar WinConsole = window.console;\n\n//------------------------------------------------------------------------------\n// whether to use the logger\n//------------------------------------------------------------------------------\nvar UseLogger = false;\n\n//------------------------------------------------------------------------------\n// Timers\n//------------------------------------------------------------------------------\nvar Timers = {};\n\n//------------------------------------------------------------------------------\n// used for unimplemented methods\n//------------------------------------------------------------------------------\nfunction noop() {}\n\n//------------------------------------------------------------------------------\n// used for unimplemented methods\n//------------------------------------------------------------------------------\nconsole.useLogger = function (value) {\n    if (arguments.length) UseLogger = !!value;\n\n    if (UseLogger) {\n        if (logger.useConsole()) {\n            throw new Error(\"console and logger are too intertwingly\");\n        }\n    }\n\n    return UseLogger;\n};\n\n//------------------------------------------------------------------------------\nconsole.log = function() {\n    if (logger.useConsole()) return;\n    logger.log.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.error = function() {\n    if (logger.useConsole()) return;\n    logger.error.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.warn = function() {\n    if (logger.useConsole()) return;\n    logger.warn.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.info = function() {\n    if (logger.useConsole()) return;\n    logger.info.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.debug = function() {\n    if (logger.useConsole()) return;\n    logger.debug.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.assert = function(expression) {\n    if (expression) return;\n\n    var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));\n    console.log(\"ASSERT: \" + message);\n};\n\n//------------------------------------------------------------------------------\nconsole.clear = function() {};\n\n//------------------------------------------------------------------------------\nconsole.dir = function(object) {\n    console.log(\"%o\", object);\n};\n\n//------------------------------------------------------------------------------\nconsole.dirxml = function(node) {\n    console.log(node.innerHTML);\n};\n\n//------------------------------------------------------------------------------\nconsole.trace = noop;\n\n//------------------------------------------------------------------------------\nconsole.group = console.log;\n\n//------------------------------------------------------------------------------\nconsole.groupCollapsed = console.log;\n\n//------------------------------------------------------------------------------\nconsole.groupEnd = noop;\n\n//------------------------------------------------------------------------------\nconsole.time = function(name) {\n    Timers[name] = new Date().valueOf();\n};\n\n//------------------------------------------------------------------------------\nconsole.timeEnd = function(name) {\n    var timeStart = Timers[name];\n    if (!timeStart) {\n        console.warn(\"unknown timer: \" + name);\n        return;\n    }\n\n    var timeElapsed = new Date().valueOf() - timeStart;\n    console.log(name + \": \" + timeElapsed + \"ms\");\n};\n\n//------------------------------------------------------------------------------\nconsole.timeStamp = noop;\n\n//------------------------------------------------------------------------------\nconsole.profile = noop;\n\n//------------------------------------------------------------------------------\nconsole.profileEnd = noop;\n\n//------------------------------------------------------------------------------\nconsole.count = noop;\n\n//------------------------------------------------------------------------------\nconsole.exception = console.log;\n\n//------------------------------------------------------------------------------\nconsole.table = function(data, columns) {\n    console.log(\"%o\", data);\n};\n\n//------------------------------------------------------------------------------\n// return a new function that calls both functions passed as args\n//------------------------------------------------------------------------------\nfunction wrapperedOrigCall(orgFunc, newFunc) {\n    return function() {\n        var args = [].slice.call(arguments);\n        try { orgFunc.apply(WinConsole, args); } catch (e) {}\n        try { newFunc.apply(console,    args); } catch (e) {}\n    };\n}\n\n//------------------------------------------------------------------------------\n// For every function that exists in the original console object, that\n// also exists in the new console object, wrap the new console method\n// with one that calls both\n//------------------------------------------------------------------------------\nfor (var key in console) {\n    if (typeof WinConsole[key] == \"function\") {\n        console[key] = wrapperedOrigCall(WinConsole[key], console[key]);\n    }\n}\n\n});\n\n//@ sourceURL=lib/common/plugin/console-via-logger.js")} catch(e) {console.log("exception: in lib/common/plugin/console-via-logger.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/contacts\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    ContactError = require('cordova/plugin/ContactError'),\n    utils = require('cordova/utils'),\n    Contact = require('cordova/plugin/Contact');\n\n/**\n* Represents a group of Contacts.\n* @constructor\n*/\nvar contacts = {\n    /**\n     * Returns an array of Contacts matching the search criteria.\n     * @param fields that should be searched\n     * @param successCB success callback\n     * @param errorCB error callback\n     * @param {ContactFindOptions} options that can be applied to contact searching\n     * @return array of Contacts matching search criteria\n     */\n    find:function(fields, successCB, errorCB, options) {\n        if (!successCB) {\n            throw new TypeError(\"You must specify a success callback for the find command.\");\n        }\n        if (!fields || (utils.isArray(fields) && fields.length === 0)) {\n            if (typeof errorCB === \"function\") {\n                errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));\n            }\n        } else {\n            var win = function(result) {\n                var cs = [];\n                for (var i = 0, l = result.length; i < l; i++) {\n                    cs.push(contacts.create(result[i]));\n                }\n                successCB(cs);\n            };\n            exec(win, errorCB, \"Contacts\", \"search\", [fields, options]);\n        }\n    },\n\n    /**\n     * This function creates a new contact, but it does not persist the contact\n     * to device storage. To persist the contact to device storage, invoke\n     * contact.save().\n     * @param properties an object who's properties will be examined to create a new Contact\n     * @returns new Contact object\n     */\n    create:function(properties) {\n        var i;\n        var contact = new Contact();\n        for (i in properties) {\n            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {\n                contact[i] = properties[i];\n            }\n        }\n        return contact;\n    }\n};\n\nmodule.exports = contacts;\n\n});\n\n//@ sourceURL=lib/common/plugin/contacts.js")} catch(e) {console.log("exception: in lib/common/plugin/contacts.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/device\", function(require, exports, module) {\nvar channel = require('cordova/channel'),\n    utils = require('cordova/utils'),\n    exec = require('cordova/exec');\n\n// Tell cordova channel to wait on the CordovaInfoReady event\nchannel.waitForInitialization('onCordovaInfoReady');\n\n/**\n * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the\n * phone, etc.\n * @constructor\n */\nfunction Device() {\n    this.available = false;\n    this.platform = null;\n    this.version = null;\n    this.name = null;\n    this.uuid = null;\n    this.cordova = null;\n\n    var me = this;\n\n    channel.onCordovaReady.subscribeOnce(function() {\n        me.getInfo(function(info) {\n            me.available = true;\n            me.platform = info.platform;\n            me.version = info.version;\n            me.name = info.name;\n            me.uuid = info.uuid;\n            me.cordova = info.cordova;\n            channel.onCordovaInfoReady.fire();\n        },function(e) {\n            me.available = false;\n            utils.alert(\"[ERROR] Error initializing Cordova: \" + e);\n        });\n    });\n}\n\n/**\n * Get device info\n *\n * @param {Function} successCallback The function to call when the heading data is available\n * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)\n */\nDevice.prototype.getInfo = function(successCallback, errorCallback) {\n\n    // successCallback required\n    if (typeof successCallback !== \"function\") {\n        console.log(\"Device Error: successCallback is not a function\");\n        return;\n    }\n\n    // errorCallback optional\n    if (errorCallback && (typeof errorCallback !== \"function\")) {\n        console.log(\"Device Error: errorCallback is not a function\");\n        return;\n    }\n\n    // Get info\n    exec(successCallback, errorCallback, \"Device\", \"getDeviceInfo\", []);\n};\n\nmodule.exports = new Device();\n\n});\n\n//@ sourceURL=lib/common/plugin/device.js")} catch(e) {console.log("exception: in lib/common/plugin/device.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/geolocation\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    PositionError = require('cordova/plugin/PositionError'),\n    Position = require('cordova/plugin/Position');\n\nvar timers = {};   // list of timers in use\n\n// Returns default params, overrides if provided with values\nfunction parseParameters(options) {\n    var opt = {\n        maximumAge: 0,\n        enableHighAccuracy: false,\n        timeout: Infinity\n    };\n\n    if (options) {\n        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {\n            opt.maximumAge = options.maximumAge;\n        }\n        if (options.enableHighAccuracy !== undefined) {\n            opt.enableHighAccuracy = options.enableHighAccuracy;\n        }\n        if (options.timeout !== undefined && !isNaN(options.timeout)) {\n            if (options.timeout < 0) {\n                opt.timeout = 0;\n            } else {\n                opt.timeout = options.timeout;\n            }\n        }\n    }\n\n    return opt;\n}\n\n// Returns a timeout failure, closed over a specified timeout value and error callback.\nfunction createTimeout(errorCallback, timeout) {\n    var t = setTimeout(function() {\n        clearTimeout(t);\n        t = null;\n        errorCallback({\n            code:PositionError.TIMEOUT,\n            message:\"Position retrieval timed out.\"\n        });\n    }, timeout);\n    return t;\n}\n\nvar geolocation = {\n    lastPosition:null, // reference to last known (cached) position returned\n    /**\n   * Asynchronously aquires the current position.\n   *\n   * @param {Function} successCallback    The function to call when the position data is available\n   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)\n   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)\n   */\n    getCurrentPosition:function(successCallback, errorCallback, options) {\n        if (arguments.length === 0) {\n            throw new Error(\"getCurrentPosition must be called with at least one argument.\");\n        }\n        options = parseParameters(options);\n\n        // Timer var that will fire an error callback if no position is retrieved from native\n        // before the \"timeout\" param provided expires\n        var timeoutTimer = null;\n\n        var win = function(p) {\n            clearTimeout(timeoutTimer);\n            if (!timeoutTimer) {\n                // Timeout already happened, or native fired error callback for\n                // this geo request.\n                // Don't continue with success callback.\n                return;\n            }\n            var pos = new Position(\n                {\n                    latitude:p.latitude,\n                    longitude:p.longitude,\n                    altitude:p.altitude,\n                    accuracy:p.accuracy,\n                    heading:p.heading,\n                    velocity:p.velocity,\n                    altitudeAccuracy:p.altitudeAccuracy\n                },\n                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))\n            );\n            geolocation.lastPosition = pos;\n            successCallback(pos);\n        };\n        var fail = function(e) {\n            clearTimeout(timeoutTimer);\n            timeoutTimer = null;\n            var err = new PositionError(e.code, e.message);\n            if (errorCallback) {\n                errorCallback(err);\n            }\n        };\n\n        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just\n        // fire the success callback with the cached position.\n        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {\n            successCallback(geolocation.lastPosition);\n        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.\n        } else if (options.timeout === 0) {\n            fail({\n                code:PositionError.TIMEOUT,\n                message:\"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter.\"\n            });\n        // Otherwise we have to call into native to retrieve a position.\n        } else {\n            if (options.timeout !== Infinity) {\n                // If the timeout value was not set to Infinity (default), then\n                // set up a timeout function that will fire the error callback\n                // if no successful position was retrieved before timeout expired.\n                timeoutTimer = createTimeout(fail, options.timeout);\n            } else {\n                // This is here so the check in the win function doesn't mess stuff up\n                // may seem weird but this guarantees timeoutTimer is\n                // always truthy before we call into native\n                timeoutTimer = true;\n            }\n            exec(win, fail, \"Geolocation\", \"getLocation\", [options.enableHighAccuracy, options.maximumAge]);\n        }\n        return timeoutTimer;\n    },\n    /**\n     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,\n     * the successCallback is called with the new location.\n     *\n     * @param {Function} successCallback    The function to call each time the location data is available\n     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)\n     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)\n     * @return String                       The watch id that must be passed to #clearWatch to stop watching.\n     */\n    watchPosition:function(successCallback, errorCallback, options) {\n        if (arguments.length === 0) {\n            throw new Error(\"watchPosition must be called with at least one argument.\");\n        }\n        options = parseParameters(options);\n\n        var id = utils.createUUID();\n\n        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition\n        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);\n\n        var fail = function(e) {\n            clearTimeout(timers[id]);\n            var err = new PositionError(e.code, e.message);\n            if (errorCallback) {\n                errorCallback(err);\n            }\n        };\n\n        var win = function(p) {\n            clearTimeout(timers[id]);\n            if (options.timeout !== Infinity) {\n                timers[id] = createTimeout(fail, options.timeout);\n            }\n            var pos = new Position(\n                {\n                    latitude:p.latitude,\n                    longitude:p.longitude,\n                    altitude:p.altitude,\n                    accuracy:p.accuracy,\n                    heading:p.heading,\n                    velocity:p.velocity,\n                    altitudeAccuracy:p.altitudeAccuracy\n                },\n                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))\n            );\n            geolocation.lastPosition = pos;\n            successCallback(pos);\n        };\n\n        exec(win, fail, \"Geolocation\", \"addWatch\", [id, options.enableHighAccuracy]);\n\n        return id;\n    },\n    /**\n     * Clears the specified heading watch.\n     *\n     * @param {String} id       The ID of the watch returned from #watchPosition\n     */\n    clearWatch:function(id) {\n        if (id && timers[id] !== undefined) {\n            clearTimeout(timers[id]);\n            delete timers[id];\n            exec(null, null, \"Geolocation\", \"clearWatch\", [id]);\n        }\n    }\n};\n\nmodule.exports = geolocation;\n\n});\n\n//@ sourceURL=lib/common/plugin/geolocation.js")} catch(e) {console.log("exception: in lib/common/plugin/geolocation.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/logger\", function(require, exports, module) {\n//------------------------------------------------------------------------------\n// The logger module exports the following properties/functions:\n//\n// LOG                          - constant for the level LOG\n// ERROR                        - constant for the level ERROR\n// WARN                         - constant for the level WARN\n// INFO                         - constant for the level INFO\n// DEBUG                        - constant for the level DEBUG\n// logLevel()                   - returns current log level\n// logLevel(value)              - sets and returns a new log level\n// useConsole()                 - returns whether logger is using console\n// useConsole(value)            - sets and returns whether logger is using console\n// log(message,...)             - logs a message at level LOG\n// error(message,...)           - logs a message at level ERROR\n// warn(message,...)            - logs a message at level WARN\n// info(message,...)            - logs a message at level INFO\n// debug(message,...)           - logs a message at level DEBUG\n// logLevel(level,message,...)  - logs a message specified level\n//\n//------------------------------------------------------------------------------\n\nvar logger = exports;\n\nvar exec    = require('cordova/exec');\nvar utils   = require('cordova/utils');\n\nvar UseConsole   = true;\nvar Queued       = [];\nvar DeviceReady  = false;\nvar CurrentLevel;\n\n/**\n * Logging levels\n */\n\nvar Levels = [\n    \"LOG\",\n    \"ERROR\",\n    \"WARN\",\n    \"INFO\",\n    \"DEBUG\"\n];\n\n/*\n * add the logging levels to the logger object and\n * to a separate levelsMap object for testing\n */\n\nvar LevelsMap = {};\nfor (var i=0; i<Levels.length; i++) {\n    var level = Levels[i];\n    LevelsMap[level] = i;\n    logger[level]    = level;\n}\n\nCurrentLevel = LevelsMap.WARN;\n\n/**\n * Getter/Setter for the logging level\n *\n * Returns the current logging level.\n *\n * When a value is passed, sets the logging level to that value.\n * The values should be one of the following constants:\n *    logger.LOG\n *    logger.ERROR\n *    logger.WARN\n *    logger.INFO\n *    logger.DEBUG\n *\n * The value used determines which messages get printed.  The logging\n * values above are in order, and only messages logged at the logging\n * level or above will actually be displayed to the user.  Eg, the\n * default level is WARN, so only messages logged with LOG, ERROR, or\n * WARN will be displayed; INFO and DEBUG messages will be ignored.\n */\nlogger.level = function (value) {\n    if (arguments.length) {\n        if (LevelsMap[value] === null) {\n            throw new Error(\"invalid logging level: \" + value);\n        }\n        CurrentLevel = LevelsMap[value];\n    }\n\n    return Levels[CurrentLevel];\n};\n\n/**\n * Getter/Setter for the useConsole functionality\n *\n * When useConsole is true, the logger will log via the\n * browser 'console' object.  Otherwise, it will use the\n * native Logger plugin.\n */\nlogger.useConsole = function (value) {\n    if (arguments.length) UseConsole = !!value;\n\n    if (UseConsole) {\n        if (typeof console == \"undefined\") {\n            throw new Error(\"global console object is not defined\");\n        }\n\n        if (typeof console.log != \"function\") {\n            throw new Error(\"global console object does not have a log function\");\n        }\n\n        if (typeof console.useLogger == \"function\") {\n            if (console.useLogger()) {\n                throw new Error(\"console and logger are too intertwingly\");\n            }\n        }\n    }\n\n    return UseConsole;\n};\n\n/**\n * Logs a message at the LOG level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.log   = function(message) { logWithArgs(\"LOG\",   arguments); };\n\n/**\n * Logs a message at the ERROR level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.error = function(message) { logWithArgs(\"ERROR\", arguments); };\n\n/**\n * Logs a message at the WARN level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.warn  = function(message) { logWithArgs(\"WARN\",  arguments); };\n\n/**\n * Logs a message at the INFO level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.info  = function(message) { logWithArgs(\"INFO\",  arguments); };\n\n/**\n * Logs a message at the DEBUG level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.debug = function(message) { logWithArgs(\"DEBUG\", arguments); };\n\n// log at the specified level with args\nfunction logWithArgs(level, args) {\n    args = [level].concat([].slice.call(args));\n    logger.logLevel.apply(logger, args);\n}\n\n/**\n * Logs a message at the specified level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.logLevel = function(level, message /* , ... */) {\n    // format the message with the parameters\n    var formatArgs = [].slice.call(arguments, 2);\n    message    = utils.vformat(message, formatArgs);\n\n    if (LevelsMap[level] === null) {\n        throw new Error(\"invalid logging level: \" + level);\n    }\n\n    if (LevelsMap[level] > CurrentLevel) return;\n\n    // queue the message if not yet at deviceready\n    if (!DeviceReady && !UseConsole) {\n        Queued.push([level, message]);\n        return;\n    }\n\n    // if not using the console, use the native logger\n    if (!UseConsole) {\n        exec(null, null, \"Logger\", \"logLevel\", [level, message]);\n        return;\n    }\n\n    // make sure console is not using logger\n    if (console.__usingCordovaLogger) {\n        throw new Error(\"console and logger are too intertwingly\");\n    }\n\n    // log to the console\n    switch (level) {\n        case logger.LOG:   console.log(message); break;\n        case logger.ERROR: console.log(\"ERROR: \" + message); break;\n        case logger.WARN:  console.log(\"WARN: \"  + message); break;\n        case logger.INFO:  console.log(\"INFO: \"  + message); break;\n        case logger.DEBUG: console.log(\"DEBUG: \" + message); break;\n    }\n};\n\n// when deviceready fires, log queued messages\nlogger.__onDeviceReady = function() {\n    if (DeviceReady) return;\n\n    DeviceReady = true;\n\n    for (var i=0; i<Queued.length; i++) {\n        var messageArgs = Queued[i];\n        logger.logLevel(messageArgs[0], messageArgs[1]);\n    }\n\n    Queued = null;\n};\n\n// add a deviceready event to log queued messages\ndocument.addEventListener(\"deviceready\", logger.__onDeviceReady, false);\n\n});\n\n//@ sourceURL=lib/common/plugin/logger.js")} catch(e) {console.log("exception: in lib/common/plugin/logger.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/network\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    cordova = require('cordova'),\n    channel = require('cordova/channel');\n\nvar NetworkConnection = function () {\n    this.type = null;\n    this._firstRun = true;\n    this._timer = null;\n    this.timeout = 500;\n\n    var me = this;\n\n    channel.onCordovaReady.subscribeOnce(function() {\n        me.getInfo(function (info) {\n            me.type = info;\n            if (info === \"none\") {\n                // set a timer if still offline at the end of timer send the offline event\n                me._timer = setTimeout(function(){\n                    cordova.fireDocumentEvent(\"offline\");\n                    me._timer = null;\n                    }, me.timeout);\n            } else {\n                // If there is a current offline event pending clear it\n                if (me._timer !== null) {\n                    clearTimeout(me._timer);\n                    me._timer = null;\n                }\n                cordova.fireDocumentEvent(\"online\");\n            }\n\n            // should only fire this once\n            if (me._firstRun) {\n                me._firstRun = false;\n                channel.onCordovaConnectionReady.fire();\n            }\n        },\n        function (e) {\n            // If we can't get the network info we should still tell Cordova\n            // to fire the deviceready event.\n            if (me._firstRun) {\n                me._firstRun = false;\n                channel.onCordovaConnectionReady.fire();\n            }\n            console.log(\"Error initializing Network Connection: \" + e);\n        });\n    });\n};\n\n/**\n * Get connection info\n *\n * @param {Function} successCallback The function to call when the Connection data is available\n * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)\n */\nNetworkConnection.prototype.getInfo = function (successCallback, errorCallback) {\n    // Get info\n    exec(successCallback, errorCallback, \"NetworkStatus\", \"getConnectionInfo\", []);\n};\n\nmodule.exports = new NetworkConnection();\n});\n\n//@ sourceURL=lib/common/plugin/network.js")} catch(e) {console.log("exception: in lib/common/plugin/network.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/notification\", function(require, exports, module) {\nvar exec = require('cordova/exec');\n\n/**\n * Provides access to notifications on the device.\n */\n\nmodule.exports = {\n\n    /**\n     * Open a native alert dialog, with a customizable title and button text.\n     *\n     * @param {String} message              Message to print in the body of the alert\n     * @param {Function} completeCallback   The callback that is called when user clicks on a button.\n     * @param {String} title                Title of the alert dialog (default: Alert)\n     * @param {String} buttonLabel          Label of the close button (default: OK)\n     */\n    alert: function(message, completeCallback, title, buttonLabel) {\n        var _title = (title || \"Alert\");\n        var _buttonLabel = (buttonLabel || \"OK\");\n        exec(completeCallback, null, \"Notification\", \"alert\", [message, _title, _buttonLabel]);\n    },\n\n    /**\n     * Open a native confirm dialog, with a customizable title and button text.\n     * The result that the user selects is returned to the result callback.\n     *\n     * @param {String} message              Message to print in the body of the alert\n     * @param {Function} resultCallback     The callback that is called when user clicks on a button.\n     * @param {String} title                Title of the alert dialog (default: Confirm)\n     * @param {String} buttonLabels         Comma separated list of the labels of the buttons (default: 'OK,Cancel')\n     */\n    confirm: function(message, resultCallback, title, buttonLabels) {\n        var _title = (title || \"Confirm\");\n        var _buttonLabels = (buttonLabels || \"OK,Cancel\");\n        exec(resultCallback, null, \"Notification\", \"confirm\", [message, _title, _buttonLabels]);\n    },\n\n    /**\n     * Causes the device to vibrate.\n     *\n     * @param {Integer} mills       The number of milliseconds to vibrate for.\n     */\n    vibrate: function(mills) {\n        exec(null, null, \"Notification\", \"vibrate\", [mills]);\n    },\n\n    /**\n     * Causes the device to beep.\n     * On Android, the default notification ringtone is played \"count\" times.\n     *\n     * @param {Integer} count       The number of beeps.\n     */\n    beep: function(count) {\n        exec(null, null, \"Notification\", \"beep\", [count]);\n    }\n};\n});\n\n//@ sourceURL=lib/common/plugin/notification.js")} catch(e) {console.log("exception: in lib/common/plugin/notification.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/requestFileSystem\", function(require, exports, module) {\nvar FileError = require('cordova/plugin/FileError'),\n    FileSystem = require('cordova/plugin/FileSystem'),\n    exec = require('cordova/exec');\n\n/**\n * Request a file system in which to store application data.\n * @param type  local file system type\n * @param size  indicates how much storage space, in bytes, the application expects to need\n * @param successCallback  invoked with a FileSystem object\n * @param errorCallback  invoked if error occurs retrieving file system\n */\nvar requestFileSystem = function(type, size, successCallback, errorCallback) {\n    var fail = function(code) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(code));\n        }\n    };\n\n    if (type < 0 || type > 3) {\n        fail(FileError.SYNTAX_ERR);\n    } else {\n        // if successful, return a FileSystem object\n        var success = function(file_system) {\n            if (file_system) {\n                if (typeof successCallback === 'function') {\n                    // grab the name and root from the file system object\n                    var result = new FileSystem(file_system.name, file_system.root);\n                    successCallback(result);\n                }\n            }\n            else {\n                // no FileSystem object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n        exec(success, fail, \"File\", \"requestFileSystem\", [type, size]);\n    }\n};\n\nmodule.exports = requestFileSystem;\n});\n\n//@ sourceURL=lib/common/plugin/requestFileSystem.js")} catch(e) {console.log("exception: in lib/common/plugin/requestFileSystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/resolveLocalFileSystemURI\", function(require, exports, module) {\nvar DirectoryEntry = require('cordova/plugin/DirectoryEntry'),\n    FileEntry = require('cordova/plugin/FileEntry'),\n    FileError = require('cordova/plugin/FileError'),\n    exec = require('cordova/exec');\n\n/**\n * Look up file system Entry referred to by local URI.\n * @param {DOMString} uri  URI referring to a local file or directory\n * @param successCallback  invoked with Entry object corresponding to URI\n * @param errorCallback    invoked if error occurs retrieving file system entry\n */\nmodule.exports = function(uri, successCallback, errorCallback) {\n    // error callback\n    var fail = function(error) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(error));\n        }\n    };\n    // sanity check for 'not:valid:filename'\n    if(!uri || uri.split(\":\").length > 2) {\n        setTimeout( function() {\n            fail(FileError.ENCODING_ERR);\n        },0);\n        return;\n    }\n    // if successful, return either a file or directory entry\n    var success = function(entry) {\n        var result;\n        if (entry) {\n            if (typeof successCallback === 'function') {\n                // create appropriate Entry object\n                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);\n                try {\n                    successCallback(result);\n                }\n                catch (e) {\n                    console.log('Error invoking callback: ' + e);\n                }\n            }\n        }\n        else {\n            // no Entry object returned\n            fail(FileError.NOT_FOUND_ERR);\n        }\n    };\n\n    exec(success, fail, \"File\", \"resolveLocalFileSystemURI\", [uri]);\n};\n\n});\n\n//@ sourceURL=lib/common/plugin/resolveLocalFileSystemURI.js")} catch(e) {console.log("exception: in lib/common/plugin/resolveLocalFileSystemURI.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/splashscreen\", function(require, exports, module) {\nvar exec = require('cordova/exec');\n\nvar splashscreen = {\n    show:function() {\n        exec(null, null, \"SplashScreen\", \"show\", []);\n    },\n    hide:function() {\n        exec(null, null, \"SplashScreen\", \"hide\", []);\n    }\n};\n\nmodule.exports = splashscreen;\n});\n\n//@ sourceURL=lib/common/plugin/splashscreen.js")} catch(e) {console.log("exception: in lib/common/plugin/splashscreen.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Accelerometer\", function(require, exports, module) {\nvar callback = null;\n\nmodule.exports = {\n    start: function (successCallback, errorCallback) {\n        window.removeEventListener(\"devicemotion\", callback);\n        callback = function (motion) {\n            successCallback({\n                x: motion.accelerationIncludingGravity.x,\n                y: motion.accelerationIncludingGravity.y,\n                z: motion.accelerationIncludingGravity.z,\n                timestamp: motion.timeStamp\n            });\n        };\n        window.addEventListener(\"devicemotion\", callback);\n    },\n    stop: function (successCallback, errorCallback) {\n        window.removeEventListener(\"devicemotion\", callback);\n    }\n};\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Accelerometer.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Accelerometer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Battery\", function(require, exports, module) {\n/*global tizen:false */\nvar id = null;\n\nmodule.exports = {\n    start: function(successCallback, errorCallback) {\n        var tizenSuccessCallback = function(power) {\n            if (successCallback) {\n                successCallback({level: Math.round(power.level * 100), isPlugged: power.isCharging});\n            }\n        };\n\n        if (id === null) {\n            id = tizen.systeminfo.addPropertyValueChangeListener(\"Power\", tizenSuccessCallback);\n        }\n        tizen.systeminfo.getPropertyValue(\"Power\", tizenSuccessCallback, errorCallback);\n    },\n\n    stop: function(successCallback, errorCallback) {\n        tizen.systeminfo.removePropertyValueChangeListener(id);\n        id = null;\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Battery.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Battery.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/BufferLoader\", function(require, exports, module) {\n/*\n * Buffer Loader Object\n * This class provides a sound buffer for one or more sounds\n * holded in a local file located by an url\n *\n * uses W3C  Web Audio API\n *\n * @constructor\n *\n * @param {AudioContext} audio context object\n * @param {Array} urlList, array of url for sound to load\n * @param {function} callback , called after buffer was loaded\n *\n */\n\nfunction BufferLoader(context, urlList, callback) {\n    this.context = context;\n    this.urlList = urlList;\n    this.onload = callback;\n    this.bufferList = [];\n    this.loadCount = 0;\n}\n\n/*\n * This method loads a sound into a buffer\n * @param {Array} urlList, array of url for sound to load\n * @param {Number} index, buffer index in the array where to load the url sound\n *\n */\n\nBufferLoader.prototype.loadBuffer = function(url, index) {\n    // Load buffer asynchronously\n    var request = null,\n        loader = null;\n\n    request = new XMLHttpRequest();\n\n    if (request === null) {\n        console.log (\"BufferLoader.prototype.loadBuffer, cannot allocate XML http request\");\n        return;\n    }\n\n    request.open(\"GET\", url, true);\n    request.responseType = \"arraybuffer\";\n\n    loader = this;\n\n    request.onload = function() {\n    // Asynchronously decode the audio file data in request.response\n    loader.context.decodeAudioData(\n        request.response,\n        function(buffer) {\n                if (!buffer) {\n                    console.log (\"BufferLoader.prototype.loadBuffer,error decoding file data: \" + url);\n                    return;\n                }\n\n                loader.bufferList[index] = buffer;\n\n                if (++loader.loadCount == loader.urlList.length) {\n                    loader.onload(loader.bufferList);\n                }\n            }\n        );\n    };\n\n    request.onerror = function() {\n        console.log (\"BufferLoader.prototype.loadBuffer, XHR error\");\n    };\n\n    request.send();\n};\n\n/*\n * This method loads all sounds identified by their url\n * and that where given to the object constructor\n *\n */\n\nBufferLoader.prototype.load = function() {\n    for (var i = 0; i < this.urlList.length; ++i) {\n        this.loadBuffer(this.urlList[i], i);\n    }\n};\n\nmodule.exports = BufferLoader;\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/BufferLoader.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/BufferLoader.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Camera\", function(require, exports, module) {\n/*global tizen:false */\nvar Camera = require('cordova/plugin/CameraConstants');\n\nfunction makeReplyCallback(successCallback, errorCallback) {\n    return {\n        onsuccess: function(reply) {\n            if (reply.length > 0) {\n                successCallback(reply[0].value);\n            } else {\n                errorCallback('Picture selection aborted');\n            }\n        },\n        onfail: function() {\n           console.log('The service launch failed');\n        }\n    };\n}\n\nmodule.exports = {\n    takePicture: function(successCallback, errorCallback, args) {\n        var destinationType = args[1],\n            sourceType = args[2],\n            encodingType = args[5],\n            mediaType = args[6];\n            // Not supported\n            /*\n            quality = args[0]\n            targetWidth = args[3]\n            targetHeight = args[4]\n            allowEdit = args[7]\n            correctOrientation = args[8]\n            saveToPhotoAlbum = args[9]\n            */\n\n        if (destinationType !== Camera.DestinationType.FILE_URI) {\n            errorCallback('DestinationType not supported');\n            return;\n        }\n        if (mediaType !== Camera.MediaType.PICTURE) {\n            errorCallback('MediaType not supported');\n            return;\n        }\n\n        var mimeType;\n        if (encodingType === Camera.EncodingType.JPEG) {\n            mimeType = 'image/jpeg';\n        } else if (encodingType === Camera.EncodingType.PNG) {\n            mimeType = 'image/png';\n        } else {\n            mimeType = 'image/*';\n        }\n\n        var serviceId;\n        if (sourceType === Camera.PictureSourceType.CAMERA) {\n            serviceId = 'http://tizen.org/appsvc/operation/create_content';\n        } else {\n            serviceId = 'http://tizen.org/appsvc/operation/pick';\n        }\n\n        var service = new tizen.ApplicationService(serviceId, null, mimeType, null);\n        tizen.application.launchService(service, null, null,\n                function(error) { errorCallback(error.message); },\n                makeReplyCallback(successCallback, errorCallback));\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Camera.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Camera.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Compass\", function(require, exports, module) {\nvar CompassError = require('cordova/plugin/CompassError'),\n    callback = null, ready = false;\n\nmodule.exports = {\n    getHeading: function(successCallback, errorCallback) {\n        if (window.DeviceOrientationEvent !== undefined) {\n            callback = function (orientation) {\n                var heading = 360 - orientation.alpha;\n                if (ready) {\n                    successCallback({\n                        magneticHeading: heading,\n                        trueHeading: heading,\n                        headingAccuracy: 0,\n                        timestamp: orientation.timeStamp\n                    });\n                    window.removeEventListener(\"deviceorientation\", callback);\n                }\n                ready = true;\n            };\n            ready = false; // workaround invalid first event value returned by WRT\n            window.addEventListener(\"deviceorientation\", callback);\n        }\n        else {\n            errorCallback(CompassError.COMPASS_NOT_SUPPORTED);\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Compass.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Compass.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Contact\", function(require, exports, module) {\n/*global tizen:false */\nvar ContactError = require('cordova/plugin/ContactError'),\n    ContactUtils = require('cordova/plugin/tizen/ContactUtils'),\n    utils = require('cordova/utils'),\n    exec = require('cordova/exec');\n\n// ------------------\n// Utility functions\n// ------------------\n\n\n/**\n * Retrieves a Tizen Contact object from the device by its unique id.\n *\n * @param uid\n *            Unique id of the contact on the device\n * @return {tizen.Contact} Tizen Contact object or null if contact with\n *         specified id is not found\n */\nvar findByUniqueId = function(id) {\n\n    if (!id) {\n        return null;\n    }\n\n    var tizenContact = null;\n\n    tizen.contact.getDefaultAddressBook().find(\n        function _successCallback(contacts){\n            tizenContact = contacts[0];\n        },\n        function _errorCallback(error){\n            console.log(\"tizen find error \" + error);\n        },\n        new tizen.AttributeFilter('id', 'CONTAINS', id),\n        new tizen.SortMode('id', 'ASC'));\n\n    return tizenContact || null;\n};\n\n\nvar traceTizenContact = function (tizenContact) {\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.id \" + tizenContact.id);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.lastUpdated \" + tizenContact.lastUpdated);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.name \" + tizenContact.name);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.account \" + tizenContact.account);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.addresses \" + tizenContact.addresses);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.photoURI \" + tizenContact.photoURI);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.phoneNumbers \" + tizenContact.phoneNumbers);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.emails \" + tizenContact.emails);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.birthday \" + tizenContact.birthday);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.organization \" + tizenContact.organization);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.notes \" + tizenContact.notes);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.urls \" + tizenContact.isFavorite);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.isFavorite \" + tizenContact.isFavorite);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.ringtonesURI \" + tizenContact.ringtonesURI);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.categories \" + tizenContact.categories);\n};\n\n\n/**\n * Creates a Tizen contact object from the W3C Contact object and persists\n * it to device storage.\n *\n * @param {Contact}\n *            contact The contact to save\n * @return a new contact object with all properties set\n */\nvar saveToDevice = function(contact) {\n\n    if (!contact) {\n        return;\n    }\n\n    var tizenContact = null;\n    var update = false;\n    var i = 0;\n\n    // if the underlying Tizen Contact object already exists, retrieve it for\n    // update\n    if (contact.id) {\n        // we must attempt to retrieve the BlackBerry contact from the device\n        // because this may be an update operation\n        tizenContact = findByUniqueId(contact.id);\n    }\n\n    // contact not found on device, create a new one\n    if (!tizenContact) {\n        tizenContact = new tizen.Contact();\n    }\n    // update the existing contact\n    else {\n        update = true;\n    }\n\n    // NOTE: The user may be working with a partial Contact object, because only\n    // user-specified Contact fields are returned from a find operation (blame\n    // the W3C spec). If this is an update to an existing Contact, we don't\n    // want to clear an attribute from the contact database simply because the\n    // Contact object that the user passed in contains a null value for that\n    // attribute. So we only copy the non-null Contact attributes to the\n    // Tizen Contact object before saving.\n    //\n    // This means that a user must explicitly set a Contact attribute to a\n    // non-null value in order to update it in the contact database.\n    //\n    traceTizenContact (tizenContact);\n\n    // display name\n    if (contact.displayName !== null) {\n        if (tizenContact.name === null) {\n            tizenContact.name = new tizen.ContactName();\n        }\n        if (tizenContact.name !== null) {\n            tizenContact.name.displayName = contact.displayName;\n        }\n    }\n\n    // name\n    if (contact.name !== null) {\n        if (contact.name.givenName) {\n            if (tizenContact.name === null) {\n                tizenContact.name = new tizen.ContactName();\n            }\n            if (tizenContact.name !== null) {\n                tizenContact.name.firstName = contact.name.givenName;\n            }\n        }\n\n        if  (contact.name.middleName) {\n            if (tizenContact.name === null) {\n                tizenContact.name = new tizen.ContactName();\n            }\n            if (tizenContact.name !== null) {\n                tizenContact.name.middleName = contact.name.middleName;\n            }\n        }\n\n        if (contact.name.familyName) {\n            if (tizenContact.name === null) {\n                tizenContact.name = new tizen.ContactName();\n            }\n            if (tizenContact.name !== null) {\n                tizenContact.name.lastName = contact.name.familyName;\n            }\n        }\n\n        if (contact.name.honorificPrefix) {\n            if (tizenContact.name === null) {\n                tizenContact.name = new tizen.ContactName();\n            }\n            if (tizenContact.name !== null) {\n                tizenContact.name.prefix = contact.name.honorificPrefix;\n            }\n        }\n    }\n\n    // nickname\n    if (contact.nickname !== null) {\n        if (tizenContact.name === null) {\n            tizenContact.name = new tizen.ContactName();\n        }\n        if (tizenContact.name !== null) {\n            if (!utils.isArray(tizenContact.name.nicknames))\n            {\n                tizenContact.name.nicknames = [];\n            }\n            tizenContact.name.nicknames[0] = contact.nickname;\n        }\n    }\n    else {\n        tizenContact.name.nicknames = [];\n    }\n\n    // note\n    if (contact.note !== null) {\n        if (tizenContact.note === null) {\n            tizenContact.note = [];\n        }\n        if (tizenContact.note !== null) {\n            tizenContact.note[0] = contact.note;\n        }\n    }\n\n    // photos\n    if (contact.photos && utils.isArray(contact.emails) && contact.emails.length > 0) {\n        tizenContact.photoURI = contact.photos[0];\n    }\n\n    if (utils.isDate(contact.birthday)) {\n        if (!utils.isDate(tizenContact.birthday)) {\n            tizenContact.birthday = new Date();\n        }\n        if (utils.isDate(tizenContact.birthday)) {\n            tizenContact.birthday.setDate(contact.birthday.getDate());\n        }\n    }\n\n    // Tizen supports many addresses\n    if (utils.isArray(contact.emails)) {\n\n        // if this is an update, re initialize email addresses\n        if (update) {\n            // doit on effacer sur un update??????\n        }\n\n        // copy the first three email addresses found\n        var emails = [];\n        for (i = 0; i < contact.emails.length; i += 1) {\n            var emailTypes = [];\n\n            emailTypes.push (contact.emails[i].type);\n\n            if (contact.emails[i].pref) {\n                emailTypes.push (\"PREF\");\n            }\n\n            emails.push(\n                new tizen.ContactEmailAddress(\n                    contact.emails[i].value,\n                    emailTypes)\n            );\n        }\n        tizenContact.emails = emails.length > 0 ? emails : [];\n    }\n    else {\n        tizenContact.emails = [];\n    }\n\n    // Tizen supports many phone numbers\n    // copy into appropriate fields based on type\n    if (utils.isArray(contact.phoneNumbers)) {\n        // if this is an update, re-initialize phone numbers\n        if (update) {\n        }\n\n        var phoneNumbers = [];\n\n        for (i = 0; i < contact.phoneNumbers.length; i += 1) {\n\n            if (!contact.phoneNumbers[i] || !contact.phoneNumbers[i].value) {\n                continue;\n            }\n\n             var phoneTypes = [];\n             phoneTypes.push (contact.phoneNumbers[i].type);\n\n             if (contact.phoneNumbers[i].pref) {\n                 phoneTypes.push (\"PREF\");\n             }\n\n            phoneNumbers.push(\n                new tizen.ContactPhoneNumber(\n                    contact.phoneNumbers[i].value,\n                    phoneTypes)\n            );\n        }\n\n        tizenContact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : [];\n    } else {\n        tizenContact.phoneNumbers = [];\n    }\n\n    if (utils.isArray(contact.addresses)) {\n        // if this is an update, re-initialize addresses\n        if (update) {\n        }\n\n        var addresses = [],\n            address = null;\n\n        for ( i = 0; i < contact.addresses.length; i += 1) {\n            address = contact.addresses[i];\n\n            if (!address || address.id === undefined || address.pref === undefined || address.type === undefined || address.formatted === undefined) {\n                continue;\n            }\n\n            var addressTypes = [];\n            addressTypes.push (address.type);\n\n            if (address.pref) {\n                addressTypes.push (\"PREF\");\n            }\n\n            addresses.push(\n                new tizen.ContactAddress({\n                         country:                   address.country,\n                         region :                   address.region,\n                         city:                      address.locality,\n                         streetAddress:             address.streetAddress,\n                         additionalInformation:     \"\",\n                         postalCode:                address.postalCode,\n                         types :                    addressTypes\n                }));\n\n        }\n        tizenContact.addresses = addresses.length > 0 ? addresses : [];\n\n    } else{\n        tizenContact.addresses = [];\n    }\n\n    // copy first url found to BlackBerry 'webpage' field\n    if (utils.isArray(contact.urls)) {\n        // if this is an update, re-initialize web page\n        if (update) {\n        }\n\n        var url = null,\n            urls = [];\n\n        for ( i = 0; i< contact.urls.length; i+= 1) {\n            url = contact.urls[i];\n\n            if (!url || !url.value) {\n                continue;\n            }\n\n            urls.push( new tizen.ContactWebSite(url.value, url.type));\n        }\n        tizenContact.urls = urls.length > 0 ? urls : [];\n    } else{\n        tizenContact.urls = [];\n    }\n\n    if (utils.isArray(contact.organizations && contact.organizations.length > 0) ) {\n        // if this is an update, re-initialize org attributes\n        var organization = contact.organizations[0];\n\n         tizenContact.organization = new tizen.ContacOrganization({\n             name:          organization.name,\n             department:    organization.department,\n             office:        \"\",\n             title:         organization.title,\n             role:          \"\",\n             logoURI:       \"\"\n         });\n    }\n\n    // categories\n    if (utils.isArray(contact.categories)) {\n        tizenContact.categories = [];\n\n        var category = null;\n\n        for (i = 0; i < contact.categories.length; i += 1) {\n            category = contact.categories[i];\n\n            if (typeof category === \"string\") {\n                tizenContact.categories.push(category);\n            }\n        }\n    }\n    else {\n        tizenContact.categories = [];\n    }\n\n    // save to device\n    // in tizen contact mean update or add\n    // later we might use addBatch and updateBatch\n    if (update){\n        tizen.contact.getDefaultAddressBook().update(tizenContact);\n    }\n    else {\n        tizen.contact.getDefaultAddressBook().add(tizenContact);\n    }\n\n    // Use the fully populated Tizen contact object to create a\n    // corresponding W3C contact object.\n    return ContactUtils.createContact(tizenContact, [ \"*\" ]);\n};\n\n\n/**\n * Creates a Tizen ContactAddress object from a W3C ContactAddress.\n *\n * @return {tizen.ContactAddress} a Tizen ContactAddress object\n */\nvar createTizenAddress = function(address) {\n\n    var type = null,\n        pref = null,\n        typesAr = [];\n\n    if (address === null) {\n        return null;\n    }\n\n\n    var tizenAddress = new tizen.ContactAddress();\n\n    if (tizenAddress === null) {\n        return null;\n    }\n\n    typesAr.push(address.type);\n\n    if (address.pref) {\n        typesAr.push(\"PREF\");\n    }\n\n    tizenAddress.country = address.country || \"\";\n    tizenAddress.region = address.region || \"\";\n    tizenAddress.city = address.locality || \"\";\n    tizenAddress.streetAddress = address.streetAddress || \"\";\n    tizenAddress.postalCode = address.postalCode || \"\";\n    tizenAddress.types = typesAr || \"\";\n\n    return tizenAddress;\n};\n\nmodule.exports = {\n    /**\n     * Persists contact to device storage.\n     */\n\n    save : function(successCB, failCB) {\n\n        try {\n            // save the contact and store it's unique id\n            var fullContact = saveToDevice(this);\n\n            this.id = fullContact.id;\n\n            // This contact object may only have a subset of properties\n            // if the save was an update of an existing contact. This is\n            // because the existing contact was likely retrieved using a\n            // subset of properties, so only those properties were set in the\n            // object. For this reason, invoke success with the contact object\n            // returned by saveToDevice since it is fully populated.\n\n            if (typeof successCB === 'function') {\n                successCB(fullContact);\n            }\n        }\n        catch (error) {\n            console.log('Error saving contact: ' +  error);\n\n            if (typeof failCB === 'function') {\n                failCB (new ContactError(ContactError.UNKNOWN_ERROR));\n            }\n        }\n    },\n\n    /**\n     * Removes contact from device storage.\n     *\n     * @param successCB\n     *            successCB callback\n     * @param failCB\n     *            error callback\n     */\n    remove : function (successCB, failCB) {\n\n        try {\n            // retrieve contact from device by id\n            var tizenContact = null;\n\n            if (this.id) {\n                tizenContact = findByUniqueId(this.id);\n            }\n\n\n            // if contact was found, remove it\n            if (tizenContact) {\n\n                tizen.contact.getDefaultAddressBook().remove(tizenContact.id);\n\n                if (typeof success === 'function') {\n                    successCB(this);\n                }\n            }\n            // attempting to remove a contact that hasn't been saved\n            else if (typeof failCB === 'function') {\n                failCB(new ContactError(ContactError.UNKNOWN_ERROR));\n            }\n        }\n        catch (error) {\n            console.log('Error removing contact ' + this.id + \": \" + error);\n            if (typeof failCB === 'function') {\n                failCB(new ContactError(ContactError.UNKNOWN_ERROR));\n            }\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Contact.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Contact.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/ContactUtils\", function(require, exports, module) {\n/*global tizen:false */\nvar ContactAddress = require('cordova/plugin/ContactAddress'),\n    ContactName = require('cordova/plugin/ContactName'),\n    ContactField = require('cordova/plugin/ContactField'),\n    ContactOrganization = require('cordova/plugin/ContactOrganization'),\n    utils = require('cordova/utils'),\n    Contact = require('cordova/plugin/Contact');\n\n/**\n * Mappings for each Contact field that may be used in a find operation. Maps\n * W3C Contact fields to one or more fields in a Tizen contact object.\n *\n * Example: user searches with a filter on the Contact 'name' field:\n *\n * <code>Contacts.find(['name'], onSuccess, onFail, {filter:'Bob'});</code>\n *\n * The 'name' field does not exist in a Tizen contact. Instead, a filter\n * expression will be built to search the Tizen contacts using the\n * Tizen 'title', 'firstName' and 'lastName' fields.\n */\nvar fieldMappings = {\n    \"id\" : [\"id\"],\n    \"displayName\" : [\"name.displayName\"],\n    \"nickname\": [\"name.nicknames\"],\n    \"name\" : [ \"name.prefix\", \"name.firstName\", \"name.lastName\" ],\n    \"phoneNumbers\" : [\"phoneNumbers.number\",\"phoneNumbers.types\"],\n    \"emails\" : [\"emails.types\", \"emails.email\"],\n    \"addresses\" : [\"addresses.country\",\"addresses.region\",\"addresses.city\",\"addresses.streetAddress\",\"addresses.postalCode\",\"addresses.country\",\"addresses.types\"],\n    \"organizations\" : [\"organization.name\",\"organization.department\",\"organization.office\", \"organization.title\"],\n    \"birthday\" : [\"birthday\"],\n    \"note\" : [\"notes\"],\n    \"photos\" : [\"photoURI\"],\n    \"categories\" : [\"categories\"],\n    \"urls\" : [\"urls.url\", \"urls.type\"]\n};\n\n/*\n * Build an array of all of the valid W3C Contact fields. This is used to\n * substitute all the fields when [\"*\"] is specified.\n */\nvar allFields = [];\n\n(function initializeAllFieldsMapping() {\n\n    for ( var key in fieldMappings) {\n        allFields.push(key);\n    }\n    // as we want it to be executed once\n    function initializeAllFieldsMapping() {\n    }\n\n})();\n\n/**\n * Create a W3C ContactAddress object from a Tizen Address object\n *\n * @param {String}\n *            type the type of address (e.g. work, home)\n * @param {tizen.ContactAddress}\n *            tizenAddress a Tizen Address object\n * @return {ContactAddress} a contact address object or null if the specified\n *         address is null\n */\nvar createContactAddress = function(type, tizenAddress) {\n    if (!tizenAddress) {\n        return null;\n    }\n\n    var streetAddress = tizenAddress.streetAddress;\n    var locality = tizenAddress.city || \"\";\n    var region = tizenAddress.region || \"\";\n    var postalCode = tizenAddress.postalCode || \"\";\n    var country = tizenAddress.country || \"\";\n    var formatted = streetAddress + \", \" + locality + \", \" + region + \", \" + postalCode + \", \" + country;\n\n    var contact = new ContactAddress(null, type, formatted, streetAddress, locality, region, postalCode, country);\n\n    return contact;\n};\n\nmodule.exports = {\n    /**\n     * Builds Tizen filter expressions for contact search using the\n     * contact fields and search filter provided.\n     *\n     * @param {String[]}\n     *            fields Array of Contact fields to search\n     * @param {String}\n     *            filter Filter, or search string\n     * @param {Boolean}\n     *                 multiple, one contacts or more wanted as result\n     * @return filter expression or null if fields is empty or filter is null or\n     *         empty\n     */\n\n    buildFilterExpression: function(fields, filter) {\n        // ensure filter exists\n        if (!filter || filter === \"\") {\n            return null;\n        }\n\n        if ((fields.length === 1) && (fields[0] === \"*\")) {\n            // Cordova enhancement to allow fields value of [\"*\"] to indicate\n            // all supported fields.\n            fields = allFields;\n        }\n\n        // build a filter expression using all Contact fields provided\n        var compositeFilter = null,\n            attributeFilter = null,\n            filterExpression = null,\n            matchFlag = \"CONTAINS\",\n            matchValue = filter,\n            attributesArray = [];\n\n        if (fields && utils.isArray(fields)) {\n\n            for ( var field in fields) {\n\n                if (!fields[field]) {\n                    continue;\n                }\n\n                // retrieve Tizen contact fields that map Cordova fields specified\n                // (tizenFields is a string or an array of strings)\n                var tizenFields = fieldMappings[fields[field]];\n\n                if (!tizenFields) {\n                    // does something maps\n                    continue;\n                }\n\n                // construct the filter expression using the Tizen fields\n                for ( var index in tizenFields) {\n                    attributeFilter = new tizen.AttributeFilter(tizenFields[index], matchFlag, matchValue);\n                    if (attributeFilter !== null) {\n                        attributesArray.push(attributeFilter);\n                    }\n                }\n            }\n        }\n\n        // fullfil tizen find attribute as a single or a composite attribute\n        if (attributesArray.length == 1 ) {\n            filterExpression = attributeFilter[0];\n        } else if (attributesArray.length > 1) {\n            // combine the filters as a Union\n            filterExpression = new tizen.CompositeFilter(\"UNION\", attributesArray);\n        } else {\n            filterExpression = null;\n        }\n\n        return filterExpression;\n    },\n\n\n\n    /**\n     * Creates a Contact object from a Tizen Contact object, copying only\n     * the fields specified.\n     *\n     * This is intended as a privately used function but it is made globally\n     * available so that a Contact.save can convert a BlackBerry contact object\n     * into its W3C equivalent.\n     *\n     * @param {tizen.Contact}\n     *            tizenContact Tizen Contact object\n     * @param {String[]}\n     *            fields array of contact fields that should be copied\n     * @return {Contact} a contact object containing the specified fields or\n     *         null if the specified contact is null\n     */\n    createContact: function(tizenContact, fields) {\n\n        if (!tizenContact) {\n            return null;\n        }\n\n        // construct a new contact object\n        // always copy the contact id and displayName fields\n        var contact = new Contact(tizenContact.id, tizenContact.name.displayName);\n\n\n        // nothing to do\n        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {\n            return contact;\n        } else if (fields.length === 1 && fields[0] === \"*\") {\n            // Cordova enhancement to allow fields value of [\"*\"] to indicate\n            // all supported fields.\n            fields = allFields;\n        }\n\n        // add the fields specified\n        for ( var key in fields) {\n\n            var field = fields[key],\n                index = 0;\n\n            if (!field) {\n                continue;\n            }\n\n            // name\n            if (field.indexOf('name') === 0) {\n\n                var formattedName = (tizenContact.name.prefix || \"\");\n\n                if (tizenContact.name.firstName) {\n                    formattedName += ' ';\n                    formattedName += (tizenContact.name.firstName || \"\");\n                }\n\n                if (tizenContact.name.middleName) {\n                    formattedName += ' ';\n                    formattedName += (tizenContact.name.middleName || \"\");\n                }\n\n                if (tizenContact.name.lastName) {\n                    formattedName += ' ';\n                    formattedName += (tizenContact.name.lastName || \"\");\n                }\n\n                contact.name = new ContactName(\n                        formattedName,\n                        tizenContact.name.lastName,\n                        tizenContact.name.firstName,\n                        tizenContact.name.middleName,\n                        tizenContact.name.prefix,\n                        null);\n            }\n\n            // phoneNumbers\n            else if (field.indexOf('phoneNumbers') === 0) {\n\n                var phoneNumbers = [];\n\n                for (index = 0 ; index < tizenContact.phoneNumbers.length ; ++index) {\n\n                    phoneNumbers.push(\n                            new ContactField(\n                                    'PHONE',\n                                    tizenContact.phoneNumbers[index].number,\n                                    ((tizenContact.phoneNumbers[index].types[1]) &&  (tizenContact.emails[index].types[1] === \"PREF\") ) ? true : false));\n                }\n\n\n                contact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : null;\n            }\n\n            // emails\n            else if (field.indexOf('emails') === 0) {\n\n                var emails = [];\n\n                for (index = 0 ; index < tizenContact.emails.length ; ++index) {\n\n                    emails.push(\n                        new ContactField(\n                            'EMAILS',\n                            tizenContact.emails[index].email,\n                            ((tizenContact.emails[index].types[1]) &&  (tizenContact.emails[index].types[1] === \"PREF\") ) ? true : false));\n                }\n                contact.emails = emails.length > 0 ? emails : null;\n            }\n\n            // addresses\n            else if (field.indexOf('addresses') === 0) {\n\n                var addresses = [];\n                for (index = 0 ; index < tizenContact.addresses.length ; ++index) {\n\n                    addresses.push(\n                            new ContactAddress(\n                                    ((tizenContact.addresses[index].types[1] &&  tizenContact.addresses[index].types[1] === \"PREF\") ? true : false),\n                                    tizenContact.addresses[index].types[0] ? tizenContact.addresses[index].types[0] : \"HOME\",\n                                    null,\n                                    tizenContact.addresses[index].streetAddress,\n                                    tizenContact.addresses[index].city,\n                                    tizenContact.addresses[index].region,\n                                    tizenContact.addresses[index].postalCode,\n                                    tizenContact.addresses[index].country ));\n                }\n\n                contact.addresses = addresses.length > 0 ? addresses : null;\n            }\n\n            // birthday\n            else if (field.indexOf('birthday') === 0) {\n                if (utils.isDate(tizenContact.birthday)) {\n                    contact.birthday = tizenContact.birthday;\n                }\n            }\n\n            // note only one in Tizen Contact\n            else if (field.indexOf('note') === 0) {\n                if (tizenContact.note) {\n                    contact.note = tizenContact.note[0];\n                }\n            }\n\n            // organizations\n            else if (field.indexOf('organizations') === 0) {\n\n                var organizations = [];\n\n                // there's only one organization in a Tizen Address\n\n                if (tizenContact.organization) {\n                    organizations.push(\n                            new ContactOrganization(\n                                    true,\n                                    'WORK',\n                                    tizenContact.organization.name,\n                                    tizenContact.organization.department,\n                                    tizenContact.organization.jobTitle));\n                }\n\n                contact.organizations = organizations.length > 0 ? organizations : null;\n            }\n\n            // categories\n            else if (field.indexOf('categories') === 0) {\n\n                var categories = [];\n\n                if (tizenContact.categories) {\n\n                    for (index = 0 ; index < tizenContact.categories.length ; ++index) {\n                        categories.push(\n                                new ContactField(\n                                        'MAIN',\n                                        tizenContact.categories,\n                                        (index === 0) ));\n                    }\n\n                    contact.categories = categories.length > 0 ? categories : null;\n                }\n            }\n\n            // urls\n            else if (field.indexOf('urls') === 0) {\n                var urls = [];\n\n                if (tizenContact.urls) {\n                    for (index = 0 ; index <tizenContact.urls.length ; ++index) {\n                        urls.push(\n                                new ContactField(\n                                        tizenContact.urls[index].type,\n                                        tizenContact.urls[index].url,\n                                        (index === 0)));\n                    }\n                }\n\n                contact.urls = urls.length > 0 ? urls : null;\n            }\n\n            // photos\n            else if (field.indexOf('photos') === 0) {\n                var photos = [];\n\n                if (tizenContact.photoURI) {\n                    photos.push(new ContactField('URI', tizenContact.photoURI, true));\n                }\n\n                contact.photos = photos.length > 0 ? photos : null;\n            }\n        }\n\n        return contact;\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/ContactUtils.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/ContactUtils.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Device\", function(require, exports, module) {\n/*global tizen:false */\nvar channel = require('cordova/channel');\n\n// Tell cordova channel to wait on the CordovaInfoReady event\nchannel.waitForInitialization('onCordovaInfoReady');\n\nfunction Device() {\n    this.version = null;\n    this.uuid = null;\n    this.name = null;\n    this.cordova =  \"2.0.0\";\n    this.platform = \"Tizen\";\n\n    var me = this;\n\n    function onSuccessCallback(sysInfoProp) {\n        me.name = sysInfoProp.model;\n        me.uuid = sysInfoProp.imei;\n        me.version = sysInfoProp.version;\n        channel.onCordovaInfoReady.fire();\n    }\n\n    function onErrorCallback(error) {\n        console.log(\"error initializing cordova: \" + error);\n    }\n\n    channel.onCordovaReady.subscribeOnce(function() {\n        me.getDeviceInfo(onSuccessCallback, onErrorCallback);\n    });\n}\n\nDevice.prototype.getDeviceInfo = function(success, fail, args) {\n    tizen.systeminfo.getPropertyValue(\"Device\", success, fail);\n};\n\nmodule.exports = new Device();\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Device.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Device.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/File\", function(require, exports, module) {\n/*global WebKitBlobBuilder:false */\nvar FileError = require('cordova/plugin/FileError'),\n    DirectoryEntry = require('cordova/plugin/DirectoryEntry'),\n    FileEntry = require('cordova/plugin/FileEntry'),\n    File = require('cordova/plugin/File'),\n    FileSystem = require('cordova/plugin/FileSystem');\n\nvar nativeRequestFileSystem = window.webkitRequestFileSystem,\n    nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL,\n    NativeFileReader = window.FileReader;\n\nfunction getFileSystemName(nativeFs) {\n    return (nativeFs.name.indexOf(\"Persistent\") != -1) ? \"persistent\" : \"temporary\";\n}\n\nfunction makeEntry(entry) {\n    if (entry.isDirectory) {\n        return new DirectoryEntry(entry.name, decodeURI(entry.toURL()));\n    }\n    else {\n        return new FileEntry(entry.name, decodeURI(entry.toURL()));\n    }\n}\n\nmodule.exports = {\n    /* requestFileSystem */\n    requestFileSystem: function(successCallback, errorCallback, args) {\n        var type = args[0],\n            size = args[1];\n\n        nativeRequestFileSystem(type, size, function(nativeFs) {\n            successCallback(new FileSystem(getFileSystemName(nativeFs), makeEntry(nativeFs.root)));\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* resolveLocalFileSystemURI */\n    resolveLocalFileSystemURI: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            successCallback(makeEntry(entry));\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* DirectoryReader */\n    readEntries: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(dirEntry) {\n            var reader = dirEntry.createReader();\n            reader.readEntries(function(entries) {\n                var retVal = [];\n                for (var i = 0; i < entries.length; i++) {\n                    retVal.push(makeEntry(entries[i]));\n                }\n                successCallback(retVal);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* Entry */\n    getMetadata: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.getMetadata(function(metaData) {\n                successCallback(metaData.modificationTime);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    moveTo: function(successCallback, errorCallback, args) {\n        var srcUri = args[0],\n            parentUri = args[1],\n            name = args[2];\n\n        nativeResolveLocalFileSystemURI(srcUri, function(source) {\n            nativeResolveLocalFileSystemURI(parentUri, function(parent) {\n                source.moveTo(parent, name, function(entry) {\n                    successCallback(makeEntry(entry));\n                }, function(error) {\n                    errorCallback(error.code);\n                });\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    copyTo: function(successCallback, errorCallback, args) {\n        var srcUri = args[0],\n            parentUri = args[1],\n            name = args[2];\n\n        nativeResolveLocalFileSystemURI(srcUri, function(source) {\n            nativeResolveLocalFileSystemURI(parentUri, function(parent) {\n                source.copyTo(parent, name, function(entry) {\n                    successCallback(makeEntry(entry));\n                }, function(error) {\n                    errorCallback(error.code);\n                });\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    remove: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            if (entry.fullPath === \"/\") {\n                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);\n            } else {\n                entry.remove(successCallback, function(error) {\n                    errorCallback(error.code);\n                });\n            }\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    getParent: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.getParent(function(entry) {\n                successCallback(makeEntry(entry));\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* FileEntry */\n    getFileMetadata: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.file(function(file) {\n                var retVal = new File(file.name, decodeURI(entry.toURL()), file.type, file.lastModifiedDate, file.size);\n                successCallback(retVal);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* DirectoryEntry */\n    getDirectory: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            path = args[1],\n            options = args[2];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.getDirectory(path, options, function(entry) {\n                successCallback(makeEntry(entry));\n            }, function(error) {\n                if (error.code === FileError.INVALID_MODIFICATION_ERR) {\n                    if (options.create) {\n                        errorCallback(FileError.PATH_EXISTS_ERR);\n                    } else {\n                        errorCallback(FileError.ENCODING_ERR);\n                    }\n                } else {\n                    errorCallback(error.code);\n                }\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    removeRecursively: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            if (entry.fullPath === \"/\") {\n                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);\n            } else {\n                entry.removeRecursively(successCallback, function(error) {\n                    errorCallback(error.code);\n                });\n            }\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    getFile: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            path = args[1],\n            options = args[2];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.getFile(path, options, function(entry) {\n                successCallback(makeEntry(entry));\n            }, function(error) {\n                if (error.code === FileError.INVALID_MODIFICATION_ERR) {\n                    if (options.create) {\n                        errorCallback(FileError.PATH_EXISTS_ERR);\n                    } else {\n                        errorCallback(FileError.ENCODING_ERR);\n                    }\n                } else {\n                    errorCallback(error.code);\n                }\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* FileReader */\n    readAsText: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            encoding = args[1];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            var onLoadEnd = function(evt) {\n                    if (!evt.target.error) {\n                        successCallback(evt.target.result);\n                    }\n            },\n                onError = function(evt) {\n                    errorCallback(evt.target.error.code);\n            };\n\n            var reader = new NativeFileReader();\n\n            reader.onloadend = onLoadEnd;\n            reader.onerror = onError;\n            entry.file(function(file) {\n                reader.readAsText(file, encoding);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    readAsDataURL: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            var onLoadEnd = function(evt) {\n                    if (!evt.target.error) {\n                        successCallback(evt.target.result);\n                    }\n            },\n                onError = function(evt) {\n                    errorCallback(evt.target.error.code);\n            };\n\n            var reader = new NativeFileReader();\n\n            reader.onloadend = onLoadEnd;\n            reader.onerror = onError;\n            entry.file(function(file) {\n                reader.readAsDataURL(file);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* FileWriter */\n    write: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            text = args[1],\n            position = args[2];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            var onWriteEnd = function(evt) {\n                    if(!evt.target.error) {\n                        successCallback(evt.target.position - position);\n                    } else {\n                        errorCallback(evt.target.error.code);\n                    }\n            },\n                onError = function(evt) {\n                    errorCallback(evt.target.error.code);\n            };\n\n            entry.createWriter(function(writer) {\n                var blob = new WebKitBlobBuilder();\n                blob.append(text);\n\n                writer.onwriteend = onWriteEnd;\n                writer.onerror = onError;\n\n                writer.seek(position);\n                writer.write(blob.getBlob('text/plain'));\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    truncate: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            size = args[1];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            var onWriteEnd = function(evt) {\n                    if(!evt.target.error) {\n                        successCallback(evt.target.length);\n                    } else {\n                        errorCallback(evt.target.error.code);\n                    }\n            },\n                onError = function(evt) {\n                    errorCallback(evt.target.error.code);\n            };\n\n            entry.createWriter(function(writer) {\n                writer.onwriteend = onWriteEnd;\n                writer.onerror = onError;\n\n                writer.truncate(size);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/File.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/File.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/FileTransfer\", function(require, exports, module) {\n/*global WebKitBlobBuilder:false */\nvar FileEntry = require('cordova/plugin/FileEntry'),\n    FileTransferError = require('cordova/plugin/FileTransferError'),\n    FileUploadResult = require('cordova/plugin/FileUploadResult');\n\nvar nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL;\n\nfunction getParentPath(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(0, pos + 1);\n}\n\nfunction getFileName(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(pos + 1);\n}\n\nmodule.exports = {\n    upload: function(successCallback, errorCallback, args) {\n        var filePath = args[0],\n            server = args[1],\n            fileKey = args[2],\n            fileName = args[3],\n            mimeType = args[4],\n            params = args[5],\n            /*trustAllHosts = args[6],*/\n            chunkedMode = args[7];\n\n        nativeResolveLocalFileSystemURI(filePath, function(entry) {\n            entry.file(function(file) {\n                function uploadFile(blobFile) {\n                    var fd = new FormData();\n\n                    fd.append(fileKey, blobFile, fileName);\n                    for (var prop in params) {\n                        if(params.hasOwnProperty(prop)) {\n                            fd.append(prop, params[prop]);\n                        }\n                    }\n\n                    var xhr = new XMLHttpRequest();\n                    xhr.open(\"POST\", server);\n                    xhr.onload = function(evt) {\n                        if (xhr.status == 200) {\n                            var result = new FileUploadResult();\n                            result.bytesSent = file.size;\n                            result.responseCode = xhr.status;\n                            result.response = xhr.response;\n                            successCallback(result);\n                        } else if (xhr.status == 404) {\n                            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));\n                        } else {\n                            errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));\n                        }\n                    };\n                    xhr.ontimeout = function(evt) {\n                        errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));\n                    };\n\n                    xhr.send(fd);\n                }\n\n                var bytesPerChunk;\n                if (chunkedMode === true) {\n                    bytesPerChunk = 1024 * 1024; // 1MB chunk sizes.\n                } else {\n                    bytesPerChunk = file.size;\n                }\n                var start = 0;\n                var end = bytesPerChunk;\n                while (start < file.size) {\n                    var chunk = file.webkitSlice(start, end, mimeType);\n                    uploadFile(chunk);\n                    start = end;\n                    end = start + bytesPerChunk;\n                }\n            },\n            function(error) {\n                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n            }\n            );\n        },\n        function(error) {\n            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n        }\n        );\n    },\n\n    download: function(successCallback, errorCallback, args) {\n        var url = args[0],\n            filePath = args[1];\n\n        var xhr = new XMLHttpRequest();\n\n        function writeFile(fileEntry) {\n            fileEntry.createWriter(function(writer) {\n                writer.onwriteend = function(evt) {\n                    if (!evt.target.error) {\n                        successCallback(new FileEntry(fileEntry.name, fileEntry.toURL()));\n                    } else {\n                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n                    }\n                };\n\n                writer.onerror = function(evt) {\n                    errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n                };\n\n                var builder = new WebKitBlobBuilder();\n                builder.append(xhr.response);\n                var blob = builder.getBlob();\n                writer.write(blob);\n            },\n            function(error) {\n                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n            });\n        }\n\n        xhr.onreadystatechange = function () {\n            if (xhr.readyState == xhr.DONE) {\n                if (xhr.status == 200 && xhr.response) {\n                    nativeResolveLocalFileSystemURI(getParentPath(filePath), function(dir) {\n                        dir.getFile(getFileName(filePath), {create: true}, writeFile, function(error) {\n                            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n                        });\n                    }, function(error) {\n                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n                    });\n                } else if (xhr.status == 404) {\n                    errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));\n                } else {\n                    errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));\n                }\n            }\n        };\n\n        xhr.open(\"GET\", url, true);\n        xhr.responseType = \"arraybuffer\";\n        xhr.send();\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/FileTransfer.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/FileTransfer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Media\", function(require, exports, module) {\n/*global Media:false, webkitURL:false */\nvar MediaError = require('cordova/plugin/MediaError'),\n    audioObjects = {};\n\nmodule.exports = {\n    create: function (successCallback, errorCallback, args) {\n        var id = args[0], src = args[1];\n        console.log(\"media::create() - id =\" + id + \", src =\" + src);\n        audioObjects[id] = new Audio(src);\n        audioObjects[id].onStalledCB = function () {\n            console.log(\"media::onStalled()\");\n             audioObjects[id].timer = window.setTimeout(function () {\n                    audioObjects[id].pause();\n                    if (audioObjects[id].currentTime !== 0)\n                        audioObjects[id].currentTime = 0;\n                    console.log(\"media::onStalled() - MEDIA_ERROR -> \" + MediaError.MEDIA_ERR_ABORTED);\n                    var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, \"Stalled\");\n                    Media.onStatus(id, Media.MEDIA_ERROR, err);\n                }, 2000);\n        };\n        audioObjects[id].onEndedCB = function () {\n            console.log(\"media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED\");\n            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);\n        };\n        audioObjects[id].onErrorCB = function () {\n            console.log(\"media::onErrorCB() - MEDIA_ERROR -> \" + event.srcElement.error);\n            Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error);\n        };\n        audioObjects[id].onPlayCB = function () {\n            console.log(\"media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING\");\n            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);\n        };\n        audioObjects[id].onPlayingCB = function () {\n            console.log(\"media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING\");\n            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);\n        };\n        audioObjects[id].onDurationChangeCB = function () {\n            console.log(\"media::onDurationChangeCB() - MEDIA_DURATION -> \" +  audioObjects[id].duration);\n            Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration);\n        };\n        audioObjects[id].onTimeUpdateCB = function () {\n            console.log(\"media::onTimeUpdateCB() - MEDIA_POSITION -> \" +  audioObjects[id].currentTime);\n            Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime);\n        };\n        audioObjects[id].onCanPlayCB = function () {\n            console.log(\"media::onCanPlayCB()\");\n            window.clearTimeout(audioObjects[id].timer);\n            audioObjects[id].play();\n        };\n      },\n    startPlayingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0], src = args[1], options = args[2];\n        console.log(\"media::startPlayingAudio() - id =\" + id + \", src =\" + src + \", options =\" + options);\n        audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB);\n        audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB);\n        audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);\n        audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB);\n        audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB);\n        audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB);\n        audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB);\n        audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB);\n        audioObjects[id].play();\n    },\n    stopPlayingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        window.clearTimeout(audioObjects[id].timer);\n        audioObjects[id].pause();\n        if (audioObjects[id].currentTime !== 0)\n            audioObjects[id].currentTime = 0;\n        console.log(\"media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED\");\n        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);\n        audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB);\n        audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB);\n        audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);\n        audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB);\n        audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB);\n        audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB);\n        audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB);\n        audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB);\n    },\n    seekToAudio: function (successCallback, errorCallback, args) {\n        var id = args[0], milliseconds = args[1];\n        console.log(\"media::seekToAudio()\");\n         audioObjects[id].currentTime = milliseconds;\n        successCallback( audioObjects[id].currentTime);\n    },\n    pausePlayingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        console.log(\"media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED\");\n        audioObjects[id].pause();\n        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);\n    },\n    getCurrentPositionAudio: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        console.log(\"media::getCurrentPositionAudio()\");\n        successCallback(audioObjects[id].currentTime);\n    },\n    release: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        window.clearTimeout(audioObjects[id].timer);\n        console.log(\"media::release()\");\n    },\n    setVolume: function (successCallback, errorCallback, args) {\n        var id = args[0], volume = args[1];\n        console.log(\"media::setVolume()\");\n        audioObjects[id].volume = volume;\n    },\n    startRecordingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0], src = args[1];\n        console.log(\"media::startRecordingAudio() - id =\" + id + \", src =\" + src);\n\n        function gotStreamCB(stream) {\n            audioObjects[id].src = webkitURL.createObjectURL(stream);\n            console.log(\"media::startRecordingAudio() - stream CB\");\n        }\n\n        function gotStreamFailedCB(error) {\n            console.log(\"media::startRecordingAudio() - error CB:\" + error.toString());\n        }\n\n        if (navigator.webkitGetUserMedia) {\n            audioObjects[id] = new Audio();\n            navigator.webkitGetUserMedia('audio', gotStreamCB, gotStreamFailedCB);\n        } else {\n            console.log(\"webkitGetUserMedia not supported\");\n        }\n        successCallback();\n    },\n    stopRecordingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        console.log(\"media::stopRecordingAudio() - id =\" + id);\n        audioObjects[id].pause();\n        successCallback();\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Media.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Media.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/MediaError\", function(require, exports, module) {\n\n// The MediaError object already exists on Tizen. This prevents the Cordova\n// version from being defined. This object is used to merge in differences\n// between Tizen and Cordova MediaError objects.\nmodule.exports = {\n        MEDIA_ERR_NONE_ACTIVE : 0,\n        MEDIA_ERR_NONE_SUPPORTED : 4\n};\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/MediaError.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/MediaError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/NetworkStatus\", function(require, exports, module) {\n/*global tizen:false */\nvar Connection = require('cordova/plugin/Connection');\n\nmodule.exports = {\n    getConnectionInfo: function (successCallback, errorCallback) {\n        var cncType = Connection.NONE;\n        var infoCount = 0;\n\n        function infoCB() {\n            infoCount++;\n            if (infoCount > 1)\n               successCallback(cncType);\n        }\n\n        function errorCB(error) {\n           console.log(\"Error: \" + error.code + \",\" + error.name + \",\" + error.message);\n           infoCB();\n        }\n\n        function wifiSuccessCB(wifi) {\n            if ((wifi.status === \"ON\")  && (wifi.ipAddress.length !== 0))\n                cncType = Connection.WIFI;\n            infoCB();\n        }\n\n        function cellularSuccessCB(cell) {\n            if ((cncType === Connection.NONE) && (cell.status === \"ON\") && (cell.ipAddress.length !== 0))\n                cncType = Connection.CELL_2G;\n            infoCB();\n        }\n\n        if (tizen.systeminfo.isSupported('WifiNetwork')) {\n            tizen.systeminfo.getPropertyValue('WifiNetwork', wifiSuccessCB, errorCB);\n        }\n\n        if (tizen.systeminfo.isSupported('CellularNetwork')) {\n            tizen.systeminfo.getPropertyValue('CellularNetwork', cellularSuccessCB, errorCB);\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/NetworkStatus.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/NetworkStatus.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Notification\", function(require, exports, module) {\nvar SoundBeat = require('cordova/plugin/tizen/SoundBeat');\n\n/* TODO: get resource path from app environment? */\nvar soundBeat = new SoundBeat([\"./sounds/beep.wav\"]);\n\nmodule.exports = {\n\n    alert: function(message, alertCallback, title, buttonName) {\n        return this.confirm(message, alertCallback, title, buttonName);\n    },\n\n    confirm: function(message, confirmCallback, title, buttonLabels) {\n        var index            =    null,\n            overlayElement    =    null,\n            popup            =    null,\n            element         =    null,\n            titleString        =     null,\n            messageString    =    null,\n            buttonString    =    null,\n            buttonsArray    =    null;\n\n\n        console.log (\"message\" , message);\n        console.log (\"confirmCallback\" , confirmCallback);\n        console.log (\"title\" , title);\n        console.log (\"buttonLabels\" , buttonLabels);\n\n        titleString = '<div class=\"popup-title\"><p>' + title + '</p></div>';\n        messageString = '<div class=\"popup-text\"><p>' + message + '</p></div>';\n        buttonString = '<div class=\"popup-button-bg\"><ul>';\n\n        switch(typeof(buttonLabels))\n        {\n        case \"string\":\n            buttonsArray = buttonLabels.split(\",\");\n\n            if (buttonsArray === null) {\n                buttonsArray = buttonLabels;\n            }\n\n            for (index in buttonsArray) {\n                buttonString += '<li><input id=\"popup-button-' + buttonsArray[index]+\n                                '\" type=\"button\" value=\"' + buttonsArray[index] + '\" /></li>';\n                console.log (\"index: \", index,\"\");\n                console.log (\"buttonsArray[index]: \", buttonsArray[index]);\n                console.log (\"buttonString: \", buttonString);\n            }\n            break;\n\n        case \"array\":\n            if (buttonsArray === null) {\n                buttonsArray = buttonLabels;\n            }\n\n            for (index in buttonsArray) {\n                buttonString += '<li><input id=\"popup-button-' + buttonsArray[index]+\n                                '\" type=\"button\" value=\"' + buttonsArray[index] + '\" /></li>';\n                console.log (\"index: \", index,\"\");\n                console.log (\"buttonsArray[index]: \", buttonsArray[index]);\n                console.log (\"buttonString: \", buttonString);\n            }\n            break;\n        default:\n            console.log (\"cordova/plugin/tizen/Notification, default, buttonLabels: \", buttonLabels);\n            break;\n        }\n\n        buttonString += '</ul></div>';\n\n        overlayElement = document.createElement(\"div\");\n        overlayElement.className = 'ui-popupwindow-screen';\n\n        overlayElement.style.zIndex = 1001;\n        overlayElement.style.width = \"100%\";\n        overlayElement.style.height = \"100%\";\n        overlayElement.style.top = 0;\n        overlayElement.style.left = 0;\n        overlayElement.style.margin = 0;\n        overlayElement.style.padding = 0;\n        overlayElement.style.position = \"absolute\";\n\n        popup = document.createElement(\"div\");\n        popup.className = \"ui-popupwindow\";\n        popup.style.position = \"fixed\";\n        popup.style.zIndex = 1002;\n        popup.innerHTML = titleString + messageString + buttonString;\n\n        document.body.appendChild(overlayElement);\n        document.body.appendChild(popup);\n\n        function createListener(button) {\n            return function() {\n                document.body.removeChild(overlayElement);\n                document.body.removeChild(popup);\n                confirmCallback(button.value);\n            };\n        }\n\n       for (index in buttonsArray) {\n           console.log (\"index: \", index);\n\n           element = document.getElementById(\"popup-button-\" + buttonsArray[index]);\n           element.addEventListener(\"click\", createListener(element), false);\n       }\n    },\n\n    vibrate: function(milliseconds) {\n        console.log (\"milliseconds\" , milliseconds);\n\n        if (navigator.vibrate) {\n            navigator.vibrate(milliseconds);\n        }\n        else {\n            console.log (\"cordova/plugin/tizen/Notification, vibrate API does not exists\");\n        }\n    },\n\n    beep: function(count) {\n        console.log (\"count\" , count);\n        soundBeat.play(count);\n    }\n};\n\n\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Notification.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Notification.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/SoundBeat\", function(require, exports, module) {\n/*global webkitAudioContext:false */\n/*\n *  SoundBeat\n * used by Notification Manager beep method\n *\n * This class provides sounds play\n *\n * uses W3C  Web Audio API\n * uses BufferLoader object\n *\n * NOTE: the W3C Web Audio doc tells we do not need to recreate the audio\n *       context to play a sound but only the audiosourcenode (createBufferSource)\n *       in the webkit implementation we have to.\n *\n */\n\nvar BufferLoader = require('cordova/plugin/tizen/BufferLoader');\n\nfunction SoundBeat(urlList) {\n    this.context = null;\n    this.urlList = urlList || null;\n    this.buffers = null;\n}\n\n/*\n * This method play a loaded sounds on the Device\n * @param {Number} times Number of times to play loaded sounds.\n *\n */\nSoundBeat.prototype.play = function(times) {\n\n    var i = 0, sources = [], that = this;\n\n    function finishedLoading (bufferList) {\n        that.buffers = bufferList;\n\n        for (i = 0; i < that.buffers.length ; i +=1) {\n            if (that.context) {\n                sources[i] = that.context.createBufferSource();\n\n                sources[i].buffer = that.buffers[i];\n                sources[i].connect (that.context.destination);\n\n                sources[i].loop = true;\n                sources[i].noteOn (0);\n                sources[i].noteOff(sources[i].buffer.duration * times);\n            }\n        }\n    }\n\n    if (webkitAudioContext !== null) {\n        this.context = new webkitAudioContext();\n    }\n    else {\n        console.log (\"SoundBeat.prototype.play, w3c web audio api not supported\");\n        this.context = null;\n    }\n\n    if (this.context === null) {\n        console.log (\"SoundBeat.prototype.play, cannot create audio context object\");\n        return;\n    }\n\n    this.bufferLoader = new BufferLoader (this.context, this.urlList, finishedLoading);\n    if (this.bufferLoader === null) {\n        console.log (\"SoundBeat.prototype.play, cannot create buffer loader object\");\n        return;\n    }\n\n    this.bufferLoader.load();\n};\n\nmodule.exports = SoundBeat;\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/SoundBeat.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/SoundBeat.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/contacts\", function(require, exports, module) {\n/*global tizen:false */\nvar ContactError = require('cordova/plugin/ContactError'),\n    utils = require('cordova/utils'),\n    ContactUtils = require('cordova/plugin/tizen/ContactUtils');\n\nmodule.exports = {\n    /**\n     * Returns an array of Contacts matching the search criteria.\n     *\n     * @return array of Contacts matching search criteria\n     */\n    find : function(fields, successCB, failCB, options) {\n\n        // Success callback is required. Throw exception if not specified.\n        if (typeof successCB !== 'function') {\n            throw new TypeError(\"You must specify a success callback for the find command.\");\n        }\n\n        // Search qualifier is required and cannot be empty.\n        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {\n            if (typeof failCB === 'function') {\n                failCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));\n            }\n            return;\n        }\n\n        // options are optional\n        var filter =\"\",\n            multiple = false,\n            contacts = [],\n            tizenFilter = null;\n\n        if (options) {\n            filter = options.filter || \"\";\n            multiple =  options.multiple || false;\n        }\n\n        if (filter){\n            tizenFilter = ContactUtils.buildFilterExpression(fields, filter);\n        }\n\n        tizen.contact.getDefaultAddressBook().find(\n            function(tizenContacts) {\n                if (multiple) {\n                    for (var index in tizenContacts) {\n                        contacts.push(ContactUtils.createContact(tizenContacts[index], fields));\n                    }\n                }\n                else {\n                    contacts.push(ContactUtils.createContact(tizenContacts[0], fields));\n                }\n\n                // return results\n                successCB(contacts);\n            },\n            function(error) {\n                if (typeof failCB === 'function') {\n                    failCB(ContactError.UNKNOWN_ERROR);\n                }\n            },\n            tizenFilter,\n            null);\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/contacts.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/contacts.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/manager\", function(require, exports, module) {\nvar cordova = require('cordova');\n\nmodule.exports = {\n    exec: function (successCallback, errorCallback, clazz, action, args) {\n        var plugin = require('cordova/plugin/tizen/' + clazz);\n\n        if (plugin && typeof plugin[action] === 'function') {\n            var result = plugin[action](successCallback, errorCallback, args);\n            return result || {status: cordova.callbackStatus.NO_RESULT};\n        }\n\n        return {\"status\" : cordova.callbackStatus.CLASS_NOT_FOUND_EXCEPTION, \"message\" : \"Function \" + clazz + \"::\" + action + \" cannot be found\"};\n    },\n    resume: function () {},\n    pause: function () {},\n    destroy: function () {}\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/manager.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/manager.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/utils\", function(require, exports, module) {\nvar utils = exports;\n\n/**\n * Returns an indication of whether the argument is an array or not\n */\nutils.isArray = function(a) {\n    return Object.prototype.toString.call(a) == '[object Array]';\n};\n\n/**\n * Returns an indication of whether the argument is a Date or not\n */\nutils.isDate = function(d) {\n    return Object.prototype.toString.call(d) == '[object Date]';\n};\n\n/**\n * Does a deep clone of the object.\n */\nutils.clone = function(obj) {\n    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {\n        return obj;\n    }\n\n    var retVal, i;\n\n    if(utils.isArray(obj)){\n        retVal = [];\n        for(i = 0; i < obj.length; ++i){\n            retVal.push(utils.clone(obj[i]));\n        }\n        return retVal;\n    }\n\n    retVal = {};\n    for(i in obj){\n        if(!(i in retVal) || retVal[i] != obj[i]) {\n            retVal[i] = utils.clone(obj[i]);\n        }\n    }\n    return retVal;\n};\n\n/**\n * Returns a wrappered version of the function\n */\nutils.close = function(context, func, params) {\n    if (typeof params == 'undefined') {\n        return function() {\n            return func.apply(context, arguments);\n        };\n    } else {\n        return function() {\n            return func.apply(context, params);\n        };\n    }\n};\n\n/**\n * Create a UUID\n */\nutils.createUUID = function() {\n    return UUIDcreatePart(4) + '-' +\n        UUIDcreatePart(2) + '-' +\n        UUIDcreatePart(2) + '-' +\n        UUIDcreatePart(2) + '-' +\n        UUIDcreatePart(6);\n};\n\n/**\n * Extends a child object from a parent object using classical inheritance\n * pattern.\n */\nutils.extend = (function() {\n    // proxy used to establish prototype chain\n    var F = function() {};\n    // extend Child from Parent\n    return function(Child, Parent) {\n        F.prototype = Parent.prototype;\n        Child.prototype = new F();\n        Child.__super__ = Parent.prototype;\n        Child.prototype.constructor = Child;\n    };\n}());\n\n/**\n * Alerts a message in any available way: alert or console.log.\n */\nutils.alert = function(msg) {\n    if (alert) {\n        alert(msg);\n    } else if (console && console.log) {\n        console.log(msg);\n    }\n};\n\n/**\n * Formats a string and arguments following it ala sprintf()\n *\n * see utils.vformat() for more information\n */\nutils.format = function(formatString /* ,... */) {\n    var args = [].slice.call(arguments, 1);\n    return utils.vformat(formatString, args);\n};\n\n/**\n * Formats a string and arguments following it ala vsprintf()\n *\n * format chars:\n *   %j - format arg as JSON\n *   %o - format arg as JSON\n *   %c - format arg as ''\n *   %% - replace with '%'\n * any other char following % will format it's\n * arg via toString().\n *\n * for rationale, see FireBug's Console API:\n *    http://getfirebug.com/wiki/index.php/Console_API\n */\nutils.vformat = function(formatString, args) {\n    if (formatString === null || formatString === undefined) return \"\";\n    if (arguments.length == 1) return formatString.toString();\n    if (typeof formatString != \"string\") return formatString.toString();\n\n    var pattern = /(.*?)%(.)(.*)/;\n    var rest    = formatString;\n    var result  = [];\n\n    while (args.length) {\n        var arg   = args.shift();\n        var match = pattern.exec(rest);\n\n        if (!match) break;\n\n        rest = match[3];\n\n        result.push(match[1]);\n\n        if (match[2] == '%') {\n            result.push('%');\n            args.unshift(arg);\n            continue;\n        }\n\n        result.push(formatted(arg, match[2]));\n    }\n\n    result.push(rest);\n\n    return result.join('');\n};\n\n//------------------------------------------------------------------------------\nfunction UUIDcreatePart(length) {\n    var uuidpart = \"\";\n    for (var i=0; i<length; i++) {\n        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);\n        if (uuidchar.length == 1) {\n            uuidchar = \"0\" + uuidchar;\n        }\n        uuidpart += uuidchar;\n    }\n    return uuidpart;\n}\n\n//------------------------------------------------------------------------------\nfunction formatted(object, formatChar) {\n\n    try {\n        switch(formatChar) {\n            case 'j':\n            case 'o': return JSON.stringify(object);\n            case 'c': return '';\n        }\n    }\n    catch (e) {\n        return \"error JSON.stringify()ing argument: \" + e;\n    }\n\n    if ((object === null) || (object === undefined)) {\n        return Object.prototype.toString.call(object);\n    }\n\n    return object.toString();\n}\n\n});\n\n//@ sourceURL=lib/common/utils.js")} catch(e) {console.log("exception: in lib/common/utils.js: " + e);console.log(e.stack);}
+
+window.cordova = require('cordova');
+
+try {eval("(function (context) {\n    var channel = require(\"cordova/channel\"),\n        _self = {\n            boot: function () {\n                /**\n                 * Create all cordova objects once page has fully loaded and native side is ready.\n                 */\n                channel.join(function() {\n                    var builder = require('cordova/builder'),\n                        base = require('cordova/common'),\n                        platform = require('cordova/platform');\n\n                    // Drop the common globals into the window object, but be nice and don't overwrite anything.\n                    builder.build(base.objects).intoButDontClobber(window);\n\n                    // Drop the platform-specific globals into the window object\n                    // and clobber any existing object.\n                    builder.build(platform.objects).intoAndClobber(window);\n\n                    // Merge the platform-specific overrides/enhancements into\n                    // the window object.\n                    if (typeof platform.merges !== 'undefined') {\n                        builder.build(platform.merges).intoAndMerge(window);\n                    }\n\n                    // Call the platform-specific initialization\n                    platform.initialize();\n\n                    // Fire event to notify that all objects are created\n                    channel.onCordovaReady.fire();\n\n                    // Fire onDeviceReady event once all constructors have run and\n                    // cordova info has been received from native side.\n                    channel.join(function() {\n                        require('cordova').fireDocumentEvent('deviceready');\n                    }, channel.deviceReadyChannelsArray);\n\n                }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);\n            }\n        };\n\n    // boot up once native side is ready\n    channel.onNativeReady.subscribeOnce(_self.boot);\n\n    // _nativeReady is global variable that the native side can set\n    // to signify that the native code is ready. It is a global since\n    // it may be called before any cordova JS is ready.\n    if (window._nativeReady) {\n        channel.onNativeReady.fire();\n    }\n\n}(window));\n\n//@ sourceURL=lib/scripts/bootstrap.js")} catch(e) {console.log("exception: in lib/scripts/bootstrap.js: " + e);console.log(e.stack);}
+try {eval("require('cordova/channel').onNativeReady.fire();\n\n//@ sourceURL=lib/scripts/bootstrap-tizen.js")} catch(e) {console.log("exception: in lib/scripts/bootstrap-tizen.js: " + e);console.log(e.stack);}
+
+})();
\ No newline at end of file
diff --git a/framework/cordova.tizen.js b/framework/cordova.tizen.js
new file mode 100644
index 0000000..3be5eb3
--- /dev/null
+++ b/framework/cordova.tizen.js
@@ -0,0 +1,7066 @@
+// commit 7dd17b00544742d14ecdeff2148a66480680f12b
+
+// File generated at :: Fri Jul 27 2012 11:40:36 GMT+0200 (CEST)
+
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+;(function() {
+
+// file: lib/scripts/require.js
+var require,
+    define;
+
+(function () {
+    var modules = {};
+
+    function build(module) {
+        var factory = module.factory;
+        module.exports = {};
+        delete module.factory;
+        factory(require, module.exports, module);
+        return module.exports;
+    }
+
+    require = function (id) {
+        if (!modules[id]) {
+            throw "module " + id + " not found";
+        }
+        return modules[id].factory ? build(modules[id]) : modules[id].exports;
+    };
+
+    define = function (id, factory) {
+        if (modules[id]) {
+            throw "module " + id + " already defined";
+        }
+
+        modules[id] = {
+            id: id,
+            factory: factory
+        };
+    };
+
+    define.remove = function (id) {
+        delete modules[id];
+    };
+
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+    module.exports.require = require;
+    module.exports.define = define;
+}
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+var channel = require('cordova/channel');
+
+/**
+ * Listen for DOMContentLoaded and notify our channel subscribers.
+ */
+document.addEventListener('DOMContentLoaded', function() {
+    channel.onDOMContentLoaded.fire();
+}, false);
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+    channel.onDOMContentLoaded.fire();
+}
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+    windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof documentEventHandlers[e] != 'undefined') {
+        if (evt === 'deviceready') {
+            documentEventHandlers[e].subscribeOnce(handler);
+        } else {
+            documentEventHandlers[e].subscribe(handler);
+        }
+    } else {
+        m_document_addEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof windowEventHandlers[e] != 'undefined') {
+        windowEventHandlers[e].subscribe(handler);
+    } else {
+        m_window_addEventListener.call(window, evt, handler, capture);
+    }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof documentEventHandlers[e] != "undefined") {
+        documentEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_document_removeEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof windowEventHandlers[e] != "undefined") {
+        windowEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_window_removeEventListener.call(window, evt, handler, capture);
+    }
+};
+
+function createEvent(type, data) {
+    var event = document.createEvent('Events');
+    event.initEvent(type, false, false);
+    if (data) {
+        for (var i in data) {
+            if (data.hasOwnProperty(i)) {
+                event[i] = data[i];
+            }
+        }
+    }
+    return event;
+}
+
+if(typeof window.console === "undefined") {
+    window.console = {
+        log:function(){}
+    };
+}
+
+var cordova = {
+    define:define,
+    require:require,
+    /**
+     * Methods to add/remove your own addEventListener hijacking on document + window.
+     */
+    addWindowEventHandler:function(event, opts) {
+        return (windowEventHandlers[event] = channel.create(event, opts));
+    },
+    addDocumentEventHandler:function(event, opts) {
+        return (documentEventHandlers[event] = channel.create(event, opts));
+    },
+    removeWindowEventHandler:function(event) {
+        delete windowEventHandlers[event];
+    },
+    removeDocumentEventHandler:function(event) {
+        delete documentEventHandlers[event];
+    },
+    /**
+     * Retreive original event handlers that were replaced by Cordova
+     *
+     * @return object
+     */
+    getOriginalHandlers: function() {
+        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+    },
+    /**
+     * Method to fire event from native code
+     */
+    fireDocumentEvent: function(type, data) {
+        var evt = createEvent(type, data);
+        if (typeof documentEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                documentEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            document.dispatchEvent(evt);
+        }
+    },
+    fireWindowEvent: function(type, data) {
+        var evt = createEvent(type,data);
+        if (typeof windowEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                windowEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            window.dispatchEvent(evt);
+        }
+    },
+    // TODO: this is Android only; think about how to do this better
+    shuttingDown:false,
+    UsePolling:false,
+    // END TODO
+
+    // TODO: iOS only
+    // This queue holds the currently executing command and all pending
+    // commands executed with cordova.exec().
+    commandQueue:[],
+    // Indicates if we're currently in the middle of flushing the command
+    // queue on the native side.
+    commandQueueFlushing:false,
+    // END TODO
+    /**
+     * Plugin callback mechanism.
+     */
+    callbackId: 0,
+    callbacks:  {},
+    callbackStatus: {
+        NO_RESULT: 0,
+        OK: 1,
+        CLASS_NOT_FOUND_EXCEPTION: 2,
+        ILLEGAL_ACCESS_EXCEPTION: 3,
+        INSTANTIATION_EXCEPTION: 4,
+        MALFORMED_URL_EXCEPTION: 5,
+        IO_EXCEPTION: 6,
+        INVALID_ACTION: 7,
+        JSON_EXCEPTION: 8,
+        ERROR: 9
+    },
+
+    /**
+     * Called by native code when returning successful result from an action.
+     *
+     * @param callbackId
+     * @param args
+     */
+    callbackSuccess: function(callbackId, args) {
+        if (cordova.callbacks[callbackId]) {
+
+            // If result is to be sent to callback
+            if (args.status == cordova.callbackStatus.OK) {
+                try {
+                    if (cordova.callbacks[callbackId].success) {
+                        cordova.callbacks[callbackId].success(args.message);
+                    }
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+callbackId+" = "+e);
+                }
+            }
+
+            // Clear callback if not expecting any more results
+            if (!args.keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+
+    /**
+     * Called by native code when returning error result from an action.
+     *
+     * @param callbackId
+     * @param args
+     */
+    callbackError: function(callbackId, args) {
+        if (cordova.callbacks[callbackId]) {
+            try {
+                if (cordova.callbacks[callbackId].fail) {
+                    cordova.callbacks[callbackId].fail(args.message);
+                }
+            }
+            catch (e) {
+                console.log("Error in error callback: "+callbackId+" = "+e);
+            }
+
+            // Clear callback if not expecting any more results
+            if (!args.keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+    addConstructor: function(func) {
+        channel.onCordovaReady.subscribeOnce(function() {
+            try {
+                func();
+            } catch(e) {
+                console.log("Failed to run constructor: " + e);
+            }
+        });
+    }
+};
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addDocumentEventHandler('deviceready');
+
+module.exports = cordova;
+
+});
+
+// file: lib/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+    for (var prop in objects) {
+        if (objects.hasOwnProperty(prop)) {
+            func.apply(context, [objects[prop], prop]);
+        }
+    }
+}
+
+function include(parent, objects, clobber, merge) {
+    each(objects, function (obj, key) {
+        try {
+          var result = obj.path ? require(obj.path) : {};
+
+          if (clobber) {
+              // Clobber if it doesn't exist.
+              if (typeof parent[key] === 'undefined') {
+                  parent[key] = result;
+              } else if (typeof obj.path !== 'undefined') {
+                  // If merging, merge properties onto parent, otherwise, clobber.
+                  if (merge) {
+                      recursiveMerge(parent[key], result);
+                  } else {
+                      parent[key] = result;
+                  }
+              }
+              result = parent[key];
+          } else {
+            // Overwrite if not currently defined.
+            if (typeof parent[key] == 'undefined') {
+              parent[key] = result;
+            } else if (merge && typeof obj.path !== 'undefined') {
+              // If merging, merge parent onto result
+              recursiveMerge(result, parent[key]);
+              parent[key] = result;
+            } else {
+              // Set result to what already exists, so we can build children into it if they exist.
+              result = parent[key];
+            }
+          }
+
+          if (obj.children) {
+            include(result, obj.children, clobber, merge);
+          }
+        } catch(e) {
+          utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+        }
+    });
+}
+
+/**
+ * Merge properties from one object onto another recursively.  Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+    for (var prop in src) {
+        if (src.hasOwnProperty(prop)) {
+            if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) {
+                // If the target object is a constructor override off prototype.
+                target.prototype[prop] = src[prop];
+            } else {
+                target[prop] = typeof src[prop] === 'object' ? recursiveMerge(
+                        target[prop], src[prop]) : src[prop];
+            }
+        }
+    }
+    return target;
+}
+
+module.exports = {
+    build: function (objects) {
+        return {
+            intoButDontClobber: function (target) {
+                include(target, objects, false, false);
+            },
+            intoAndClobber: function(target) {
+                include(target, objects, true, false);
+            },
+            intoAndMerge: function(target) {
+                include(target, objects, true, true);
+            }
+        };
+    }
+};
+
+});
+
+// file: lib/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+var utils = require('cordova/utils');
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded         Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady              Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady             Internal event fired when all Cordova JavaScript objects have been created.
+ * onCordovaInfoReady         Internal event fired when device properties are available.
+ * onCordovaConnectionReady   Internal event fired when the connection property has been set.
+ * onDeviceReady              User event fired to indicate that Cordova is ready
+ * onResume                   User event fired to indicate a start/resume lifecycle event
+ * onPause                    User event fired to indicate a pause lifecycle event
+ * onDestroy                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The only Cordova events that user code should register for are:
+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ *      pause                 App has moved to background
+ *      resume                App has returned to foreground
+ *
+ * Listeners can be registered as:
+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);
+ *      document.addEventListener("resume", myResumeListener, false);
+ *      document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ *      window.onload
+ *      window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type  String the channel name
+ * @param opts  Object options to pass into the channel, currently
+ *                     supports:
+ *                     onSubscribe: callback that fires when
+ *                       something subscribes to the Channel. Sets
+ *                       context to the Channel.
+ *                     onUnsubscribe: callback that fires when
+ *                       something unsubscribes to the Channel. Sets
+ *                       context to the Channel.
+ */
+var Channel = function(type, opts) {
+    this.type = type;
+    this.handlers = {};
+    this.numHandlers = 0;
+    this.guid = 1;
+    this.fired = false;
+    this.enabled = true;
+    this.events = {
+        onSubscribe:null,
+        onUnsubscribe:null
+    };
+    if (opts) {
+        if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe;
+        if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe;
+    }
+},
+    channel = {
+        /**
+         * Calls the provided function only after all of the channels specified
+         * have been fired.
+         */
+        join: function (h, c) {
+            var i = c.length;
+            var len = i;
+            var f = function() {
+                if (!(--i)) h();
+            };
+            for (var j=0; j<len; j++) {
+                !c[j].fired?c[j].subscribeOnce(f):i--;
+            }
+            if (!i) h();
+        },
+        create: function (type, opts) {
+            channel[type] = new Channel(type, opts);
+            return channel[type];
+        },
+
+        /**
+         * cordova Channels that must fire before "deviceready" is fired.
+         */
+        deviceReadyChannelsArray: [],
+        deviceReadyChannelsMap: {},
+
+        /**
+         * Indicate that a feature needs to be initialized before it is ready to be used.
+         * This holds up Cordova's "deviceready" event until the feature has been initialized
+         * and Cordova.initComplete(feature) is called.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        waitForInitialization: function(feature) {
+            if (feature) {
+                var c = null;
+                if (this[feature]) {
+                    c = this[feature];
+                }
+                else {
+                    c = this.create(feature);
+                }
+                this.deviceReadyChannelsMap[feature] = c;
+                this.deviceReadyChannelsArray.push(c);
+            }
+        },
+
+        /**
+         * Indicate that initialization code has completed and the feature is ready to be used.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        initializationComplete: function(feature) {
+            var c = this.deviceReadyChannelsMap[feature];
+            if (c) {
+                c.fire();
+            }
+        }
+    };
+
+function forceFunction(f) {
+    if (f === null || f === undefined || typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c, g) {
+    // need a function to call
+    forceFunction(f);
+
+    var func = f;
+    if (typeof c == "object") { func = utils.close(c, f); }
+
+    g = g || func.observer_guid || f.observer_guid;
+    if (!g) {
+        // first time we've seen this subscriber
+        g = this.guid++;
+    }
+    else {
+        // subscriber already handled; dont set it twice
+        return g;
+    }
+    func.observer_guid = g;
+    f.observer_guid = g;
+    this.handlers[g] = func;
+    this.numHandlers++;
+    if (this.events.onSubscribe) this.events.onSubscribe.call(this);
+    if (this.fired) func.call(this);
+    return g;
+};
+
+/**
+ * Like subscribe but the function is only called once and then it
+ * auto-unsubscribes itself.
+ */
+Channel.prototype.subscribeOnce = function(f, c) {
+    // need a function to call
+    forceFunction(f);
+
+    var g = null;
+    var _this = this;
+    var m = function() {
+        f.apply(c || null, arguments);
+        _this.unsubscribe(g);
+    };
+    if (this.fired) {
+        if (typeof c == "object") { f = utils.close(c, f); }
+        f.apply(this, this.fireArgs);
+    } else {
+        g = this.subscribe(m);
+    }
+    return g;
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(g) {
+    // need a function to unsubscribe
+    if (g === null || g === undefined) { throw "You must pass _something_ into Channel.unsubscribe"; }
+
+    if (typeof g == 'function') { g = g.observer_guid; }
+    var handler = this.handlers[g];
+    if (handler) {
+        if (handler.observer_guid) handler.observer_guid=null;
+        this.handlers[g] = null;
+        delete this.handlers[g];
+        this.numHandlers--;
+        if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);
+    }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+    if (this.enabled) {
+        var fail = false;
+        this.fired = true;
+        for (var item in this.handlers) {
+            var handler = this.handlers[item];
+            if (typeof handler == 'function') {
+                var rv = (handler.apply(this, arguments)===false);
+                fail = fail || rv;
+            }
+        }
+        this.fireArgs = arguments;
+        return !fail;
+    }
+    return true;
+};
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.create('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.create('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.create('onCordovaReady');
+
+// Event to indicate that device properties are available
+channel.create('onCordovaInfoReady');
+
+// Event to indicate that the connection property has been set.
+channel.create('onCordovaConnectionReady');
+
+// Event to indicate that Cordova is ready
+channel.create('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.create('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onCordovaConnectionReady');
+
+module.exports = channel;
+
+});
+
+// file: lib/common/common.js
+define("cordova/common", function(require, exports, module) {
+module.exports = {
+    objects: {
+        cordova: {
+            path: 'cordova',
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                },
+                logger: {
+                    path: 'cordova/plugin/logger'
+                }
+            }
+        },
+        Cordova: {
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                }
+            }
+        },
+        PhoneGap:{
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                }
+            }
+        },
+        navigator: {
+            children: {
+                notification: {
+                    path: 'cordova/plugin/notification'
+                },
+                accelerometer: {
+                    path: 'cordova/plugin/accelerometer'
+                },
+                battery: {
+                    path: 'cordova/plugin/battery'
+                },
+                camera:{
+                    path: 'cordova/plugin/Camera'
+                },
+                compass:{
+                    path: 'cordova/plugin/compass'
+                },
+                contacts: {
+                    path: 'cordova/plugin/contacts'
+                },
+                device:{
+                    children:{
+                        capture: {
+                            path: 'cordova/plugin/capture'
+                        }
+                    }
+                },
+                geolocation: {
+                    path: 'cordova/plugin/geolocation'
+                },
+                network: {
+                    children: {
+                        connection: {
+                            path: 'cordova/plugin/network'
+                        }
+                    }
+                },
+                splashscreen: {
+                    path: 'cordova/plugin/splashscreen'
+                }
+            }
+        },
+        Acceleration: {
+            path: 'cordova/plugin/Acceleration'
+        },
+        Camera:{
+            path: 'cordova/plugin/CameraConstants'
+        },
+        CameraPopoverOptions: {
+            path: 'cordova/plugin/CameraPopoverOptions'
+        },
+        CaptureError: {
+            path: 'cordova/plugin/CaptureError'
+        },
+        CaptureAudioOptions:{
+            path: 'cordova/plugin/CaptureAudioOptions'
+        },
+        CaptureImageOptions: {
+            path: 'cordova/plugin/CaptureImageOptions'
+        },
+        CaptureVideoOptions: {
+            path: 'cordova/plugin/CaptureVideoOptions'
+        },
+        CompassHeading:{
+            path: 'cordova/plugin/CompassHeading'
+        },
+        CompassError:{
+            path: 'cordova/plugin/CompassError'
+        },
+        ConfigurationData: {
+            path: 'cordova/plugin/ConfigurationData'
+        },
+        Connection: {
+            path: 'cordova/plugin/Connection'
+        },
+        Contact: {
+            path: 'cordova/plugin/Contact'
+        },
+        ContactAddress: {
+            path: 'cordova/plugin/ContactAddress'
+        },
+        ContactError: {
+            path: 'cordova/plugin/ContactError'
+        },
+        ContactField: {
+            path: 'cordova/plugin/ContactField'
+        },
+        ContactFindOptions: {
+            path: 'cordova/plugin/ContactFindOptions'
+        },
+        ContactName: {
+            path: 'cordova/plugin/ContactName'
+        },
+        ContactOrganization: {
+            path: 'cordova/plugin/ContactOrganization'
+        },
+        Coordinates: {
+            path: 'cordova/plugin/Coordinates'
+        },
+        device: {
+            path: 'cordova/plugin/device'
+        },
+        DirectoryEntry: {
+            path: 'cordova/plugin/DirectoryEntry'
+        },
+        DirectoryReader: {
+            path: 'cordova/plugin/DirectoryReader'
+        },
+        Entry: {
+            path: 'cordova/plugin/Entry'
+        },
+        File: {
+            path: 'cordova/plugin/File'
+        },
+        FileEntry: {
+            path: 'cordova/plugin/FileEntry'
+        },
+        FileError: {
+            path: 'cordova/plugin/FileError'
+        },
+        FileReader: {
+            path: 'cordova/plugin/FileReader'
+        },
+        FileSystem: {
+            path: 'cordova/plugin/FileSystem'
+        },
+        FileTransfer: {
+            path: 'cordova/plugin/FileTransfer'
+        },
+        FileTransferError: {
+            path: 'cordova/plugin/FileTransferError'
+        },
+        FileUploadOptions: {
+            path: 'cordova/plugin/FileUploadOptions'
+        },
+        FileUploadResult: {
+            path: 'cordova/plugin/FileUploadResult'
+        },
+        FileWriter: {
+            path: 'cordova/plugin/FileWriter'
+        },
+        Flags: {
+            path: 'cordova/plugin/Flags'
+        },
+        LocalFileSystem: {
+            path: 'cordova/plugin/LocalFileSystem'
+        },
+        Media: {
+            path: 'cordova/plugin/Media'
+        },
+        MediaError: {
+            path: 'cordova/plugin/MediaError'
+        },
+        MediaFile: {
+            path: 'cordova/plugin/MediaFile'
+        },
+        MediaFileData:{
+            path: 'cordova/plugin/MediaFileData'
+        },
+        Metadata:{
+            path: 'cordova/plugin/Metadata'
+        },
+        Position: {
+            path: 'cordova/plugin/Position'
+        },
+        PositionError: {
+            path: 'cordova/plugin/PositionError'
+        },
+        ProgressEvent: {
+            path: 'cordova/plugin/ProgressEvent'
+        },
+        requestFileSystem:{
+            path: 'cordova/plugin/requestFileSystem'
+        },
+        resolveLocalFileSystemURI:{
+            path: 'cordova/plugin/resolveLocalFileSystemURI'
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/exec.js
+define("cordova/exec", function(require, exports, module) {
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchrounous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} successCB  The success callback
+ * @param {Function} failCB     The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ */
+
+var tizen = require('cordova/plugin/tizen/manager'),
+    cordova = require('cordova'),
+    utils = require('cordova/utils');
+
+module.exports = function(successCB, failCB, service, action, args) {
+
+    try {
+        var v = tizen.exec(successCB, failCB, service, action, args);
+
+        // If status is OK, then return value back to caller
+        if (v.status == cordova.callbackStatus.OK) {
+
+            // If there is a success callback, then call it now with returned value
+            if (successCB) {
+                try {
+                    successCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+ service + "." + action + " = " + e);
+                }
+
+            }
+            return v.message;
+        } else if (v.status == cordova.callbackStatus.NO_RESULT) {
+            // Nothing to do here
+        } else {
+            // If error, then display error
+            console.log("Error: " + service + "." + action + " Status=" + v.status + " Message=" + v.message);
+
+            // If there is a fail callback, then call it now with returned value
+            if (failCB) {
+                try {
+                    failCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in error callback: " + service + "." + action + " = "+e);
+                }
+            }
+            return null;
+        }
+    } catch (e) {
+        utils.alert("Error: " + e);
+    }
+};
+
+});
+
+// file: lib/tizen/platform.js
+define("cordova/platform", function(require, exports, module) {
+module.exports = {
+    id: "tizen",
+    initialize: function() {},
+    objects: {
+        device: {
+            path: "cordova/plugin/tizen/Device"
+        },
+        File: { // exists natively, override
+            path: "cordova/plugin/File"
+        },
+        FileReader: { // exists natively, override
+            path: "cordova/plugin/FileReader"
+        },
+        FileError: { //exists natively, override
+            path: "cordova/plugin/FileError"
+        }
+    },
+    merges: {
+        MediaError: { // exists natively
+            path: "cordova/plugin/tizen/MediaError"
+        },
+        navigator: {
+            children: {
+                device: {
+                    path: "cordova/plugin/tizen/Device"
+                },
+                contacts: {
+                    path: "cordova/plugin/tizen/contacts"
+                },
+               notification: {
+                   path: "cordova/plugin/tizen/Notification"
+               }
+            }
+        },
+        Contact: {
+            path: "cordova/plugin/tizen/Contact"
+        }
+    }
+};
+
+});
+
+// file: lib/common/plugin/Acceleration.js
+define("cordova/plugin/Acceleration", function(require, exports, module) {
+var Acceleration = function(x, y, z, timestamp) {
+    this.x = x;
+    this.y = y;
+    this.z = z;
+    this.timestamp = timestamp || (new Date()).getTime();
+};
+
+module.exports = Acceleration;
+
+});
+
+// file: lib/common/plugin/Camera.js
+define("cordova/plugin/Camera", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    Camera = require('cordova/plugin/CameraConstants');
+
+var cameraExport = {};
+
+// Tack on the Camera Constants to the base camera plugin.
+for (var key in Camera) {
+    cameraExport[key] = Camera[key];
+}
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+cameraExport.getPicture = function(successCallback, errorCallback, options) {
+    // successCallback required
+    if (typeof successCallback != "function") {
+        console.log("Camera Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback != "function")) {
+        console.log("Camera Error: errorCallback is not a function");
+        return;
+    }
+
+    var quality = 50;
+    if (options && typeof options.quality == "number") {
+        quality = options.quality;
+    } else if (options && typeof options.quality == "string") {
+        var qlity = parseInt(options.quality, 10);
+        if (isNaN(qlity) === false) {
+            quality = qlity.valueOf();
+        }
+    }
+
+    var destinationType = Camera.DestinationType.FILE_URI;
+    if (typeof options.destinationType == "number") {
+        destinationType = options.destinationType;
+    }
+
+    var sourceType = Camera.PictureSourceType.CAMERA;
+    if (typeof options.sourceType == "number") {
+        sourceType = options.sourceType;
+    }
+
+    var targetWidth = -1;
+    if (typeof options.targetWidth == "number") {
+        targetWidth = options.targetWidth;
+    } else if (typeof options.targetWidth == "string") {
+        var width = parseInt(options.targetWidth, 10);
+        if (isNaN(width) === false) {
+            targetWidth = width.valueOf();
+        }
+    }
+
+    var targetHeight = -1;
+    if (typeof options.targetHeight == "number") {
+        targetHeight = options.targetHeight;
+    } else if (typeof options.targetHeight == "string") {
+        var height = parseInt(options.targetHeight, 10);
+        if (isNaN(height) === false) {
+            targetHeight = height.valueOf();
+        }
+    }
+
+    var encodingType = Camera.EncodingType.JPEG;
+    if (typeof options.encodingType == "number") {
+        encodingType = options.encodingType;
+    }
+
+    var mediaType = Camera.MediaType.PICTURE;
+    if (typeof options.mediaType == "number") {
+        mediaType = options.mediaType;
+    }
+    var allowEdit = false;
+    if (typeof options.allowEdit == "boolean") {
+        allowEdit = options.allowEdit;
+    } else if (typeof options.allowEdit == "number") {
+        allowEdit = options.allowEdit <= 0 ? false : true;
+    }
+    var correctOrientation = false;
+    if (typeof options.correctOrientation == "boolean") {
+        correctOrientation = options.correctOrientation;
+    } else if (typeof options.correctOrientation == "number") {
+        correctOrientation = options.correctOrientation <=0 ? false : true;
+    }
+    var saveToPhotoAlbum = false;
+    if (typeof options.saveToPhotoAlbum == "boolean") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum;
+    } else if (typeof options.saveToPhotoAlbum == "number") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum <=0 ? false : true;
+    }
+    var popoverOptions = null;
+    if (typeof options.popoverOptions == "object") {
+        popoverOptions = options.popoverOptions;
+    }
+
+    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
+                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+
+    exec(successCallback, errorCallback, "Camera", "takePicture", args);
+};
+
+cameraExport.cleanup = function(successCallback, errorCallback) {
+    exec(successCallback, errorCallback, "Camera", "cleanup", []);
+};
+
+module.exports = cameraExport;
+});
+
+// file: lib/common/plugin/CameraConstants.js
+define("cordova/plugin/CameraConstants", function(require, exports, module) {
+module.exports = {
+  DestinationType:{
+    DATA_URL: 0,         // Return base64 encoded string
+    FILE_URI: 1          // Return file uri (content://media/external/images/media/2 for Android)
+  },
+  EncodingType:{
+    JPEG: 0,             // Return JPEG encoded image
+    PNG: 1               // Return PNG encoded image
+  },
+  MediaType:{
+    PICTURE: 0,          // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
+    VIDEO: 1,            // allow selection of video only, ONLY RETURNS URL
+    ALLMEDIA : 2         // allow selection from all media types
+  },
+  PictureSourceType:{
+    PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
+    CAMERA : 1,          // Take picture from camera
+    SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)
+  },
+  PopoverArrowDirection:{
+      ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
+      ARROW_DOWN : 2,
+      ARROW_LEFT : 4,
+      ARROW_RIGHT : 8,
+      ARROW_ANY : 15
+  }
+};
+});
+
+// file: lib/common/plugin/CameraPopoverOptions.js
+define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
+var Camera = require('cordova/plugin/CameraConstants');
+
+/**
+ * Encapsulates options for iOS Popover image picker
+ */
+var CameraPopoverOptions = function(x,y,width,height,arrowDir){
+    // information of rectangle that popover should be anchored to
+    this.x = x || 0;
+    this.y = y || 32;
+    this.width = width || 320;
+    this.height = height || 480;
+    // The direction of the popover arrow
+    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
+};
+
+module.exports = CameraPopoverOptions;
+});
+
+// file: lib/common/plugin/CaptureAudioOptions.js
+define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
+/**
+ * Encapsulates all audio capture operation configuration options.
+ */
+var CaptureAudioOptions = function(){
+    // Upper limit of sound clips user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single sound clip in seconds.
+    this.duration = 0;
+    // The selected audio mode. Must match with one of the elements in supportedAudioModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureAudioOptions;
+});
+
+// file: lib/common/plugin/CaptureError.js
+define("cordova/plugin/CaptureError", function(require, exports, module) {
+/**
+ * The CaptureError interface encapsulates all errors in the Capture API.
+ */
+var CaptureError = function(c) {
+   this.code = c || null;
+};
+
+// Camera or microphone failed to capture image or sound.
+CaptureError.CAPTURE_INTERNAL_ERR = 0;
+// Camera application or audio capture application is currently serving other capture request.
+CaptureError.CAPTURE_APPLICATION_BUSY = 1;
+// Invalid use of the API (e.g. limit parameter has value less than one).
+CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
+// User exited camera application or audio capture application before capturing anything.
+CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
+// The requested capture operation is not supported.
+CaptureError.CAPTURE_NOT_SUPPORTED = 20;
+
+module.exports = CaptureError;
+});
+
+// file: lib/common/plugin/CaptureImageOptions.js
+define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
+/**
+ * Encapsulates all image capture operation configuration options.
+ */
+var CaptureImageOptions = function(){
+    // Upper limit of images user can take. Value must be equal or greater than 1.
+    this.limit = 1;
+    // The selected image mode. Must match with one of the elements in supportedImageModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureImageOptions;
+});
+
+// file: lib/common/plugin/CaptureVideoOptions.js
+define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
+/**
+ * Encapsulates all video capture operation configuration options.
+ */
+var CaptureVideoOptions = function(){
+    // Upper limit of videos user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single video clip in seconds.
+    this.duration = 0;
+    // The selected video mode. Must match with one of the elements in supportedVideoModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureVideoOptions;
+});
+
+// file: lib/common/plugin/CompassError.js
+define("cordova/plugin/CompassError", function(require, exports, module) {
+/**
+ *  CompassError.
+ *  An error code assigned by an implementation when an error has occured
+ * @constructor
+ */
+var CompassError = function(err) {
+    this.code = (err !== undefined ? err : null);
+};
+
+CompassError.COMPASS_INTERNAL_ERR = 0;
+CompassError.COMPASS_NOT_SUPPORTED = 20;
+
+module.exports = CompassError;
+});
+
+// file: lib/common/plugin/CompassHeading.js
+define("cordova/plugin/CompassHeading", function(require, exports, module) {
+var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
+  this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null);
+  this.trueHeading = (trueHeading !== undefined ? trueHeading : null);
+  this.headingAccuracy = (headingAccuracy !== undefined ? headingAccuracy : null);
+  this.timestamp = (timestamp !== undefined ? timestamp : new Date().getTime());
+};
+
+module.exports = CompassHeading;
+});
+
+// file: lib/common/plugin/ConfigurationData.js
+define("cordova/plugin/ConfigurationData", function(require, exports, module) {
+/**
+ * Encapsulates a set of parameters that the capture device supports.
+ */
+function ConfigurationData() {
+    // The ASCII-encoded string in lower case representing the media type.
+    this.type = null;
+    // The height attribute represents height of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0.
+    this.height = 0;
+    // The width attribute represents width of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0
+    this.width = 0;
+}
+
+module.exports = ConfigurationData;
+});
+
+// file: lib/common/plugin/Connection.js
+define("cordova/plugin/Connection", function(require, exports, module) {
+/**
+ * Network status
+ */
+module.exports = {
+        UNKNOWN: "unknown",
+        ETHERNET: "ethernet",
+        WIFI: "wifi",
+        CELL_2G: "2g",
+        CELL_3G: "3g",
+        CELL_4G: "4g",
+        NONE: "none"
+};
+});
+
+// file: lib/common/plugin/Contact.js
+define("cordova/plugin/Contact", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils');
+
+/**
+* Converts primitives into Complex Object
+* Currently only used for Date fields
+*/
+function convertIn(contact) {
+    var value = contact.birthday;
+    try {
+      contact.birthday = new Date(parseFloat(value));
+    } catch (exception){
+      console.log("Cordova Contact convertIn error: exception creating date.");
+    }
+    return contact;
+}
+
+/**
+* Converts Complex objects into primitives
+* Only conversion at present is for Dates.
+**/
+
+function convertOut(contact) {
+    var value = contact.birthday;
+    if (value !== null) {
+        // try to make it a Date object if it is not already
+        if (!utils.isDate(value)){
+            try {
+                value = new Date(value);
+            } catch(exception){
+                value = null;
+            }
+        }
+        if (utils.isDate(value)){
+            value = value.valueOf(); // convert to milliseconds
+        }
+        contact.birthday = value;
+    }
+    return contact;
+}
+
+/**
+* Contains information about a single contact.
+* @constructor
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {Array.<ContactField>} phoneNumbers array of phone numbers
+* @param {Array.<ContactField>} emails array of email addresses
+* @param {Array.<ContactAddress>} addresses array of addresses
+* @param {Array.<ContactField>} ims instant messaging user ids
+* @param {Array.<ContactOrganization>} organizations
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} note user notes about contact
+* @param {Array.<ContactField>} photos
+* @param {Array.<ContactField>} categories
+* @param {Array.<ContactField>} urls contact's web sites
+*/
+var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
+    ims, organizations, birthday, note, photos, categories, urls) {
+    this.id = id || null;
+    this.rawId = null;
+    this.displayName = displayName || null;
+    this.name = name || null; // ContactName
+    this.nickname = nickname || null;
+    this.phoneNumbers = phoneNumbers || null; // ContactField[]
+    this.emails = emails || null; // ContactField[]
+    this.addresses = addresses || null; // ContactAddress[]
+    this.ims = ims || null; // ContactField[]
+    this.organizations = organizations || null; // ContactOrganization[]
+    this.birthday = birthday || null;
+    this.note = note || null;
+    this.photos = photos || null; // ContactField[]
+    this.categories = categories || null; // ContactField[]
+    this.urls = urls || null; // ContactField[]
+};
+
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+    var fail = function(code) {
+        errorCB(new ContactError(code));
+    };
+    if (this.id === null) {
+        fail(ContactError.UNKNOWN_ERROR);
+    }
+    else {
+        exec(successCB, fail, "Contacts", "remove", [this.id]);
+    }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+    var clonedContact = utils.clone(this);
+    var i;
+    clonedContact.id = null;
+    clonedContact.rawId = null;
+    // Loop through and clear out any id's in phones, emails, etc.
+    if (clonedContact.phoneNumbers) {
+        for (i = 0; i < clonedContact.phoneNumbers.length; i++) {
+            clonedContact.phoneNumbers[i].id = null;
+        }
+    }
+    if (clonedContact.emails) {
+        for (i = 0; i < clonedContact.emails.length; i++) {
+            clonedContact.emails[i].id = null;
+        }
+    }
+    if (clonedContact.addresses) {
+        for (i = 0; i < clonedContact.addresses.length; i++) {
+            clonedContact.addresses[i].id = null;
+        }
+    }
+    if (clonedContact.ims) {
+        for (i = 0; i < clonedContact.ims.length; i++) {
+            clonedContact.ims[i].id = null;
+        }
+    }
+    if (clonedContact.organizations) {
+        for (i = 0; i < clonedContact.organizations.length; i++) {
+            clonedContact.organizations[i].id = null;
+        }
+    }
+    if (clonedContact.categories) {
+        for (i = 0; i < clonedContact.categories.length; i++) {
+            clonedContact.categories[i].id = null;
+        }
+    }
+    if (clonedContact.photos) {
+        for (i = 0; i < clonedContact.photos.length; i++) {
+            clonedContact.photos[i].id = null;
+        }
+    }
+    if (clonedContact.urls) {
+        for (i = 0; i < clonedContact.urls.length; i++) {
+            clonedContact.urls[i].id = null;
+        }
+    }
+    return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+  var fail = function(code) {
+      errorCB(new ContactError(code));
+  };
+    var success = function(result) {
+      if (result) {
+          if (typeof successCB === 'function') {
+              var fullContact = require('cordova/plugin/contacts').create(result);
+              successCB(convertIn(fullContact));
+          }
+      }
+      else {
+          // no Entry object returned
+          fail(ContactError.UNKNOWN_ERROR);
+      }
+  };
+    var dupContact = convertOut(utils.clone(this));
+    exec(success, fail, "Contacts", "save", [dupContact]);
+};
+
+
+module.exports = Contact;
+
+});
+
+// file: lib/common/plugin/ContactAddress.js
+define("cordova/plugin/ContactAddress", function(require, exports, module) {
+/**
+* Contact address.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code
+* @param formatted // NOTE: not a W3C standard
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+
+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.formatted = formatted || null;
+    this.streetAddress = streetAddress || null;
+    this.locality = locality || null;
+    this.region = region || null;
+    this.postalCode = postalCode || null;
+    this.country = country || null;
+};
+
+module.exports = ContactAddress;
+});
+
+// file: lib/common/plugin/ContactError.js
+define("cordova/plugin/ContactError", function(require, exports, module) {
+/**
+ *  ContactError.
+ *  An error code assigned by an implementation when an error has occured
+ * @constructor
+ */
+var ContactError = function(err) {
+    this.code = (typeof err != 'undefined' ? err : null);
+};
+
+/**
+ * Error codes
+ */
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.TIMEOUT_ERROR = 2;
+ContactError.PENDING_OPERATION_ERROR = 3;
+ContactError.IO_ERROR = 4;
+ContactError.NOT_SUPPORTED_ERROR = 5;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+module.exports = ContactError;
+});
+
+// file: lib/common/plugin/ContactField.js
+define("cordova/plugin/ContactField", function(require, exports, module) {
+/**
+* Generic contact field.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param type
+* @param value
+* @param pref
+*/
+var ContactField = function(type, value, pref) {
+    this.id = null;
+    this.type = (type && type.toString()) || null;
+    this.value = (value && value.toString()) || null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+};
+
+module.exports = ContactField;
+});
+
+// file: lib/common/plugin/ContactFindOptions.js
+define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
+/**
+ * ContactFindOptions.
+ * @constructor
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ */
+
+var ContactFindOptions = function(filter, multiple) {
+    this.filter = filter || '';
+    this.multiple = (typeof multiple != 'undefined' ? multiple : false);
+};
+
+module.exports = ContactFindOptions;
+});
+
+// file: lib/common/plugin/ContactName.js
+define("cordova/plugin/ContactName", function(require, exports, module) {
+/**
+* Contact name.
+* @constructor
+* @param formatted // NOTE: not part of W3C standard
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
+    this.formatted = formatted || null;
+    this.familyName = familyName || null;
+    this.givenName = givenName || null;
+    this.middleName = middle || null;
+    this.honorificPrefix = prefix || null;
+    this.honorificSuffix = suffix || null;
+};
+
+module.exports = ContactName;
+});
+
+// file: lib/common/plugin/ContactOrganization.js
+define("cordova/plugin/ContactOrganization", function(require, exports, module) {
+/**
+* Contact organization.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param name
+* @param dept
+* @param title
+* @param startDate
+* @param endDate
+* @param location
+* @param desc
+*/
+
+var ContactOrganization = function(pref, type, name, dept, title) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.name = name || null;
+    this.department = dept || null;
+    this.title = title || null;
+};
+
+module.exports = ContactOrganization;
+});
+
+// file: lib/common/plugin/Coordinates.js
+define("cordova/plugin/Coordinates", function(require, exports, module) {
+/**
+ * This class contains position information.
+ * @param {Object} lat
+ * @param {Object} lng
+ * @param {Object} alt
+ * @param {Object} acc
+ * @param {Object} head
+ * @param {Object} vel
+ * @param {Object} altacc
+ * @constructor
+ */
+var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
+    /**
+     * The latitude of the position.
+     */
+    this.latitude = lat;
+    /**
+     * The longitude of the position,
+     */
+    this.longitude = lng;
+    /**
+     * The accuracy of the position.
+     */
+    this.accuracy = acc;
+    /**
+     * The altitude of the position.
+     */
+    this.altitude = (alt !== undefined ? alt : null);
+    /**
+     * The direction the device is moving at the position.
+     */
+    this.heading = (head !== undefined ? head : null);
+    /**
+     * The velocity with which the device is moving at the position.
+     */
+    this.speed = (vel !== undefined ? vel : null);
+
+    if (this.speed === 0 || this.speed === null) {
+        this.heading = NaN;
+    }
+
+    /**
+     * The altitude accuracy of the position.
+     */
+    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
+};
+
+module.exports = Coordinates;
+
+});
+
+// file: lib/common/plugin/DirectoryEntry.js
+define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileError = require('cordova/plugin/FileError'),
+    DirectoryReader = require('cordova/plugin/DirectoryReader');
+
+/**
+ * An interface representing a directory on the file system.
+ *
+ * {boolean} isFile always false (readonly)
+ * {boolean} isDirectory always true (readonly)
+ * {DOMString} name of the directory, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the directory (readonly)
+ * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
+ */
+var DirectoryEntry = function(name, fullPath) {
+     DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]);
+};
+
+utils.extend(DirectoryEntry, Entry);
+
+/**
+ * Creates a new DirectoryReader to read entries from this directory
+ */
+DirectoryEntry.prototype.createReader = function() {
+    return new DirectoryReader(this.fullPath);
+};
+
+/**
+ * Creates or looks up a directory
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
+ * @param {Flags} options to create or excluively create the directory
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
+};
+
+/**
+ * Deletes a directory and all of it's contents
+ *
+ * @param {Function} successCallback is called with no parameters
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
+};
+
+/**
+ * Creates or looks up a file
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
+ * @param {Flags} options to create or excluively create the file
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var FileEntry = require('cordova/plugin/FileEntry');
+        var entry = new FileEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
+};
+
+module.exports = DirectoryEntry;
+
+});
+
+// file: lib/common/plugin/DirectoryReader.js
+define("cordova/plugin/DirectoryReader", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError') ;
+
+/**
+ * An interface that lists the files and directories in a directory.
+ */
+function DirectoryReader(path) {
+    this.path = path || null;
+}
+
+/**
+ * Returns a list of entries from a directory.
+ *
+ * @param {Function} successCallback is called with a list of entries
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var retVal = [];
+        for (var i=0; i<result.length; i++) {
+            var entry = null;
+            if (result[i].isDirectory) {
+                entry = new (require('cordova/plugin/DirectoryEntry'))();
+            }
+            else if (result[i].isFile) {
+                entry = new (require('cordova/plugin/FileEntry'))();
+            }
+            entry.isDirectory = result[i].isDirectory;
+            entry.isFile = result[i].isFile;
+            entry.name = result[i].name;
+            entry.fullPath = result[i].fullPath;
+            retVal.push(entry);
+        }
+        successCallback(retVal);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "readEntries", [this.path]);
+};
+
+module.exports = DirectoryReader;
+
+});
+
+// file: lib/common/plugin/Entry.js
+define("cordova/plugin/Entry", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    Metadata = require('cordova/plugin/Metadata');
+
+/**
+ * Represents a file or directory on the local file system.
+ *
+ * @param isFile
+ *            {boolean} true if Entry is a file (readonly)
+ * @param isDirectory
+ *            {boolean} true if Entry is a directory (readonly)
+ * @param name
+ *            {DOMString} name of the file or directory, excluding the path
+ *            leading to it (readonly)
+ * @param fullPath
+ *            {DOMString} the absolute full path to the file or directory
+ *            (readonly)
+ */
+function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
+    this.isFile = (typeof isFile != 'undefined'?isFile:false);
+    this.isDirectory = (typeof isDirectory != 'undefined'?isDirectory:false);
+    this.name = name || '';
+    this.fullPath = fullPath || '';
+    this.filesystem = fileSystem || null;
+}
+
+/**
+ * Look up the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ */
+Entry.prototype.getMetadata = function(successCallback, errorCallback) {
+  var success = typeof successCallback !== 'function' ? null : function(lastModified) {
+      var metadata = new Metadata(lastModified);
+      successCallback(metadata);
+  };
+  var fail = typeof errorCallback !== 'function' ? null : function(code) {
+      errorCallback(new FileError(code));
+  };
+
+  exec(success, fail, "File", "getMetadata", [this.fullPath]);
+};
+
+/**
+ * Set the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ * @param metadataObject
+ *            {Object} keys and values to set
+ */
+Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
+
+  exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
+};
+
+/**
+ * Move a file or directory to a new location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to move this entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new DirectoryEntry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+    // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Copy a directory to a different location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to copy the entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new Entry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+
+        // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        // success callback
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Return a URL that can be used to identify this entry.
+ */
+Entry.prototype.toURL = function() {
+    // fullPath attribute contains the full URL
+    return this.fullPath;
+};
+
+/**
+ * Returns a URI that can be used to identify this entry.
+ *
+ * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
+ * @return uri
+ */
+Entry.prototype.toURI = function(mimeType) {
+    console.log("DEPRECATED: Update your code to use 'toURL'");
+    // fullPath attribute contains the full URI
+    return this.toURL();
+};
+
+/**
+ * Remove a file or directory. It is an error to attempt to delete a
+ * directory that is not empty. It is an error to attempt to delete a
+ * root directory of a file system.
+ *
+ * @param successCallback {Function} called with no parameters
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.remove = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "remove", [this.fullPath]);
+};
+
+/**
+ * Look up the parent DirectoryEntry of this entry.
+ *
+ * @param successCallback {Function} called with the parent DirectoryEntry object
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.getParent = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getParent", [this.fullPath]);
+};
+
+module.exports = Entry;
+});
+
+// file: lib/common/plugin/File.js
+define("cordova/plugin/File", function(require, exports, module) {
+/**
+ * Constructor.
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+
+var File = function(name, fullPath, type, lastModifiedDate, size){
+    this.name = name || '';
+    this.fullPath = fullPath || null;
+    this.type = type || null;
+    this.lastModifiedDate = lastModifiedDate || null;
+    this.size = size || 0;
+};
+
+module.exports = File;
+});
+
+// file: lib/common/plugin/FileEntry.js
+define("cordova/plugin/FileEntry", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileWriter = require('cordova/plugin/FileWriter'),
+    File = require('cordova/plugin/File'),
+    FileError = require('cordova/plugin/FileError');
+
+/**
+ * An interface representing a file on the file system.
+ *
+ * {boolean} isFile always true (readonly)
+ * {boolean} isDirectory always false (readonly)
+ * {DOMString} name of the file, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the file (readonly)
+ * {FileSystem} filesystem on which the file resides (readonly)
+ */
+var FileEntry = function(name, fullPath) {
+     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
+};
+
+utils.extend(FileEntry, Entry);
+
+/**
+ * Creates a new FileWriter associated with the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new FileWriter
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
+    this.file(function(filePointer) {
+        var writer = new FileWriter(filePointer);
+
+        if (writer.fileName === null || writer.fileName === "") {
+            if (typeof errorCallback === "function") {
+                errorCallback(new FileError(FileError.INVALID_STATE_ERR));
+            }
+        } else {
+            if (typeof successCallback === "function") {
+                successCallback(writer);
+            }
+        }
+    }, errorCallback);
+};
+
+/**
+ * Returns a File that represents the current state of the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new File object
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.file = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(f) {
+        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
+        successCallback(file);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
+};
+
+
+module.exports = FileEntry;
+});
+
+// file: lib/common/plugin/FileError.js
+define("cordova/plugin/FileError", function(require, exports, module) {
+/**
+ * FileError
+ */
+function FileError(error) {
+  this.code = error || null;
+}
+
+// File error codes
+// Found in DOMException
+FileError.NOT_FOUND_ERR = 1;
+FileError.SECURITY_ERR = 2;
+FileError.ABORT_ERR = 3;
+
+// Added by File API specification
+FileError.NOT_READABLE_ERR = 4;
+FileError.ENCODING_ERR = 5;
+FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
+FileError.INVALID_STATE_ERR = 7;
+FileError.SYNTAX_ERR = 8;
+FileError.INVALID_MODIFICATION_ERR = 9;
+FileError.QUOTA_EXCEEDED_ERR = 10;
+FileError.TYPE_MISMATCH_ERR = 11;
+FileError.PATH_EXISTS_ERR = 12;
+
+module.exports = FileError;
+});
+
+// file: lib/common/plugin/FileReader.js
+define("cordova/plugin/FileReader", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class reads the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To read from the SD card, the file name is "sdcard/my_file.txt"
+ * @constructor
+ */
+var FileReader = function() {
+    this.fileName = "";
+
+    this.readyState = 0; // FileReader.EMPTY
+
+    // File data
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onloadstart = null;    // When the read starts.
+    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total)
+    this.onload = null;         // When the read has successfully completed.
+    this.onerror = null;        // When the read has failed (see errors).
+    this.onloadend = null;      // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.
+};
+
+// States
+FileReader.EMPTY = 0;
+FileReader.LOADING = 1;
+FileReader.DONE = 2;
+
+/**
+ * Abort reading file.
+ */
+FileReader.prototype.abort = function() {
+    this.result = null;
+
+    if (this.readyState == FileReader.DONE || this.readyState == FileReader.EMPTY) {
+      return;
+    }
+
+    this.readyState = FileReader.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === 'function') {
+        this.onabort(new ProgressEvent('abort', {target:this}));
+    }
+    // If load end callback
+    if (typeof this.onloadend === 'function') {
+        this.onloadend(new ProgressEvent('loadend', {target:this}));
+    }
+};
+
+/**
+ * Read text file.
+ *
+ * @param file          {File} File object containing file properties
+ * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)
+ */
+FileReader.prototype.readAsText = function(file, encoding) {
+    // Figure out pathing
+    this.fileName = '';
+    if (typeof file.fullPath === 'undefined') {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    // Default encoding is UTF-8
+    var enc = encoding ? encoding : "UTF-8";
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // null result
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsText", [this.fileName, enc]);
+};
+
+
+/**
+ * Read file and return data as a base64 encoded data url.
+ * A data url is of the form:
+ *      data:[<mediatype>][;base64],<data>
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsDataURL = function(file) {
+    this.fileName = "";
+    if (typeof file.fullPath === "undefined") {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsDataURL", [this.fileName]);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsBinaryString = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('method "readAsBinaryString" is not supported at this time.');
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsArrayBuffer = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('This method is not supported at this time.');
+};
+
+module.exports = FileReader;
+});
+
+// file: lib/common/plugin/FileSystem.js
+define("cordova/plugin/FileSystem", function(require, exports, module) {
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+
+/**
+ * An interface representing a file system
+ *
+ * @constructor
+ * {DOMString} name the unique name of the file system (readonly)
+ * {DirectoryEntry} root directory of the file system (readonly)
+ */
+var FileSystem = function(name, root) {
+    this.name = name || null;
+    if (root) {
+        this.root = new DirectoryEntry(root.name, root.fullPath);
+    }
+};
+
+module.exports = FileSystem;
+
+});
+
+// file: lib/common/plugin/FileTransfer.js
+define("cordova/plugin/FileTransfer", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileTransferError = require('cordova/plugin/FileTransferError');
+
+/**
+ * FileTransfer uploads a file to a remote server.
+ * @constructor
+ */
+var FileTransfer = function() {};
+
+/**
+* Given an absolute file path, uploads a file on the device to a remote server
+* using a multipart HTTP request.
+* @param filePath {String}           Full path of the file on the device
+* @param server {String}             URL of the server to receive the file
+* @param successCallback (Function}  Callback to be invoked when upload has completed
+* @param errorCallback {Function}    Callback to be invoked upon error
+* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
+* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+*/
+FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
+    // sanity parameter checking
+    if (!filePath || !server) throw new Error("FileTransfer.upload requires filePath and server URL parameters at the minimum.");
+    // check for options
+    var fileKey = null;
+    var fileName = null;
+    var mimeType = null;
+    var params = null;
+    var chunkedMode = true;
+    if (options) {
+        fileKey = options.fileKey;
+        fileName = options.fileName;
+        mimeType = options.mimeType;
+        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
+            chunkedMode = options.chunkedMode;
+        }
+        if (options.params) {
+            params = options.params;
+        }
+        else {
+            params = {};
+        }
+    }
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]);
+};
+
+/**
+ * Downloads a file form a given URL and saves it to the specified directory.
+ * @param source {String}          URL of the server to receive the file
+ * @param target {String}         Full path of the file on the device
+ * @param successCallback (Function}  Callback to be invoked when upload has completed
+ * @param errorCallback {Function}    Callback to be invoked upon error
+ */
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) {
+    // sanity parameter checking
+    if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum.");
+    var win = function(result) {
+        var entry = null;
+        if (result.isDirectory) {
+            entry = new (require('cordova/plugin/DirectoryEntry'))();
+        }
+        else if (result.isFile) {
+            entry = new (require('cordova/plugin/FileEntry'))();
+        }
+        entry.isDirectory = result.isDirectory;
+        entry.isFile = result.isFile;
+        entry.name = result.name;
+        entry.fullPath = result.fullPath;
+        successCallback(entry);
+    };
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    exec(win, errorCallback, 'FileTransfer', 'download', [source, target]);
+};
+
+module.exports = FileTransfer;
+
+});
+
+// file: lib/common/plugin/FileTransferError.js
+define("cordova/plugin/FileTransferError", function(require, exports, module) {
+/**
+ * FileTransferError
+ * @constructor
+ */
+var FileTransferError = function(code, source, target, status) {
+    this.code = code || null;
+    this.source = source || null;
+    this.target = target || null;
+    this.http_status = status || null;
+};
+
+FileTransferError.FILE_NOT_FOUND_ERR = 1;
+FileTransferError.INVALID_URL_ERR = 2;
+FileTransferError.CONNECTION_ERR = 3;
+
+module.exports = FileTransferError;
+
+});
+
+// file: lib/common/plugin/FileUploadOptions.js
+define("cordova/plugin/FileUploadOptions", function(require, exports, module) {
+/**
+ * Options to customize the HTTP request used to upload files.
+ * @constructor
+ * @param fileKey {String}   Name of file request parameter.
+ * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.
+ * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.
+ * @param params {Object}    Object with key: value params to send to the server.
+ */
+var FileUploadOptions = function(fileKey, fileName, mimeType, params) {
+    this.fileKey = fileKey || null;
+    this.fileName = fileName || null;
+    this.mimeType = mimeType || null;
+    this.params = params || null;
+};
+
+module.exports = FileUploadOptions;
+});
+
+// file: lib/common/plugin/FileUploadResult.js
+define("cordova/plugin/FileUploadResult", function(require, exports, module) {
+/**
+ * FileUploadResult
+ * @constructor
+ */
+var FileUploadResult = function() {
+    this.bytesSent = 0;
+    this.responseCode = null;
+    this.response = null;
+};
+
+module.exports = FileUploadResult;
+});
+
+// file: lib/common/plugin/FileWriter.js
+define("cordova/plugin/FileWriter", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class writes to the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To write to the SD card, the file name is "sdcard/my_file.txt"
+ *
+ * @constructor
+ * @param file {File} File object containing file properties
+ * @param append if true write to the end of the file, otherwise overwrite the file
+ */
+var FileWriter = function(file) {
+    this.fileName = "";
+    this.length = 0;
+    if (file) {
+        this.fileName = file.fullPath || file;
+        this.length = file.size || 0;
+    }
+    // default is to write at the beginning of the file
+    this.position = 0;
+
+    this.readyState = 0; // EMPTY
+
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onwritestart = null;   // When writing starts
+    this.onprogress = null;     // While writing the file, and reporting partial file data
+    this.onwrite = null;        // When the write has successfully completed.
+    this.onwriteend = null;     // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.
+    this.onerror = null;        // When the write has failed (see errors).
+};
+
+// States
+FileWriter.INIT = 0;
+FileWriter.WRITING = 1;
+FileWriter.DONE = 2;
+
+/**
+ * Abort writing file.
+ */
+FileWriter.prototype.abort = function() {
+    // check for invalid state
+    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // set error
+    this.error = new FileError(FileError.ABORT_ERR);
+
+    this.readyState = FileWriter.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === "function") {
+        this.onabort(new ProgressEvent("abort", {"target":this}));
+    }
+
+    // If write end callback
+    if (typeof this.onwriteend === "function") {
+        this.onwriteend(new ProgressEvent("writeend", {"target":this}));
+    }
+};
+
+/**
+ * Writes data to the file
+ *
+ * @param text to be written
+ */
+FileWriter.prototype.write = function(text) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":me}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // position always increases by bytes written because file would be extended
+            me.position += r;
+            // The length of the file is now where we are done writing.
+
+            me.length = me.position;
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "write", [this.fileName, text, this.position]);
+};
+
+/**
+ * Moves the file pointer to the location specified.
+ *
+ * If the offset is a negative number the position of the file
+ * pointer is rewound.  If the offset is greater than the file
+ * size the position is set to the end of the file.
+ *
+ * @param offset is the location to move the file pointer to.
+ */
+FileWriter.prototype.seek = function(offset) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    if (!offset && offset !== 0) {
+        return;
+    }
+
+    // See back from end of file.
+    if (offset < 0) {
+        this.position = Math.max(offset + this.length, 0);
+    }
+    // Offset is bigger then file size so set position
+    // to the end of the file.
+    else if (offset > this.length) {
+        this.position = this.length;
+    }
+    // Offset is between 0 and file size so set the position
+    // to start writing.
+    else {
+        this.position = offset;
+    }
+};
+
+/**
+ * Truncates the file to the size specified.
+ *
+ * @param size to chop the file at.
+ */
+FileWriter.prototype.truncate = function(size) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":this}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Update the length of the file
+            me.length = r;
+            me.position = Math.min(me.position, r);
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "truncate", [this.fileName, size]);
+};
+
+module.exports = FileWriter;
+
+});
+
+// file: lib/common/plugin/Flags.js
+define("cordova/plugin/Flags", function(require, exports, module) {
+/**
+ * Supplies arguments to methods that lookup or create files and directories.
+ *
+ * @param create
+ *            {boolean} file or directory if it doesn't exist
+ * @param exclusive
+ *            {boolean} used with create; if true the command will fail if
+ *            target path exists
+ */
+function Flags(create, exclusive) {
+    this.create = create || false;
+    this.exclusive = exclusive || false;
+}
+
+module.exports = Flags;
+});
+
+// file: lib/common/plugin/LocalFileSystem.js
+define("cordova/plugin/LocalFileSystem", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+/**
+ * Represents a local file system.
+ */
+var LocalFileSystem = function() {
+
+};
+
+LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence
+LocalFileSystem.PERSISTENT = 1; //persistent
+
+module.exports = LocalFileSystem;
+});
+
+// file: lib/common/plugin/Media.js
+define("cordova/plugin/Media", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+var mediaObjects = {};
+
+/**
+ * This class provides access to the device media, interfaces to both sound and video
+ *
+ * @constructor
+ * @param src                   The file name or url to play
+ * @param successCallback       The callback to be called when the file is done playing or recording.
+ *                                  successCallback()
+ * @param errorCallback         The callback to be called if there is an error.
+ *                                  errorCallback(int errorCode) - OPTIONAL
+ * @param statusCallback        The callback to be called when media status has changed.
+ *                                  statusCallback(int statusCode) - OPTIONAL
+ */
+var Media = function(src, successCallback, errorCallback, statusCallback) {
+
+    // successCallback optional
+    if (successCallback && (typeof successCallback !== "function")) {
+        console.log("Media Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Media Error: errorCallback is not a function");
+        return;
+    }
+
+    // statusCallback optional
+    if (statusCallback && (typeof statusCallback !== "function")) {
+        console.log("Media Error: statusCallback is not a function");
+        return;
+    }
+
+    this.id = utils.createUUID();
+    mediaObjects[this.id] = this;
+    this.src = src;
+    this.successCallback = successCallback;
+    this.errorCallback = errorCallback;
+    this.statusCallback = statusCallback;
+    this._duration = -1;
+    this._position = -1;
+    exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
+};
+
+// Media messages
+Media.MEDIA_STATE = 1;
+Media.MEDIA_DURATION = 2;
+Media.MEDIA_POSITION = 3;
+Media.MEDIA_ERROR = 9;
+
+// Media states
+Media.MEDIA_NONE = 0;
+Media.MEDIA_STARTING = 1;
+Media.MEDIA_RUNNING = 2;
+Media.MEDIA_PAUSED = 3;
+Media.MEDIA_STOPPED = 4;
+Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
+
+// "static" function to return existing objs.
+Media.get = function(id) {
+    return mediaObjects[id];
+};
+
+/**
+ * Start or resume playing audio file.
+ */
+Media.prototype.play = function(options) {
+    exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
+};
+
+/**
+ * Stop playing audio file.
+ */
+Media.prototype.stop = function() {
+    var me = this;
+    exec(function() {
+        me._position = 0;
+        me.successCallback();
+    }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
+};
+
+/**
+ * Seek or jump to a new time in the track..
+ */
+Media.prototype.seekTo = function(milliseconds) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+    }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
+};
+
+/**
+ * Pause playing audio file.
+ */
+Media.prototype.pause = function() {
+    exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
+};
+
+/**
+ * Get duration of an audio file.
+ * The duration is only set for audio that is playing, paused or stopped.
+ *
+ * @return      duration or -1 if not known.
+ */
+Media.prototype.getDuration = function() {
+    return this._duration;
+};
+
+/**
+ * Get position of audio.
+ */
+Media.prototype.getCurrentPosition = function(success, fail) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+        success(p);
+    }, fail, "Media", "getCurrentPositionAudio", [this.id]);
+};
+
+/**
+ * Start recording audio file.
+ */
+Media.prototype.startRecord = function() {
+    exec(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
+};
+
+/**
+ * Stop recording audio file.
+ */
+Media.prototype.stopRecord = function() {
+    exec(this.successCallback, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
+};
+
+/**
+ * Release the resources.
+ */
+Media.prototype.release = function() {
+    exec(null, this.errorCallback, "Media", "release", [this.id]);
+};
+
+/**
+ * Adjust the volume.
+ */
+Media.prototype.setVolume = function(volume) {
+    exec(null, null, "Media", "setVolume", [this.id, volume]);
+};
+
+/**
+ * Audio has status update.
+ * PRIVATE
+ *
+ * @param id            The media object id (string)
+ * @param status        The status code (int)
+ * @param msg           The status message (string)
+ */
+Media.onStatus = function(id, msg, value) {
+    var media = mediaObjects[id];
+    // If state update
+    if (msg === Media.MEDIA_STATE) {
+        if (value === Media.MEDIA_STOPPED) {
+            if (media.successCallback) {
+                media.successCallback();
+            }
+        }
+        if (media.statusCallback) {
+            media.statusCallback(value);
+        }
+    }
+    else if (msg === Media.MEDIA_DURATION) {
+        media._duration = value;
+    }
+    else if (msg === Media.MEDIA_ERROR) {
+        if (media.errorCallback) {
+            // value should be a MediaError object when msg == MEDIA_ERROR
+            media.errorCallback(value);
+        }
+    }
+    else if (msg === Media.MEDIA_POSITION) {
+        media._position = value;
+    }
+};
+
+module.exports = Media;
+});
+
+// file: lib/common/plugin/MediaError.js
+define("cordova/plugin/MediaError", function(require, exports, module) {
+/**
+ * This class contains information about any Media errors.
+ * @constructor
+ */
+var MediaError = function(code, msg) {
+    this.code = (code !== undefined ? code : null);
+    this.message = msg || "";
+};
+
+MediaError.MEDIA_ERR_NONE_ACTIVE    = 0;
+MediaError.MEDIA_ERR_ABORTED        = 1;
+MediaError.MEDIA_ERR_NETWORK        = 2;
+MediaError.MEDIA_ERR_DECODE         = 3;
+MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
+
+module.exports = MediaError;
+});
+
+// file: lib/common/plugin/MediaFile.js
+define("cordova/plugin/MediaFile", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    File = require('cordova/plugin/File'),
+    CaptureError = require('cordova/plugin/CaptureError');
+/**
+ * Represents a single file.
+ *
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+var MediaFile = function(name, fullPath, type, lastModifiedDate, size){
+    MediaFile.__super__.constructor.apply(this, arguments);
+};
+
+utils.extend(MediaFile, File);
+
+/**
+ * Request capture format data for a specific file and type
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ */
+MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
+    if (typeof this.fullPath === "undefined" || this.fullPath === null) {
+        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));
+    } else {
+        exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);
+    }
+};
+
+// TODO: can we axe this?
+/**
+ * Casts a PluginResult message property  (array of objects) to an array of MediaFile objects
+ * (used in Objective-C and Android)
+ *
+ * @param {PluginResult} pluginResult
+ */
+MediaFile.cast = function(pluginResult) {
+    var mediaFiles = [];
+    for (var i=0; i<pluginResult.message.length; i++) {
+        var mediaFile = new MediaFile();
+        mediaFile.name = pluginResult.message[i].name;
+        mediaFile.fullPath = pluginResult.message[i].fullPath;
+        mediaFile.type = pluginResult.message[i].type;
+        mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate;
+        mediaFile.size = pluginResult.message[i].size;
+        mediaFiles.push(mediaFile);
+    }
+    pluginResult.message = mediaFiles;
+    return pluginResult;
+};
+
+module.exports = MediaFile;
+
+});
+
+// file: lib/common/plugin/MediaFileData.js
+define("cordova/plugin/MediaFileData", function(require, exports, module) {
+/**
+ * MediaFileData encapsulates format information of a media file.
+ *
+ * @param {DOMString} codecs
+ * @param {long} bitrate
+ * @param {long} height
+ * @param {long} width
+ * @param {float} duration
+ */
+var MediaFileData = function(codecs, bitrate, height, width, duration){
+    this.codecs = codecs || null;
+    this.bitrate = bitrate || 0;
+    this.height = height || 0;
+    this.width = width || 0;
+    this.duration = duration || 0;
+};
+
+module.exports = MediaFileData;
+});
+
+// file: lib/common/plugin/Metadata.js
+define("cordova/plugin/Metadata", function(require, exports, module) {
+/**
+ * Information about the state of the file or directory
+ *
+ * {Date} modificationTime (readonly)
+ */
+var Metadata = function(time) {
+    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);
+};
+
+module.exports = Metadata;
+});
+
+// file: lib/common/plugin/Position.js
+define("cordova/plugin/Position", function(require, exports, module) {
+var Coordinates = require('cordova/plugin/Coordinates');
+
+var Position = function(coords, timestamp) {
+    if (coords) {
+        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);
+    } else {
+        this.coords = new Coordinates();
+    }
+    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();
+};
+
+module.exports = Position;
+
+});
+
+// file: lib/common/plugin/PositionError.js
+define("cordova/plugin/PositionError", function(require, exports, module) {
+/**
+ * Position error object
+ *
+ * @constructor
+ * @param code
+ * @param message
+ */
+var PositionError = function(code, message) {
+    this.code = code || null;
+    this.message = message || '';
+};
+
+PositionError.PERMISSION_DENIED = 1;
+PositionError.POSITION_UNAVAILABLE = 2;
+PositionError.TIMEOUT = 3;
+
+module.exports = PositionError;
+});
+
+// file: lib/common/plugin/ProgressEvent.js
+define("cordova/plugin/ProgressEvent", function(require, exports, module) {
+// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill
+// Feature test: See if we can instantiate a native ProgressEvent;
+// if so, use that approach,
+// otherwise fill-in with our own implementation.
+//
+// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.
+var ProgressEvent = (function() {
+    /*
+    var createEvent = function(data) {
+        var event = document.createEvent('Events');
+        event.initEvent('ProgressEvent', false, false);
+        if (data) {
+            for (var i in data) {
+                if (data.hasOwnProperty(i)) {
+                    event[i] = data[i];
+                }
+            }
+            if (data.target) {
+                // TODO: cannot call <some_custom_object>.dispatchEvent
+                // need to first figure out how to implement EventTarget
+            }
+        }
+        return event;
+    };
+    try {
+        var ev = createEvent({type:"abort",target:document});
+        return function ProgressEvent(type, data) {
+            data.type = type;
+            return createEvent(data);
+        };
+    } catch(e){
+    */
+        return function ProgressEvent(type, dict) {
+            this.type = type;
+            this.bubbles = false;
+            this.cancelBubble = false;
+            this.cancelable = false;
+            this.lengthComputable = false;
+            this.loaded = dict && dict.loaded ? dict.loaded : 0;
+            this.total = dict && dict.total ? dict.total : 0;
+            this.target = dict && dict.target ? dict.target : null;
+        };
+    //}
+})();
+
+module.exports = ProgressEvent;
+});
+
+// file: lib/common/plugin/accelerometer.js
+define("cordova/plugin/accelerometer", function(require, exports, module) {
+/**
+ * This class provides access to device accelerometer data.
+ * @constructor
+ */
+var utils = require("cordova/utils"),
+    exec = require("cordova/exec"),
+    Acceleration = require('cordova/plugin/Acceleration');
+
+// Is the accel sensor running?
+var running = false;
+
+// Keeps reference to watchAcceleration calls.
+var timers = {};
+
+// Array of listeners; used to keep track of when we should call start and stop.
+var listeners = [];
+
+// Last returned acceleration object from native
+var accel = null;
+
+// Tells native to start.
+function start() {
+    exec(function(a) {
+        var tempListeners = listeners.slice(0);
+        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].win(accel);
+        }
+    }, function(e) {
+        var tempListeners = listeners.slice(0);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].fail(e);
+        }
+    }, "Accelerometer", "start", []);
+    running = true;
+}
+
+// Tells native to stop.
+function stop() {
+    exec(null, null, "Accelerometer", "stop", []);
+    running = false;
+}
+
+// Adds a callback pair to the listeners array
+function createCallbackPair(win, fail) {
+    return {win:win, fail:fail};
+}
+
+// Removes a win/fail listener pair from the listeners array
+function removeListeners(l) {
+    var idx = listeners.indexOf(l);
+    if (idx > -1) {
+        listeners.splice(idx, 1);
+        if (listeners.length === 0) {
+            stop();
+        }
+    }
+}
+
+var accelerometer = {
+    /**
+     * Asynchronously aquires the current acceleration.
+     *
+     * @param {Function} successCallback    The function to call when the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     */
+    getCurrentAcceleration: function(successCallback, errorCallback, options) {
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "getCurrentAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        var p;
+        var win = function(a) {
+            removeListeners(p);
+            successCallback(a);
+        };
+        var fail = function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        };
+
+        p = createCallbackPair(win, fail);
+        listeners.push(p);
+
+        if (!running) {
+            start();
+        }
+    },
+
+    /**
+     * Asynchronously aquires the acceleration repeatedly at a given interval.
+     *
+     * @param {Function} successCallback    The function to call each time the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchAcceleration: function(successCallback, errorCallback, options) {
+        // Default interval (10 sec)
+        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;
+
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "watchAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        // Keep reference to watch id, and report accel readings as often as defined in frequency
+        var id = utils.createUUID();
+
+        var p = createCallbackPair(function(){}, function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        });
+        listeners.push(p);
+
+        timers[id] = {
+            timer:window.setInterval(function() {
+                if (accel) {
+                    successCallback(accel);
+                }
+            }, frequency),
+            listeners:p
+        };
+
+        if (running) {
+            // If we're already running then immediately invoke the success callback
+            // but only if we have retreived a value, sample code does not check for null ...
+            if(accel) {
+                successCallback(accel);
+            }
+        } else {
+            start();
+        }
+
+        return id;
+    },
+
+    /**
+     * Clears the specified accelerometer watch.
+     *
+     * @param {String} id       The id of the watch returned from #watchAcceleration.
+     */
+    clearWatch: function(id) {
+        // Stop javascript timer & remove from timer list
+        if (id && timers[id]) {
+            window.clearInterval(timers[id].timer);
+            removeListeners(timers[id].listeners);
+            delete timers[id];
+        }
+    }
+};
+
+module.exports = accelerometer;
+
+});
+
+// file: lib/common/plugin/battery.js
+define("cordova/plugin/battery", function(require, exports, module) {
+/**
+ * This class contains information about the current battery status.
+ * @constructor
+ */
+var cordova = require('cordova'),
+    exec = require('cordova/exec');
+
+function handlers() {
+  return battery.channels.batterystatus.numHandlers +
+         battery.channels.batterylow.numHandlers +
+         battery.channels.batterycritical.numHandlers;
+}
+
+var Battery = function() {
+    this._level = null;
+    this._isPlugged = null;
+    // Create new event handlers on the window (returns a channel instance)
+    var subscriptionEvents = {
+      onSubscribe:this.onSubscribe,
+      onUnsubscribe:this.onUnsubscribe
+    };
+    this.channels = {
+      batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents),
+      batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents),
+      batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents)
+    };
+};
+/**
+ * Event handlers for when callbacks get registered for the battery.
+ * Keep track of how many handlers we have so we can start and stop the native battery listener
+ * appropriately (and hopefully save on battery life!).
+ */
+Battery.prototype.onSubscribe = function() {
+  var me = battery;
+  // If we just registered the first handler, make sure native listener is started.
+  if (handlers() === 1) {
+    exec(me._status, me._error, "Battery", "start", []);
+  }
+};
+
+Battery.prototype.onUnsubscribe = function() {
+  var me = battery;
+
+  // If we just unregistered the last handler, make sure native listener is stopped.
+  if (handlers() === 0) {
+      exec(null, null, "Battery", "stop", []);
+  }
+};
+
+/**
+ * Callback for battery status
+ *
+ * @param {Object} info            keys: level, isPlugged
+ */
+Battery.prototype._status = function(info) {
+    if (info) {
+        var me = battery;
+    var level = info.level;
+        if (me._level !== level || me._isPlugged !== info.isPlugged) {
+            // Fire batterystatus event
+            cordova.fireWindowEvent("batterystatus", info);
+
+            // Fire low battery event
+            if (level === 20 || level === 5) {
+                if (level === 20) {
+                    cordova.fireWindowEvent("batterylow", info);
+                }
+                else {
+                    cordova.fireWindowEvent("batterycritical", info);
+                }
+            }
+        }
+        me._level = level;
+        me._isPlugged = info.isPlugged;
+    }
+};
+
+/**
+ * Error callback for battery start
+ */
+Battery.prototype._error = function(e) {
+    console.log("Error initializing Battery: " + e);
+};
+
+var battery = new Battery();
+
+module.exports = battery;
+});
+
+// file: lib/common/plugin/capture.js
+define("cordova/plugin/capture", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    MediaFile = require('cordova/plugin/MediaFile');
+
+/**
+ * Launches a capture of different types.
+ *
+ * @param (DOMString} type
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+function _capture(type, successCallback, errorCallback, options) {
+    var win = function(pluginResult) {
+        var mediaFiles = [];
+        var i;
+        for (i = 0; i < pluginResult.length; i++) {
+            var mediaFile = new MediaFile();
+            mediaFile.name = pluginResult[i].name;
+            mediaFile.fullPath = pluginResult[i].fullPath;
+            mediaFile.type = pluginResult[i].type;
+            mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;
+            mediaFile.size = pluginResult[i].size;
+            mediaFiles.push(mediaFile);
+        }
+        successCallback(mediaFiles);
+    };
+    exec(win, errorCallback, "Capture", type, [options]);
+}
+/**
+ * The Capture interface exposes an interface to the camera and microphone of the hosting device.
+ */
+function Capture() {
+    this.supportedAudioModes = [];
+    this.supportedImageModes = [];
+    this.supportedVideoModes = [];
+}
+
+/**
+ * Launch audio recorder application for recording audio clip(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureAudioOptions} options
+ */
+Capture.prototype.captureAudio = function(successCallback, errorCallback, options){
+    _capture("captureAudio", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch camera application for taking image(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureImageOptions} options
+ */
+Capture.prototype.captureImage = function(successCallback, errorCallback, options){
+    _capture("captureImage", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch device camera application for recording video(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+Capture.prototype.captureVideo = function(successCallback, errorCallback, options){
+    _capture("captureVideo", successCallback, errorCallback, options);
+};
+
+
+module.exports = new Capture();
+
+});
+
+// file: lib/common/plugin/compass.js
+define("cordova/plugin/compass", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    utils = require('cordova/utils'),
+    CompassHeading = require('cordova/plugin/CompassHeading'),
+    CompassError = require('cordova/plugin/CompassError'),
+    timers = {},
+    compass = {
+        /**
+         * Asynchronously acquires the current heading.
+         * @param {Function} successCallback The function to call when the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {CompassOptions} options The options for getting the heading data (not used).
+         */
+        getCurrentHeading:function(successCallback, errorCallback, options) {
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var win = function(result) {
+                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);
+                successCallback(ch);
+            };
+            var fail = function(code) {
+                var ce = new CompassError(code);
+                errorCallback(ce);
+            };
+
+            // Get heading
+            exec(win, fail, "Compass", "getHeading", [options]);
+        },
+
+        /**
+         * Asynchronously acquires the heading repeatedly at a given interval.
+         * @param {Function} successCallback The function to call each time the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {HeadingOptions} options The options for getting the heading data
+         * such as timeout and the frequency of the watch. For iOS, filter parameter
+         * specifies to watch via a distance filter rather than time.
+         */
+        watchHeading:function(successCallback, errorCallback, options) {
+            // Default interval (100 msec)
+            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;
+            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;
+
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var id = utils.createUUID();
+            if (filter > 0) {
+                // is an iOS request for watch by filter, no timer needed
+                timers[id] = "iOS";
+                compass.getCurrentHeading(successCallback, errorCallback, options);
+            } else {
+                // Start watch timer to get headings
+                timers[id] = window.setInterval(function() {
+                    compass.getCurrentHeading(successCallback, errorCallback);
+                }, frequency);
+            }
+
+            return id;
+        },
+
+        /**
+         * Clears the specified heading watch.
+         * @param {String} watchId The ID of the watch returned from #watchHeading.
+         */
+        clearWatch:function(id) {
+            // Stop javascript timer & remove from timer list
+            if (id && timers[id]) {
+                if (timers[id] != "iOS") {
+                      clearInterval(timers[id]);
+                  } else {
+                    // is iOS watch by filter so call into device to stop
+                    exec(null, null, "Compass", "stopHeading", []);
+                }
+                delete timers[id];
+            }
+        }
+    };
+
+module.exports = compass;
+});
+
+// file: lib/common/plugin/console-via-logger.js
+define("cordova/plugin/console-via-logger", function(require, exports, module) {
+//------------------------------------------------------------------------------
+
+var logger = require("cordova/plugin/logger");
+var utils  = require("cordova/utils");
+
+//------------------------------------------------------------------------------
+// object that we're exporting
+//------------------------------------------------------------------------------
+var console = module.exports;
+
+//------------------------------------------------------------------------------
+// copy of the original console object
+//------------------------------------------------------------------------------
+var WinConsole = window.console;
+
+//------------------------------------------------------------------------------
+// whether to use the logger
+//------------------------------------------------------------------------------
+var UseLogger = false;
+
+//------------------------------------------------------------------------------
+// Timers
+//------------------------------------------------------------------------------
+var Timers = {};
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+function noop() {}
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+console.useLogger = function (value) {
+    if (arguments.length) UseLogger = !!value;
+
+    if (UseLogger) {
+        if (logger.useConsole()) {
+            throw new Error("console and logger are too intertwingly");
+        }
+    }
+
+    return UseLogger;
+};
+
+//------------------------------------------------------------------------------
+console.log = function() {
+    if (logger.useConsole()) return;
+    logger.log.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.error = function() {
+    if (logger.useConsole()) return;
+    logger.error.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.warn = function() {
+    if (logger.useConsole()) return;
+    logger.warn.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.info = function() {
+    if (logger.useConsole()) return;
+    logger.info.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.debug = function() {
+    if (logger.useConsole()) return;
+    logger.debug.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.assert = function(expression) {
+    if (expression) return;
+
+    var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));
+    console.log("ASSERT: " + message);
+};
+
+//------------------------------------------------------------------------------
+console.clear = function() {};
+
+//------------------------------------------------------------------------------
+console.dir = function(object) {
+    console.log("%o", object);
+};
+
+//------------------------------------------------------------------------------
+console.dirxml = function(node) {
+    console.log(node.innerHTML);
+};
+
+//------------------------------------------------------------------------------
+console.trace = noop;
+
+//------------------------------------------------------------------------------
+console.group = console.log;
+
+//------------------------------------------------------------------------------
+console.groupCollapsed = console.log;
+
+//------------------------------------------------------------------------------
+console.groupEnd = noop;
+
+//------------------------------------------------------------------------------
+console.time = function(name) {
+    Timers[name] = new Date().valueOf();
+};
+
+//------------------------------------------------------------------------------
+console.timeEnd = function(name) {
+    var timeStart = Timers[name];
+    if (!timeStart) {
+        console.warn("unknown timer: " + name);
+        return;
+    }
+
+    var timeElapsed = new Date().valueOf() - timeStart;
+    console.log(name + ": " + timeElapsed + "ms");
+};
+
+//------------------------------------------------------------------------------
+console.timeStamp = noop;
+
+//------------------------------------------------------------------------------
+console.profile = noop;
+
+//------------------------------------------------------------------------------
+console.profileEnd = noop;
+
+//------------------------------------------------------------------------------
+console.count = noop;
+
+//------------------------------------------------------------------------------
+console.exception = console.log;
+
+//------------------------------------------------------------------------------
+console.table = function(data, columns) {
+    console.log("%o", data);
+};
+
+//------------------------------------------------------------------------------
+// return a new function that calls both functions passed as args
+//------------------------------------------------------------------------------
+function wrapperedOrigCall(orgFunc, newFunc) {
+    return function() {
+        var args = [].slice.call(arguments);
+        try { orgFunc.apply(WinConsole, args); } catch (e) {}
+        try { newFunc.apply(console,    args); } catch (e) {}
+    };
+}
+
+//------------------------------------------------------------------------------
+// For every function that exists in the original console object, that
+// also exists in the new console object, wrap the new console method
+// with one that calls both
+//------------------------------------------------------------------------------
+for (var key in console) {
+    if (typeof WinConsole[key] == "function") {
+        console[key] = wrapperedOrigCall(WinConsole[key], console[key]);
+    }
+}
+
+});
+
+// file: lib/common/plugin/contacts.js
+define("cordova/plugin/contacts", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+* Represents a group of Contacts.
+* @constructor
+*/
+var contacts = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     * @param fields that should be searched
+     * @param successCB success callback
+     * @param errorCB error callback
+     * @param {ContactFindOptions} options that can be applied to contact searching
+     * @return array of Contacts matching search criteria
+     */
+    find:function(fields, successCB, errorCB, options) {
+        if (!successCB) {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+        if (!fields || (utils.isArray(fields) && fields.length === 0)) {
+            if (typeof errorCB === "function") {
+                errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+        } else {
+            var win = function(result) {
+                var cs = [];
+                for (var i = 0, l = result.length; i < l; i++) {
+                    cs.push(contacts.create(result[i]));
+                }
+                successCB(cs);
+            };
+            exec(win, errorCB, "Contacts", "search", [fields, options]);
+        }
+    },
+
+    /**
+     * This function creates a new contact, but it does not persist the contact
+     * to device storage. To persist the contact to device storage, invoke
+     * contact.save().
+     * @param properties an object who's properties will be examined to create a new Contact
+     * @returns new Contact object
+     */
+    create:function(properties) {
+        var i;
+        var contact = new Contact();
+        for (i in properties) {
+            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {
+                contact[i] = properties[i];
+            }
+        }
+        return contact;
+    }
+};
+
+module.exports = contacts;
+
+});
+
+// file: lib/common/plugin/device.js
+define("cordova/plugin/device", function(require, exports, module) {
+var channel = require('cordova/channel'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+/**
+ * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+function Device() {
+    this.available = false;
+    this.platform = null;
+    this.version = null;
+    this.name = null;
+    this.uuid = null;
+    this.cordova = null;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getInfo(function(info) {
+            me.available = true;
+            me.platform = info.platform;
+            me.version = info.version;
+            me.name = info.name;
+            me.uuid = info.uuid;
+            me.cordova = info.cordova;
+            channel.onCordovaInfoReady.fire();
+        },function(e) {
+            me.available = false;
+            utils.alert("[ERROR] Error initializing Cordova: " + e);
+        });
+    });
+}
+
+/**
+ * Get device info
+ *
+ * @param {Function} successCallback The function to call when the heading data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
+ */
+Device.prototype.getInfo = function(successCallback, errorCallback) {
+
+    // successCallback required
+    if (typeof successCallback !== "function") {
+        console.log("Device Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Device Error: errorCallback is not a function");
+        return;
+    }
+
+    // Get info
+    exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
+};
+
+module.exports = new Device();
+
+});
+
+// file: lib/common/plugin/geolocation.js
+define("cordova/plugin/geolocation", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    PositionError = require('cordova/plugin/PositionError'),
+    Position = require('cordova/plugin/Position');
+
+var timers = {};   // list of timers in use
+
+// Returns default params, overrides if provided with values
+function parseParameters(options) {
+    var opt = {
+        maximumAge: 0,
+        enableHighAccuracy: false,
+        timeout: Infinity
+    };
+
+    if (options) {
+        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {
+            opt.maximumAge = options.maximumAge;
+        }
+        if (options.enableHighAccuracy !== undefined) {
+            opt.enableHighAccuracy = options.enableHighAccuracy;
+        }
+        if (options.timeout !== undefined && !isNaN(options.timeout)) {
+            if (options.timeout < 0) {
+                opt.timeout = 0;
+            } else {
+                opt.timeout = options.timeout;
+            }
+        }
+    }
+
+    return opt;
+}
+
+// Returns a timeout failure, closed over a specified timeout value and error callback.
+function createTimeout(errorCallback, timeout) {
+    var t = setTimeout(function() {
+        clearTimeout(t);
+        t = null;
+        errorCallback({
+            code:PositionError.TIMEOUT,
+            message:"Position retrieval timed out."
+        });
+    }, timeout);
+    return t;
+}
+
+var geolocation = {
+    lastPosition:null, // reference to last known (cached) position returned
+    /**
+   * Asynchronously aquires the current position.
+   *
+   * @param {Function} successCallback    The function to call when the position data is available
+   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)
+   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)
+   */
+    getCurrentPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("getCurrentPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        // Timer var that will fire an error callback if no position is retrieved from native
+        // before the "timeout" param provided expires
+        var timeoutTimer = null;
+
+        var win = function(p) {
+            clearTimeout(timeoutTimer);
+            if (!timeoutTimer) {
+                // Timeout already happened, or native fired error callback for
+                // this geo request.
+                // Don't continue with success callback.
+                return;
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+        var fail = function(e) {
+            clearTimeout(timeoutTimer);
+            timeoutTimer = null;
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just
+        // fire the success callback with the cached position.
+        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {
+            successCallback(geolocation.lastPosition);
+        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.
+        } else if (options.timeout === 0) {
+            fail({
+                code:PositionError.TIMEOUT,
+                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter."
+            });
+        // Otherwise we have to call into native to retrieve a position.
+        } else {
+            if (options.timeout !== Infinity) {
+                // If the timeout value was not set to Infinity (default), then
+                // set up a timeout function that will fire the error callback
+                // if no successful position was retrieved before timeout expired.
+                timeoutTimer = createTimeout(fail, options.timeout);
+            } else {
+                // This is here so the check in the win function doesn't mess stuff up
+                // may seem weird but this guarantees timeoutTimer is
+                // always truthy before we call into native
+                timeoutTimer = true;
+            }
+            exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);
+        }
+        return timeoutTimer;
+    },
+    /**
+     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,
+     * the successCallback is called with the new location.
+     *
+     * @param {Function} successCallback    The function to call each time the location data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)
+     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("watchPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        var id = utils.createUUID();
+
+        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition
+        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);
+
+        var fail = function(e) {
+            clearTimeout(timers[id]);
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        var win = function(p) {
+            clearTimeout(timers[id]);
+            if (options.timeout !== Infinity) {
+                timers[id] = createTimeout(fail, options.timeout);
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+
+        exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);
+
+        return id;
+    },
+    /**
+     * Clears the specified heading watch.
+     *
+     * @param {String} id       The ID of the watch returned from #watchPosition
+     */
+    clearWatch:function(id) {
+        if (id && timers[id] !== undefined) {
+            clearTimeout(timers[id]);
+            delete timers[id];
+            exec(null, null, "Geolocation", "clearWatch", [id]);
+        }
+    }
+};
+
+module.exports = geolocation;
+
+});
+
+// file: lib/common/plugin/logger.js
+define("cordova/plugin/logger", function(require, exports, module) {
+//------------------------------------------------------------------------------
+// The logger module exports the following properties/functions:
+//
+// LOG                          - constant for the level LOG
+// ERROR                        - constant for the level ERROR
+// WARN                         - constant for the level WARN
+// INFO                         - constant for the level INFO
+// DEBUG                        - constant for the level DEBUG
+// logLevel()                   - returns current log level
+// logLevel(value)              - sets and returns a new log level
+// useConsole()                 - returns whether logger is using console
+// useConsole(value)            - sets and returns whether logger is using console
+// log(message,...)             - logs a message at level LOG
+// error(message,...)           - logs a message at level ERROR
+// warn(message,...)            - logs a message at level WARN
+// info(message,...)            - logs a message at level INFO
+// debug(message,...)           - logs a message at level DEBUG
+// logLevel(level,message,...)  - logs a message specified level
+//
+//------------------------------------------------------------------------------
+
+var logger = exports;
+
+var exec    = require('cordova/exec');
+var utils   = require('cordova/utils');
+
+var UseConsole   = true;
+var Queued       = [];
+var DeviceReady  = false;
+var CurrentLevel;
+
+/**
+ * Logging levels
+ */
+
+var Levels = [
+    "LOG",
+    "ERROR",
+    "WARN",
+    "INFO",
+    "DEBUG"
+];
+
+/*
+ * add the logging levels to the logger object and
+ * to a separate levelsMap object for testing
+ */
+
+var LevelsMap = {};
+for (var i=0; i<Levels.length; i++) {
+    var level = Levels[i];
+    LevelsMap[level] = i;
+    logger[level]    = level;
+}
+
+CurrentLevel = LevelsMap.WARN;
+
+/**
+ * Getter/Setter for the logging level
+ *
+ * Returns the current logging level.
+ *
+ * When a value is passed, sets the logging level to that value.
+ * The values should be one of the following constants:
+ *    logger.LOG
+ *    logger.ERROR
+ *    logger.WARN
+ *    logger.INFO
+ *    logger.DEBUG
+ *
+ * The value used determines which messages get printed.  The logging
+ * values above are in order, and only messages logged at the logging
+ * level or above will actually be displayed to the user.  Eg, the
+ * default level is WARN, so only messages logged with LOG, ERROR, or
+ * WARN will be displayed; INFO and DEBUG messages will be ignored.
+ */
+logger.level = function (value) {
+    if (arguments.length) {
+        if (LevelsMap[value] === null) {
+            throw new Error("invalid logging level: " + value);
+        }
+        CurrentLevel = LevelsMap[value];
+    }
+
+    return Levels[CurrentLevel];
+};
+
+/**
+ * Getter/Setter for the useConsole functionality
+ *
+ * When useConsole is true, the logger will log via the
+ * browser 'console' object.  Otherwise, it will use the
+ * native Logger plugin.
+ */
+logger.useConsole = function (value) {
+    if (arguments.length) UseConsole = !!value;
+
+    if (UseConsole) {
+        if (typeof console == "undefined") {
+            throw new Error("global console object is not defined");
+        }
+
+        if (typeof console.log != "function") {
+            throw new Error("global console object does not have a log function");
+        }
+
+        if (typeof console.useLogger == "function") {
+            if (console.useLogger()) {
+                throw new Error("console and logger are too intertwingly");
+            }
+        }
+    }
+
+    return UseConsole;
+};
+
+/**
+ * Logs a message at the LOG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.log   = function(message) { logWithArgs("LOG",   arguments); };
+
+/**
+ * Logs a message at the ERROR level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.error = function(message) { logWithArgs("ERROR", arguments); };
+
+/**
+ * Logs a message at the WARN level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.warn  = function(message) { logWithArgs("WARN",  arguments); };
+
+/**
+ * Logs a message at the INFO level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.info  = function(message) { logWithArgs("INFO",  arguments); };
+
+/**
+ * Logs a message at the DEBUG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.debug = function(message) { logWithArgs("DEBUG", arguments); };
+
+// log at the specified level with args
+function logWithArgs(level, args) {
+    args = [level].concat([].slice.call(args));
+    logger.logLevel.apply(logger, args);
+}
+
+/**
+ * Logs a message at the specified level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.logLevel = function(level, message /* , ... */) {
+    // format the message with the parameters
+    var formatArgs = [].slice.call(arguments, 2);
+    message    = utils.vformat(message, formatArgs);
+
+    if (LevelsMap[level] === null) {
+        throw new Error("invalid logging level: " + level);
+    }
+
+    if (LevelsMap[level] > CurrentLevel) return;
+
+    // queue the message if not yet at deviceready
+    if (!DeviceReady && !UseConsole) {
+        Queued.push([level, message]);
+        return;
+    }
+
+    // if not using the console, use the native logger
+    if (!UseConsole) {
+        exec(null, null, "Logger", "logLevel", [level, message]);
+        return;
+    }
+
+    // make sure console is not using logger
+    if (console.__usingCordovaLogger) {
+        throw new Error("console and logger are too intertwingly");
+    }
+
+    // log to the console
+    switch (level) {
+        case logger.LOG:   console.log(message); break;
+        case logger.ERROR: console.log("ERROR: " + message); break;
+        case logger.WARN:  console.log("WARN: "  + message); break;
+        case logger.INFO:  console.log("INFO: "  + message); break;
+        case logger.DEBUG: console.log("DEBUG: " + message); break;
+    }
+};
+
+// when deviceready fires, log queued messages
+logger.__onDeviceReady = function() {
+    if (DeviceReady) return;
+
+    DeviceReady = true;
+
+    for (var i=0; i<Queued.length; i++) {
+        var messageArgs = Queued[i];
+        logger.logLevel(messageArgs[0], messageArgs[1]);
+    }
+
+    Queued = null;
+};
+
+// add a deviceready event to log queued messages
+document.addEventListener("deviceready", logger.__onDeviceReady, false);
+
+});
+
+// file: lib/common/plugin/network.js
+define("cordova/plugin/network", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    cordova = require('cordova'),
+    channel = require('cordova/channel');
+
+var NetworkConnection = function () {
+    this.type = null;
+    this._firstRun = true;
+    this._timer = null;
+    this.timeout = 500;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getInfo(function (info) {
+            me.type = info;
+            if (info === "none") {
+                // set a timer if still offline at the end of timer send the offline event
+                me._timer = setTimeout(function(){
+                    cordova.fireDocumentEvent("offline");
+                    me._timer = null;
+                    }, me.timeout);
+            } else {
+                // If there is a current offline event pending clear it
+                if (me._timer !== null) {
+                    clearTimeout(me._timer);
+                    me._timer = null;
+                }
+                cordova.fireDocumentEvent("online");
+            }
+
+            // should only fire this once
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+        },
+        function (e) {
+            // If we can't get the network info we should still tell Cordova
+            // to fire the deviceready event.
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+            console.log("Error initializing Network Connection: " + e);
+        });
+    });
+};
+
+/**
+ * Get connection info
+ *
+ * @param {Function} successCallback The function to call when the Connection data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)
+ */
+NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) {
+    // Get info
+    exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []);
+};
+
+module.exports = new NetworkConnection();
+});
+
+// file: lib/common/plugin/notification.js
+define("cordova/plugin/notification", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+/**
+ * Provides access to notifications on the device.
+ */
+
+module.exports = {
+
+    /**
+     * Open a native alert dialog, with a customizable title and button text.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} completeCallback   The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Alert)
+     * @param {String} buttonLabel          Label of the close button (default: OK)
+     */
+    alert: function(message, completeCallback, title, buttonLabel) {
+        var _title = (title || "Alert");
+        var _buttonLabel = (buttonLabel || "OK");
+        exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]);
+    },
+
+    /**
+     * Open a native confirm dialog, with a customizable title and button text.
+     * The result that the user selects is returned to the result callback.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Confirm)
+     * @param {String} buttonLabels         Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+     */
+    confirm: function(message, resultCallback, title, buttonLabels) {
+        var _title = (title || "Confirm");
+        var _buttonLabels = (buttonLabels || "OK,Cancel");
+        exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
+    },
+
+    /**
+     * Causes the device to vibrate.
+     *
+     * @param {Integer} mills       The number of milliseconds to vibrate for.
+     */
+    vibrate: function(mills) {
+        exec(null, null, "Notification", "vibrate", [mills]);
+    },
+
+    /**
+     * Causes the device to beep.
+     * On Android, the default notification ringtone is played "count" times.
+     *
+     * @param {Integer} count       The number of beeps.
+     */
+    beep: function(count) {
+        exec(null, null, "Notification", "beep", [count]);
+    }
+};
+});
+
+// file: lib/common/plugin/requestFileSystem.js
+define("cordova/plugin/requestFileSystem", function(require, exports, module) {
+var FileError = require('cordova/plugin/FileError'),
+    FileSystem = require('cordova/plugin/FileSystem'),
+    exec = require('cordova/exec');
+
+/**
+ * Request a file system in which to store application data.
+ * @param type  local file system type
+ * @param size  indicates how much storage space, in bytes, the application expects to need
+ * @param successCallback  invoked with a FileSystem object
+ * @param errorCallback  invoked if error occurs retrieving file system
+ */
+var requestFileSystem = function(type, size, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    if (type < 0 || type > 3) {
+        fail(FileError.SYNTAX_ERR);
+    } else {
+        // if successful, return a FileSystem object
+        var success = function(file_system) {
+            if (file_system) {
+                if (typeof successCallback === 'function') {
+                    // grab the name and root from the file system object
+                    var result = new FileSystem(file_system.name, file_system.root);
+                    successCallback(result);
+                }
+            }
+            else {
+                // no FileSystem object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+        exec(success, fail, "File", "requestFileSystem", [type, size]);
+    }
+};
+
+module.exports = requestFileSystem;
+});
+
+// file: lib/common/plugin/resolveLocalFileSystemURI.js
+define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) {
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    FileError = require('cordova/plugin/FileError'),
+    exec = require('cordova/exec');
+
+/**
+ * Look up file system Entry referred to by local URI.
+ * @param {DOMString} uri  URI referring to a local file or directory
+ * @param successCallback  invoked with Entry object corresponding to URI
+ * @param errorCallback    invoked if error occurs retrieving file system entry
+ */
+module.exports = function(uri, successCallback, errorCallback) {
+    // error callback
+    var fail = function(error) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(error));
+        }
+    };
+    // sanity check for 'not:valid:filename'
+    if(!uri || uri.split(":").length > 2) {
+        setTimeout( function() {
+            fail(FileError.ENCODING_ERR);
+        },0);
+        return;
+    }
+    // if successful, return either a file or directory entry
+    var success = function(entry) {
+        var result;
+        if (entry) {
+            if (typeof successCallback === 'function') {
+                // create appropriate Entry object
+                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);
+                try {
+                    successCallback(result);
+                }
+                catch (e) {
+                    console.log('Error invoking callback: ' + e);
+                }
+            }
+        }
+        else {
+            // no Entry object returned
+            fail(FileError.NOT_FOUND_ERR);
+        }
+    };
+
+    exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
+};
+
+});
+
+// file: lib/common/plugin/splashscreen.js
+define("cordova/plugin/splashscreen", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+var splashscreen = {
+    show:function() {
+        exec(null, null, "SplashScreen", "show", []);
+    },
+    hide:function() {
+        exec(null, null, "SplashScreen", "hide", []);
+    }
+};
+
+module.exports = splashscreen;
+});
+
+// file: lib/tizen/plugin/tizen/Accelerometer.js
+define("cordova/plugin/tizen/Accelerometer", function(require, exports, module) {
+var callback = null;
+
+module.exports = {
+    start: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+        callback = function (motion) {
+            successCallback({
+                x: motion.accelerationIncludingGravity.x,
+                y: motion.accelerationIncludingGravity.y,
+                z: motion.accelerationIncludingGravity.z,
+                timestamp: motion.timeStamp
+            });
+        };
+        window.addEventListener("devicemotion", callback);
+    },
+    stop: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+    }
+};
+});
+
+// file: lib/tizen/plugin/tizen/Battery.js
+define("cordova/plugin/tizen/Battery", function(require, exports, module) {
+/*global tizen:false */
+var id = null;
+
+module.exports = {
+    start: function(successCallback, errorCallback) {
+        var tizenSuccessCallback = function(power) {
+            if (successCallback) {
+                successCallback({level: Math.round(power.level * 100), isPlugged: power.isCharging});
+            }
+        };
+
+        if (id === null) {
+            id = tizen.systeminfo.addPropertyValueChangeListener("Power", tizenSuccessCallback);
+        }
+        tizen.systeminfo.getPropertyValue("Power", tizenSuccessCallback, errorCallback);
+    },
+
+    stop: function(successCallback, errorCallback) {
+        tizen.systeminfo.removePropertyValueChangeListener(id);
+        id = null;
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/BufferLoader.js
+define("cordova/plugin/tizen/BufferLoader", function(require, exports, module) {
+/*
+ * Buffer Loader Object
+ * This class provides a sound buffer for one or more sounds
+ * holded in a local file located by an url
+ *
+ * uses W3C  Web Audio API
+ *
+ * @constructor
+ *
+ * @param {AudioContext} audio context object
+ * @param {Array} urlList, array of url for sound to load
+ * @param {function} callback , called after buffer was loaded
+ *
+ */
+
+function BufferLoader(context, urlList, callback) {
+    this.context = context;
+    this.urlList = urlList;
+    this.onload = callback;
+    this.bufferList = [];
+    this.loadCount = 0;
+}
+
+/*
+ * This method loads a sound into a buffer
+ * @param {Array} urlList, array of url for sound to load
+ * @param {Number} index, buffer index in the array where to load the url sound
+ *
+ */
+
+BufferLoader.prototype.loadBuffer = function(url, index) {
+    // Load buffer asynchronously
+    var request = null,
+        loader = null;
+
+    request = new XMLHttpRequest();
+
+    if (request === null) {
+        console.log ("BufferLoader.prototype.loadBuffer, cannot allocate XML http request");
+        return;
+    }
+
+    request.open("GET", url, true);
+    request.responseType = "arraybuffer";
+
+    loader = this;
+
+    request.onload = function() {
+    // Asynchronously decode the audio file data in request.response
+    loader.context.decodeAudioData(
+        request.response,
+        function(buffer) {
+                if (!buffer) {
+                    console.log ("BufferLoader.prototype.loadBuffer,error decoding file data: " + url);
+                    return;
+                }
+
+                loader.bufferList[index] = buffer;
+
+                if (++loader.loadCount == loader.urlList.length) {
+                    loader.onload(loader.bufferList);
+                }
+            }
+        );
+    };
+
+    request.onerror = function() {
+        console.log ("BufferLoader.prototype.loadBuffer, XHR error");
+    };
+
+    request.send();
+};
+
+/*
+ * This method loads all sounds identified by their url
+ * and that where given to the object constructor
+ *
+ */
+
+BufferLoader.prototype.load = function() {
+    for (var i = 0; i < this.urlList.length; ++i) {
+        this.loadBuffer(this.urlList[i], i);
+    }
+};
+
+module.exports = BufferLoader;
+
+});
+
+// file: lib/tizen/plugin/tizen/Camera.js
+define("cordova/plugin/tizen/Camera", function(require, exports, module) {
+/*global tizen:false */
+var Camera = require('cordova/plugin/CameraConstants');
+
+function makeReplyCallback(successCallback, errorCallback) {
+    return {
+        onsuccess: function(reply) {
+            if (reply.length > 0) {
+                successCallback(reply[0].value);
+            } else {
+                errorCallback('Picture selection aborted');
+            }
+        },
+        onfail: function() {
+           console.log('The service launch failed');
+        }
+    };
+}
+
+module.exports = {
+    takePicture: function(successCallback, errorCallback, args) {
+        var destinationType = args[1],
+            sourceType = args[2],
+            encodingType = args[5],
+            mediaType = args[6];
+            // Not supported
+            /*
+            quality = args[0]
+            targetWidth = args[3]
+            targetHeight = args[4]
+            allowEdit = args[7]
+            correctOrientation = args[8]
+            saveToPhotoAlbum = args[9]
+            */
+
+        if (destinationType !== Camera.DestinationType.FILE_URI) {
+            errorCallback('DestinationType not supported');
+            return;
+        }
+        if (mediaType !== Camera.MediaType.PICTURE) {
+            errorCallback('MediaType not supported');
+            return;
+        }
+
+        var mimeType;
+        if (encodingType === Camera.EncodingType.JPEG) {
+            mimeType = 'image/jpeg';
+        } else if (encodingType === Camera.EncodingType.PNG) {
+            mimeType = 'image/png';
+        } else {
+            mimeType = 'image/*';
+        }
+
+        var serviceId;
+        if (sourceType === Camera.PictureSourceType.CAMERA) {
+            serviceId = 'http://tizen.org/appsvc/operation/create_content';
+        } else {
+            serviceId = 'http://tizen.org/appsvc/operation/pick';
+        }
+
+        var service = new tizen.ApplicationService(serviceId, null, mimeType, null);
+        tizen.application.launchService(service, null, null,
+                function(error) { errorCallback(error.message); },
+                makeReplyCallback(successCallback, errorCallback));
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Compass.js
+define("cordova/plugin/tizen/Compass", function(require, exports, module) {
+var CompassError = require('cordova/plugin/CompassError'),
+    callback = null, ready = false;
+
+module.exports = {
+    getHeading: function(successCallback, errorCallback) {
+        if (window.DeviceOrientationEvent !== undefined) {
+            callback = function (orientation) {
+                var heading = 360 - orientation.alpha;
+                if (ready) {
+                    successCallback({
+                        magneticHeading: heading,
+                        trueHeading: heading,
+                        headingAccuracy: 0,
+                        timestamp: orientation.timeStamp
+                    });
+                    window.removeEventListener("deviceorientation", callback);
+                }
+                ready = true;
+            };
+            ready = false; // workaround invalid first event value returned by WRT
+            window.addEventListener("deviceorientation", callback);
+        }
+        else {
+            errorCallback(CompassError.COMPASS_NOT_SUPPORTED);
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Contact.js
+define("cordova/plugin/tizen/Contact", function(require, exports, module) {
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// ------------------
+// Utility functions
+// ------------------
+
+
+/**
+ * Retrieves a Tizen Contact object from the device by its unique id.
+ *
+ * @param uid
+ *            Unique id of the contact on the device
+ * @return {tizen.Contact} Tizen Contact object or null if contact with
+ *         specified id is not found
+ */
+var findByUniqueId = function(id) {
+
+    if (!id) {
+        return null;
+    }
+
+    var tizenContact = null;
+
+    tizen.contact.getDefaultAddressBook().find(
+        function _successCallback(contacts){
+            tizenContact = contacts[0];
+        },
+        function _errorCallback(error){
+            console.log("tizen find error " + error);
+        },
+        new tizen.AttributeFilter('id', 'CONTAINS', id),
+        new tizen.SortMode('id', 'ASC'));
+
+    return tizenContact || null;
+};
+
+
+var traceTizenContact = function (tizenContact) {
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.id " + tizenContact.id);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.lastUpdated " + tizenContact.lastUpdated);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.name " + tizenContact.name);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.account " + tizenContact.account);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.addresses " + tizenContact.addresses);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.photoURI " + tizenContact.photoURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.phoneNumbers " + tizenContact.phoneNumbers);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.emails " + tizenContact.emails);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.birthday " + tizenContact.birthday);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.organization " + tizenContact.organization);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.notes " + tizenContact.notes);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.urls " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.isFavorite " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.ringtonesURI " + tizenContact.ringtonesURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.categories " + tizenContact.categories);
+};
+
+
+/**
+ * Creates a Tizen contact object from the W3C Contact object and persists
+ * it to device storage.
+ *
+ * @param {Contact}
+ *            contact The contact to save
+ * @return a new contact object with all properties set
+ */
+var saveToDevice = function(contact) {
+
+    if (!contact) {
+        return;
+    }
+
+    var tizenContact = null;
+    var update = false;
+    var i = 0;
+
+    // if the underlying Tizen Contact object already exists, retrieve it for
+    // update
+    if (contact.id) {
+        // we must attempt to retrieve the BlackBerry contact from the device
+        // because this may be an update operation
+        tizenContact = findByUniqueId(contact.id);
+    }
+
+    // contact not found on device, create a new one
+    if (!tizenContact) {
+        tizenContact = new tizen.Contact();
+    }
+    // update the existing contact
+    else {
+        update = true;
+    }
+
+    // NOTE: The user may be working with a partial Contact object, because only
+    // user-specified Contact fields are returned from a find operation (blame
+    // the W3C spec). If this is an update to an existing Contact, we don't
+    // want to clear an attribute from the contact database simply because the
+    // Contact object that the user passed in contains a null value for that
+    // attribute. So we only copy the non-null Contact attributes to the
+    // Tizen Contact object before saving.
+    //
+    // This means that a user must explicitly set a Contact attribute to a
+    // non-null value in order to update it in the contact database.
+    //
+    traceTizenContact (tizenContact);
+
+    // display name
+    if (contact.displayName !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            tizenContact.name.displayName = contact.displayName;
+        }
+    }
+
+    // name
+    if (contact.name !== null) {
+        if (contact.name.givenName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.firstName = contact.name.givenName;
+            }
+        }
+
+        if  (contact.name.middleName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.middleName = contact.name.middleName;
+            }
+        }
+
+        if (contact.name.familyName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.lastName = contact.name.familyName;
+            }
+        }
+
+        if (contact.name.honorificPrefix) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.prefix = contact.name.honorificPrefix;
+            }
+        }
+    }
+
+    // nickname
+    if (contact.nickname !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            if (!utils.isArray(tizenContact.name.nicknames))
+            {
+                tizenContact.name.nicknames = [];
+            }
+            tizenContact.name.nicknames[0] = contact.nickname;
+        }
+    }
+    else {
+        tizenContact.name.nicknames = [];
+    }
+
+    // note
+    if (contact.note !== null) {
+        if (tizenContact.note === null) {
+            tizenContact.note = [];
+        }
+        if (tizenContact.note !== null) {
+            tizenContact.note[0] = contact.note;
+        }
+    }
+
+    // photos
+    if (contact.photos && utils.isArray(contact.emails) && contact.emails.length > 0) {
+        tizenContact.photoURI = contact.photos[0];
+    }
+
+    if (utils.isDate(contact.birthday)) {
+        if (!utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday = new Date();
+        }
+        if (utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday.setDate(contact.birthday.getDate());
+        }
+    }
+
+    // Tizen supports many addresses
+    if (utils.isArray(contact.emails)) {
+
+        // if this is an update, re initialize email addresses
+        if (update) {
+            // doit on effacer sur un update??????
+        }
+
+        // copy the first three email addresses found
+        var emails = [];
+        for (i = 0; i < contact.emails.length; i += 1) {
+            var emailTypes = [];
+
+            emailTypes.push (contact.emails[i].type);
+
+            if (contact.emails[i].pref) {
+                emailTypes.push ("PREF");
+            }
+
+            emails.push(
+                new tizen.ContactEmailAddress(
+                    contact.emails[i].value,
+                    emailTypes)
+            );
+        }
+        tizenContact.emails = emails.length > 0 ? emails : [];
+    }
+    else {
+        tizenContact.emails = [];
+    }
+
+    // Tizen supports many phone numbers
+    // copy into appropriate fields based on type
+    if (utils.isArray(contact.phoneNumbers)) {
+        // if this is an update, re-initialize phone numbers
+        if (update) {
+        }
+
+        var phoneNumbers = [];
+
+        for (i = 0; i < contact.phoneNumbers.length; i += 1) {
+
+            if (!contact.phoneNumbers[i] || !contact.phoneNumbers[i].value) {
+                continue;
+            }
+
+             var phoneTypes = [];
+             phoneTypes.push (contact.phoneNumbers[i].type);
+
+             if (contact.phoneNumbers[i].pref) {
+                 phoneTypes.push ("PREF");
+             }
+
+            phoneNumbers.push(
+                new tizen.ContactPhoneNumber(
+                    contact.phoneNumbers[i].value,
+                    phoneTypes)
+            );
+        }
+
+        tizenContact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : [];
+    } else {
+        tizenContact.phoneNumbers = [];
+    }
+
+    if (utils.isArray(contact.addresses)) {
+        // if this is an update, re-initialize addresses
+        if (update) {
+        }
+
+        var addresses = [],
+            address = null;
+
+        for ( i = 0; i < contact.addresses.length; i += 1) {
+            address = contact.addresses[i];
+
+            if (!address || address.id === undefined || address.pref === undefined || address.type === undefined || address.formatted === undefined) {
+                continue;
+            }
+
+            var addressTypes = [];
+            addressTypes.push (address.type);
+
+            if (address.pref) {
+                addressTypes.push ("PREF");
+            }
+
+            addresses.push(
+                new tizen.ContactAddress({
+                         country:                   address.country,
+                         region :                   address.region,
+                         city:                      address.locality,
+                         streetAddress:             address.streetAddress,
+                         additionalInformation:     "",
+                         postalCode:                address.postalCode,
+                         types :                    addressTypes
+                }));
+
+        }
+        tizenContact.addresses = addresses.length > 0 ? addresses : [];
+
+    } else{
+        tizenContact.addresses = [];
+    }
+
+    // copy first url found to BlackBerry 'webpage' field
+    if (utils.isArray(contact.urls)) {
+        // if this is an update, re-initialize web page
+        if (update) {
+        }
+
+        var url = null,
+            urls = [];
+
+        for ( i = 0; i< contact.urls.length; i+= 1) {
+            url = contact.urls[i];
+
+            if (!url || !url.value) {
+                continue;
+            }
+
+            urls.push( new tizen.ContactWebSite(url.value, url.type));
+        }
+        tizenContact.urls = urls.length > 0 ? urls : [];
+    } else{
+        tizenContact.urls = [];
+    }
+
+    if (utils.isArray(contact.organizations && contact.organizations.length > 0) ) {
+        // if this is an update, re-initialize org attributes
+        var organization = contact.organizations[0];
+
+         tizenContact.organization = new tizen.ContacOrganization({
+             name:          organization.name,
+             department:    organization.department,
+             office:        "",
+             title:         organization.title,
+             role:          "",
+             logoURI:       ""
+         });
+    }
+
+    // categories
+    if (utils.isArray(contact.categories)) {
+        tizenContact.categories = [];
+
+        var category = null;
+
+        for (i = 0; i < contact.categories.length; i += 1) {
+            category = contact.categories[i];
+
+            if (typeof category === "string") {
+                tizenContact.categories.push(category);
+            }
+        }
+    }
+    else {
+        tizenContact.categories = [];
+    }
+
+    // save to device
+    // in tizen contact mean update or add
+    // later we might use addBatch and updateBatch
+    if (update){
+        tizen.contact.getDefaultAddressBook().update(tizenContact);
+    }
+    else {
+        tizen.contact.getDefaultAddressBook().add(tizenContact);
+    }
+
+    // Use the fully populated Tizen contact object to create a
+    // corresponding W3C contact object.
+    return ContactUtils.createContact(tizenContact, [ "*" ]);
+};
+
+
+/**
+ * Creates a Tizen ContactAddress object from a W3C ContactAddress.
+ *
+ * @return {tizen.ContactAddress} a Tizen ContactAddress object
+ */
+var createTizenAddress = function(address) {
+
+    var type = null,
+        pref = null,
+        typesAr = [];
+
+    if (address === null) {
+        return null;
+    }
+
+
+    var tizenAddress = new tizen.ContactAddress();
+
+    if (tizenAddress === null) {
+        return null;
+    }
+
+    typesAr.push(address.type);
+
+    if (address.pref) {
+        typesAr.push("PREF");
+    }
+
+    tizenAddress.country = address.country || "";
+    tizenAddress.region = address.region || "";
+    tizenAddress.city = address.locality || "";
+    tizenAddress.streetAddress = address.streetAddress || "";
+    tizenAddress.postalCode = address.postalCode || "";
+    tizenAddress.types = typesAr || "";
+
+    return tizenAddress;
+};
+
+module.exports = {
+    /**
+     * Persists contact to device storage.
+     */
+
+    save : function(successCB, failCB) {
+
+        try {
+            // save the contact and store it's unique id
+            var fullContact = saveToDevice(this);
+
+            this.id = fullContact.id;
+
+            // This contact object may only have a subset of properties
+            // if the save was an update of an existing contact. This is
+            // because the existing contact was likely retrieved using a
+            // subset of properties, so only those properties were set in the
+            // object. For this reason, invoke success with the contact object
+            // returned by saveToDevice since it is fully populated.
+
+            if (typeof successCB === 'function') {
+                successCB(fullContact);
+            }
+        }
+        catch (error) {
+            console.log('Error saving contact: ' +  error);
+
+            if (typeof failCB === 'function') {
+                failCB (new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    },
+
+    /**
+     * Removes contact from device storage.
+     *
+     * @param successCB
+     *            successCB callback
+     * @param failCB
+     *            error callback
+     */
+    remove : function (successCB, failCB) {
+
+        try {
+            // retrieve contact from device by id
+            var tizenContact = null;
+
+            if (this.id) {
+                tizenContact = findByUniqueId(this.id);
+            }
+
+
+            // if contact was found, remove it
+            if (tizenContact) {
+
+                tizen.contact.getDefaultAddressBook().remove(tizenContact.id);
+
+                if (typeof success === 'function') {
+                    successCB(this);
+                }
+            }
+            // attempting to remove a contact that hasn't been saved
+            else if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+        catch (error) {
+            console.log('Error removing contact ' + this.id + ": " + error);
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/ContactUtils.js
+define("cordova/plugin/tizen/ContactUtils", function(require, exports, module) {
+/*global tizen:false */
+var ContactAddress = require('cordova/plugin/ContactAddress'),
+    ContactName = require('cordova/plugin/ContactName'),
+    ContactField = require('cordova/plugin/ContactField'),
+    ContactOrganization = require('cordova/plugin/ContactOrganization'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+ * Mappings for each Contact field that may be used in a find operation. Maps
+ * W3C Contact fields to one or more fields in a Tizen contact object.
+ *
+ * Example: user searches with a filter on the Contact 'name' field:
+ *
+ * <code>Contacts.find(['name'], onSuccess, onFail, {filter:'Bob'});</code>
+ *
+ * The 'name' field does not exist in a Tizen contact. Instead, a filter
+ * expression will be built to search the Tizen contacts using the
+ * Tizen 'title', 'firstName' and 'lastName' fields.
+ */
+var fieldMappings = {
+    "id" : ["id"],
+    "displayName" : ["name.displayName"],
+    "nickname": ["name.nicknames"],
+    "name" : [ "name.prefix", "name.firstName", "name.lastName" ],
+    "phoneNumbers" : ["phoneNumbers.number","phoneNumbers.types"],
+    "emails" : ["emails.types", "emails.email"],
+    "addresses" : ["addresses.country","addresses.region","addresses.city","addresses.streetAddress","addresses.postalCode","addresses.country","addresses.types"],
+    "organizations" : ["organization.name","organization.department","organization.office", "organization.title"],
+    "birthday" : ["birthday"],
+    "note" : ["notes"],
+    "photos" : ["photoURI"],
+    "categories" : ["categories"],
+    "urls" : ["urls.url", "urls.type"]
+};
+
+/*
+ * Build an array of all of the valid W3C Contact fields. This is used to
+ * substitute all the fields when ["*"] is specified.
+ */
+var allFields = [];
+
+(function initializeAllFieldsMapping() {
+
+    for ( var key in fieldMappings) {
+        allFields.push(key);
+    }
+    // as we want it to be executed once
+    function initializeAllFieldsMapping() {
+    }
+
+})();
+
+/**
+ * Create a W3C ContactAddress object from a Tizen Address object
+ *
+ * @param {String}
+ *            type the type of address (e.g. work, home)
+ * @param {tizen.ContactAddress}
+ *            tizenAddress a Tizen Address object
+ * @return {ContactAddress} a contact address object or null if the specified
+ *         address is null
+ */
+var createContactAddress = function(type, tizenAddress) {
+    if (!tizenAddress) {
+        return null;
+    }
+
+    var streetAddress = tizenAddress.streetAddress;
+    var locality = tizenAddress.city || "";
+    var region = tizenAddress.region || "";
+    var postalCode = tizenAddress.postalCode || "";
+    var country = tizenAddress.country || "";
+    var formatted = streetAddress + ", " + locality + ", " + region + ", " + postalCode + ", " + country;
+
+    var contact = new ContactAddress(null, type, formatted, streetAddress, locality, region, postalCode, country);
+
+    return contact;
+};
+
+module.exports = {
+    /**
+     * Builds Tizen filter expressions for contact search using the
+     * contact fields and search filter provided.
+     *
+     * @param {String[]}
+     *            fields Array of Contact fields to search
+     * @param {String}
+     *            filter Filter, or search string
+     * @param {Boolean}
+     *                 multiple, one contacts or more wanted as result
+     * @return filter expression or null if fields is empty or filter is null or
+     *         empty
+     */
+
+    buildFilterExpression: function(fields, filter) {
+        // ensure filter exists
+        if (!filter || filter === "") {
+            return null;
+        }
+
+        if ((fields.length === 1) && (fields[0] === "*")) {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // build a filter expression using all Contact fields provided
+        var compositeFilter = null,
+            attributeFilter = null,
+            filterExpression = null,
+            matchFlag = "CONTAINS",
+            matchValue = filter,
+            attributesArray = [];
+
+        if (fields && utils.isArray(fields)) {
+
+            for ( var field in fields) {
+
+                if (!fields[field]) {
+                    continue;
+                }
+
+                // retrieve Tizen contact fields that map Cordova fields specified
+                // (tizenFields is a string or an array of strings)
+                var tizenFields = fieldMappings[fields[field]];
+
+                if (!tizenFields) {
+                    // does something maps
+                    continue;
+                }
+
+                // construct the filter expression using the Tizen fields
+                for ( var index in tizenFields) {
+                    attributeFilter = new tizen.AttributeFilter(tizenFields[index], matchFlag, matchValue);
+                    if (attributeFilter !== null) {
+                        attributesArray.push(attributeFilter);
+                    }
+                }
+            }
+        }
+
+        // fullfil tizen find attribute as a single or a composite attribute
+        if (attributesArray.length == 1 ) {
+            filterExpression = attributeFilter[0];
+        } else if (attributesArray.length > 1) {
+            // combine the filters as a Union
+            filterExpression = new tizen.CompositeFilter("UNION", attributesArray);
+        } else {
+            filterExpression = null;
+        }
+
+        return filterExpression;
+    },
+
+
+
+    /**
+     * Creates a Contact object from a Tizen Contact object, copying only
+     * the fields specified.
+     *
+     * This is intended as a privately used function but it is made globally
+     * available so that a Contact.save can convert a BlackBerry contact object
+     * into its W3C equivalent.
+     *
+     * @param {tizen.Contact}
+     *            tizenContact Tizen Contact object
+     * @param {String[]}
+     *            fields array of contact fields that should be copied
+     * @return {Contact} a contact object containing the specified fields or
+     *         null if the specified contact is null
+     */
+    createContact: function(tizenContact, fields) {
+
+        if (!tizenContact) {
+            return null;
+        }
+
+        // construct a new contact object
+        // always copy the contact id and displayName fields
+        var contact = new Contact(tizenContact.id, tizenContact.name.displayName);
+
+
+        // nothing to do
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            return contact;
+        } else if (fields.length === 1 && fields[0] === "*") {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // add the fields specified
+        for ( var key in fields) {
+
+            var field = fields[key],
+                index = 0;
+
+            if (!field) {
+                continue;
+            }
+
+            // name
+            if (field.indexOf('name') === 0) {
+
+                var formattedName = (tizenContact.name.prefix || "");
+
+                if (tizenContact.name.firstName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.firstName || "");
+                }
+
+                if (tizenContact.name.middleName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.middleName || "");
+                }
+
+                if (tizenContact.name.lastName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.lastName || "");
+                }
+
+                contact.name = new ContactName(
+                        formattedName,
+                        tizenContact.name.lastName,
+                        tizenContact.name.firstName,
+                        tizenContact.name.middleName,
+                        tizenContact.name.prefix,
+                        null);
+            }
+
+            // phoneNumbers
+            else if (field.indexOf('phoneNumbers') === 0) {
+
+                var phoneNumbers = [];
+
+                for (index = 0 ; index < tizenContact.phoneNumbers.length ; ++index) {
+
+                    phoneNumbers.push(
+                            new ContactField(
+                                    'PHONE',
+                                    tizenContact.phoneNumbers[index].number,
+                                    ((tizenContact.phoneNumbers[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+
+
+                contact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : null;
+            }
+
+            // emails
+            else if (field.indexOf('emails') === 0) {
+
+                var emails = [];
+
+                for (index = 0 ; index < tizenContact.emails.length ; ++index) {
+
+                    emails.push(
+                        new ContactField(
+                            'EMAILS',
+                            tizenContact.emails[index].email,
+                            ((tizenContact.emails[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+                contact.emails = emails.length > 0 ? emails : null;
+            }
+
+            // addresses
+            else if (field.indexOf('addresses') === 0) {
+
+                var addresses = [];
+                for (index = 0 ; index < tizenContact.addresses.length ; ++index) {
+
+                    addresses.push(
+                            new ContactAddress(
+                                    ((tizenContact.addresses[index].types[1] &&  tizenContact.addresses[index].types[1] === "PREF") ? true : false),
+                                    tizenContact.addresses[index].types[0] ? tizenContact.addresses[index].types[0] : "HOME",
+                                    null,
+                                    tizenContact.addresses[index].streetAddress,
+                                    tizenContact.addresses[index].city,
+                                    tizenContact.addresses[index].region,
+                                    tizenContact.addresses[index].postalCode,
+                                    tizenContact.addresses[index].country ));
+                }
+
+                contact.addresses = addresses.length > 0 ? addresses : null;
+            }
+
+            // birthday
+            else if (field.indexOf('birthday') === 0) {
+                if (utils.isDate(tizenContact.birthday)) {
+                    contact.birthday = tizenContact.birthday;
+                }
+            }
+
+            // note only one in Tizen Contact
+            else if (field.indexOf('note') === 0) {
+                if (tizenContact.note) {
+                    contact.note = tizenContact.note[0];
+                }
+            }
+
+            // organizations
+            else if (field.indexOf('organizations') === 0) {
+
+                var organizations = [];
+
+                // there's only one organization in a Tizen Address
+
+                if (tizenContact.organization) {
+                    organizations.push(
+                            new ContactOrganization(
+                                    true,
+                                    'WORK',
+                                    tizenContact.organization.name,
+                                    tizenContact.organization.department,
+                                    tizenContact.organization.jobTitle));
+                }
+
+                contact.organizations = organizations.length > 0 ? organizations : null;
+            }
+
+            // categories
+            else if (field.indexOf('categories') === 0) {
+
+                var categories = [];
+
+                if (tizenContact.categories) {
+
+                    for (index = 0 ; index < tizenContact.categories.length ; ++index) {
+                        categories.push(
+                                new ContactField(
+                                        'MAIN',
+                                        tizenContact.categories,
+                                        (index === 0) ));
+                    }
+
+                    contact.categories = categories.length > 0 ? categories : null;
+                }
+            }
+
+            // urls
+            else if (field.indexOf('urls') === 0) {
+                var urls = [];
+
+                if (tizenContact.urls) {
+                    for (index = 0 ; index <tizenContact.urls.length ; ++index) {
+                        urls.push(
+                                new ContactField(
+                                        tizenContact.urls[index].type,
+                                        tizenContact.urls[index].url,
+                                        (index === 0)));
+                    }
+                }
+
+                contact.urls = urls.length > 0 ? urls : null;
+            }
+
+            // photos
+            else if (field.indexOf('photos') === 0) {
+                var photos = [];
+
+                if (tizenContact.photoURI) {
+                    photos.push(new ContactField('URI', tizenContact.photoURI, true));
+                }
+
+                contact.photos = photos.length > 0 ? photos : null;
+            }
+        }
+
+        return contact;
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Device.js
+define("cordova/plugin/tizen/Device", function(require, exports, module) {
+/*global tizen:false */
+var channel = require('cordova/channel');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+function Device() {
+    this.version = null;
+    this.uuid = null;
+    this.name = null;
+    this.cordova =  "2.0.0";
+    this.platform = "Tizen";
+
+    var me = this;
+
+    function onSuccessCallback(sysInfoProp) {
+        me.name = sysInfoProp.model;
+        me.uuid = sysInfoProp.imei;
+        me.version = sysInfoProp.version;
+        channel.onCordovaInfoReady.fire();
+    }
+
+    function onErrorCallback(error) {
+        console.log("error initializing cordova: " + error);
+    }
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getDeviceInfo(onSuccessCallback, onErrorCallback);
+    });
+}
+
+Device.prototype.getDeviceInfo = function(success, fail, args) {
+    tizen.systeminfo.getPropertyValue("Device", success, fail);
+};
+
+module.exports = new Device();
+
+});
+
+// file: lib/tizen/plugin/tizen/File.js
+define("cordova/plugin/tizen/File", function(require, exports, module) {
+/*global WebKitBlobBuilder:false */
+var FileError = require('cordova/plugin/FileError'),
+    DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    File = require('cordova/plugin/File'),
+    FileSystem = require('cordova/plugin/FileSystem');
+
+var nativeRequestFileSystem = window.webkitRequestFileSystem,
+    nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL,
+    NativeFileReader = window.FileReader;
+
+function getFileSystemName(nativeFs) {
+    return (nativeFs.name.indexOf("Persistent") != -1) ? "persistent" : "temporary";
+}
+
+function makeEntry(entry) {
+    if (entry.isDirectory) {
+        return new DirectoryEntry(entry.name, decodeURI(entry.toURL()));
+    }
+    else {
+        return new FileEntry(entry.name, decodeURI(entry.toURL()));
+    }
+}
+
+module.exports = {
+    /* requestFileSystem */
+    requestFileSystem: function(successCallback, errorCallback, args) {
+        var type = args[0],
+            size = args[1];
+
+        nativeRequestFileSystem(type, size, function(nativeFs) {
+            successCallback(new FileSystem(getFileSystemName(nativeFs), makeEntry(nativeFs.root)));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* resolveLocalFileSystemURI */
+    resolveLocalFileSystemURI: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            successCallback(makeEntry(entry));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryReader */
+    readEntries: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(dirEntry) {
+            var reader = dirEntry.createReader();
+            reader.readEntries(function(entries) {
+                var retVal = [];
+                for (var i = 0; i < entries.length; i++) {
+                    retVal.push(makeEntry(entries[i]));
+                }
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* Entry */
+    getMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getMetadata(function(metaData) {
+                successCallback(metaData.modificationTime);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    moveTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.moveTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    copyTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.copyTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    remove: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.remove(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getParent: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getParent(function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileEntry */
+    getFileMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.file(function(file) {
+                var retVal = new File(file.name, decodeURI(entry.toURL()), file.type, file.lastModifiedDate, file.size);
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryEntry */
+    getDirectory: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getDirectory(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    removeRecursively: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.removeRecursively(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getFile: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getFile(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileReader */
+    readAsText: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            encoding = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsText(file, encoding);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    readAsDataURL: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsDataURL(file);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileWriter */
+    write: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            text = args[1],
+            position = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.position - position);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                var blob = new WebKitBlobBuilder();
+                blob.append(text);
+
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.seek(position);
+                writer.write(blob.getBlob('text/plain'));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    truncate: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            size = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.length);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.truncate(size);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/FileTransfer.js
+define("cordova/plugin/tizen/FileTransfer", function(require, exports, module) {
+/*global WebKitBlobBuilder:false */
+var FileEntry = require('cordova/plugin/FileEntry'),
+    FileTransferError = require('cordova/plugin/FileTransferError'),
+    FileUploadResult = require('cordova/plugin/FileUploadResult');
+
+var nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL;
+
+function getParentPath(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(0, pos + 1);
+}
+
+function getFileName(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(pos + 1);
+}
+
+module.exports = {
+    upload: function(successCallback, errorCallback, args) {
+        var filePath = args[0],
+            server = args[1],
+            fileKey = args[2],
+            fileName = args[3],
+            mimeType = args[4],
+            params = args[5],
+            /*trustAllHosts = args[6],*/
+            chunkedMode = args[7];
+
+        nativeResolveLocalFileSystemURI(filePath, function(entry) {
+            entry.file(function(file) {
+                function uploadFile(blobFile) {
+                    var fd = new FormData();
+
+                    fd.append(fileKey, blobFile, fileName);
+                    for (var prop in params) {
+                        if(params.hasOwnProperty(prop)) {
+                            fd.append(prop, params[prop]);
+                        }
+                    }
+
+                    var xhr = new XMLHttpRequest();
+                    xhr.open("POST", server);
+                    xhr.onload = function(evt) {
+                        if (xhr.status == 200) {
+                            var result = new FileUploadResult();
+                            result.bytesSent = file.size;
+                            result.responseCode = xhr.status;
+                            result.response = xhr.response;
+                            successCallback(result);
+                        } else if (xhr.status == 404) {
+                            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                        } else {
+                            errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                        }
+                    };
+                    xhr.ontimeout = function(evt) {
+                        errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                    };
+
+                    xhr.send(fd);
+                }
+
+                var bytesPerChunk;
+                if (chunkedMode === true) {
+                    bytesPerChunk = 1024 * 1024; // 1MB chunk sizes.
+                } else {
+                    bytesPerChunk = file.size;
+                }
+                var start = 0;
+                var end = bytesPerChunk;
+                while (start < file.size) {
+                    var chunk = file.webkitSlice(start, end, mimeType);
+                    uploadFile(chunk);
+                    start = end;
+                    end = start + bytesPerChunk;
+                }
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            }
+            );
+        },
+        function(error) {
+            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+        }
+        );
+    },
+
+    download: function(successCallback, errorCallback, args) {
+        var url = args[0],
+            filePath = args[1];
+
+        var xhr = new XMLHttpRequest();
+
+        function writeFile(fileEntry) {
+            fileEntry.createWriter(function(writer) {
+                writer.onwriteend = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(new FileEntry(fileEntry.name, fileEntry.toURL()));
+                    } else {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    }
+                };
+
+                writer.onerror = function(evt) {
+                    errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                };
+
+                var builder = new WebKitBlobBuilder();
+                builder.append(xhr.response);
+                var blob = builder.getBlob();
+                writer.write(blob);
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            });
+        }
+
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == xhr.DONE) {
+                if (xhr.status == 200 && xhr.response) {
+                    nativeResolveLocalFileSystemURI(getParentPath(filePath), function(dir) {
+                        dir.getFile(getFileName(filePath), {create: true}, writeFile, function(error) {
+                            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                        });
+                    }, function(error) {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    });
+                } else if (xhr.status == 404) {
+                    errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                } else {
+                    errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                }
+            }
+        };
+
+        xhr.open("GET", url, true);
+        xhr.responseType = "arraybuffer";
+        xhr.send();
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Media.js
+define("cordova/plugin/tizen/Media", function(require, exports, module) {
+/*global Media:false, webkitURL:false */
+var MediaError = require('cordova/plugin/MediaError'),
+    audioObjects = {};
+
+module.exports = {
+    create: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::create() - id =" + id + ", src =" + src);
+        audioObjects[id] = new Audio(src);
+        audioObjects[id].onStalledCB = function () {
+            console.log("media::onStalled()");
+             audioObjects[id].timer = window.setTimeout(function () {
+                    audioObjects[id].pause();
+                    if (audioObjects[id].currentTime !== 0)
+                        audioObjects[id].currentTime = 0;
+                    console.log("media::onStalled() - MEDIA_ERROR -> " + MediaError.MEDIA_ERR_ABORTED);
+                    var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, "Stalled");
+                    Media.onStatus(id, Media.MEDIA_ERROR, err);
+                }, 2000);
+        };
+        audioObjects[id].onEndedCB = function () {
+            console.log("media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        };
+        audioObjects[id].onErrorCB = function () {
+            console.log("media::onErrorCB() - MEDIA_ERROR -> " + event.srcElement.error);
+            Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error);
+        };
+        audioObjects[id].onPlayCB = function () {
+            console.log("media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
+        };
+        audioObjects[id].onPlayingCB = function () {
+            console.log("media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);
+        };
+        audioObjects[id].onDurationChangeCB = function () {
+            console.log("media::onDurationChangeCB() - MEDIA_DURATION -> " +  audioObjects[id].duration);
+            Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration);
+        };
+        audioObjects[id].onTimeUpdateCB = function () {
+            console.log("media::onTimeUpdateCB() - MEDIA_POSITION -> " +  audioObjects[id].currentTime);
+            Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime);
+        };
+        audioObjects[id].onCanPlayCB = function () {
+            console.log("media::onCanPlayCB()");
+            window.clearTimeout(audioObjects[id].timer);
+            audioObjects[id].play();
+        };
+      },
+    startPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1], options = args[2];
+        console.log("media::startPlayingAudio() - id =" + id + ", src =" + src + ", options =" + options);
+        audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB);
+        audioObjects[id].play();
+    },
+    stopPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        audioObjects[id].pause();
+        if (audioObjects[id].currentTime !== 0)
+            audioObjects[id].currentTime = 0;
+        console.log("media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED");
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB);
+    },
+    seekToAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], milliseconds = args[1];
+        console.log("media::seekToAudio()");
+         audioObjects[id].currentTime = milliseconds;
+        successCallback( audioObjects[id].currentTime);
+    },
+    pausePlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED");
+        audioObjects[id].pause();
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
+    },
+    getCurrentPositionAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::getCurrentPositionAudio()");
+        successCallback(audioObjects[id].currentTime);
+    },
+    release: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        console.log("media::release()");
+    },
+    setVolume: function (successCallback, errorCallback, args) {
+        var id = args[0], volume = args[1];
+        console.log("media::setVolume()");
+        audioObjects[id].volume = volume;
+    },
+    startRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::startRecordingAudio() - id =" + id + ", src =" + src);
+
+        function gotStreamCB(stream) {
+            audioObjects[id].src = webkitURL.createObjectURL(stream);
+            console.log("media::startRecordingAudio() - stream CB");
+        }
+
+        function gotStreamFailedCB(error) {
+            console.log("media::startRecordingAudio() - error CB:" + error.toString());
+        }
+
+        if (navigator.webkitGetUserMedia) {
+            audioObjects[id] = new Audio();
+            navigator.webkitGetUserMedia('audio', gotStreamCB, gotStreamFailedCB);
+        } else {
+            console.log("webkitGetUserMedia not supported");
+        }
+        successCallback();
+    },
+    stopRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::stopRecordingAudio() - id =" + id);
+        audioObjects[id].pause();
+        successCallback();
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/MediaError.js
+define("cordova/plugin/tizen/MediaError", function(require, exports, module) {
+
+// The MediaError object already exists on Tizen. This prevents the Cordova
+// version from being defined. This object is used to merge in differences
+// between Tizen and Cordova MediaError objects.
+module.exports = {
+        MEDIA_ERR_NONE_ACTIVE : 0,
+        MEDIA_ERR_NONE_SUPPORTED : 4
+};
+});
+
+// file: lib/tizen/plugin/tizen/NetworkStatus.js
+define("cordova/plugin/tizen/NetworkStatus", function(require, exports, module) {
+/*global tizen:false */
+var Connection = require('cordova/plugin/Connection');
+
+module.exports = {
+    getConnectionInfo: function (successCallback, errorCallback) {
+        var cncType = Connection.NONE;
+        var infoCount = 0;
+
+        function infoCB() {
+            infoCount++;
+            if (infoCount > 1)
+               successCallback(cncType);
+        }
+
+        function errorCB(error) {
+           console.log("Error: " + error.code + "," + error.name + "," + error.message);
+           infoCB();
+        }
+
+        function wifiSuccessCB(wifi) {
+            if ((wifi.status === "ON")  && (wifi.ipAddress.length !== 0))
+                cncType = Connection.WIFI;
+            infoCB();
+        }
+
+        function cellularSuccessCB(cell) {
+            if ((cncType === Connection.NONE) && (cell.status === "ON") && (cell.ipAddress.length !== 0))
+                cncType = Connection.CELL_2G;
+            infoCB();
+        }
+
+        if (tizen.systeminfo.isSupported('WifiNetwork')) {
+            tizen.systeminfo.getPropertyValue('WifiNetwork', wifiSuccessCB, errorCB);
+        }
+
+        if (tizen.systeminfo.isSupported('CellularNetwork')) {
+            tizen.systeminfo.getPropertyValue('CellularNetwork', cellularSuccessCB, errorCB);
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Notification.js
+define("cordova/plugin/tizen/Notification", function(require, exports, module) {
+var SoundBeat = require('cordova/plugin/tizen/SoundBeat');
+
+/* TODO: get resource path from app environment? */
+var soundBeat = new SoundBeat(["./sounds/beep.wav"]);
+
+module.exports = {
+
+    alert: function(message, alertCallback, title, buttonName) {
+        return this.confirm(message, alertCallback, title, buttonName);
+    },
+
+    confirm: function(message, confirmCallback, title, buttonLabels) {
+        var index            =    null,
+            overlayElement    =    null,
+            popup            =    null,
+            element         =    null,
+            titleString        =     null,
+            messageString    =    null,
+            buttonString    =    null,
+            buttonsArray    =    null;
+
+
+        console.log ("message" , message);
+        console.log ("confirmCallback" , confirmCallback);
+        console.log ("title" , title);
+        console.log ("buttonLabels" , buttonLabels);
+
+        titleString = '<div class="popup-title"><p>' + title + '</p></div>';
+        messageString = '<div class="popup-text"><p>' + message + '</p></div>';
+        buttonString = '<div class="popup-button-bg"><ul>';
+
+        switch(typeof(buttonLabels))
+        {
+        case "string":
+            buttonsArray = buttonLabels.split(",");
+
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+
+        case "array":
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+        default:
+            console.log ("cordova/plugin/tizen/Notification, default, buttonLabels: ", buttonLabels);
+            break;
+        }
+
+        buttonString += '</ul></div>';
+
+        overlayElement = document.createElement("div");
+        overlayElement.className = 'ui-popupwindow-screen';
+
+        overlayElement.style.zIndex = 1001;
+        overlayElement.style.width = "100%";
+        overlayElement.style.height = "100%";
+        overlayElement.style.top = 0;
+        overlayElement.style.left = 0;
+        overlayElement.style.margin = 0;
+        overlayElement.style.padding = 0;
+        overlayElement.style.position = "absolute";
+
+        popup = document.createElement("div");
+        popup.className = "ui-popupwindow";
+        popup.style.position = "fixed";
+        popup.style.zIndex = 1002;
+        popup.innerHTML = titleString + messageString + buttonString;
+
+        document.body.appendChild(overlayElement);
+        document.body.appendChild(popup);
+
+        function createListener(button) {
+            return function() {
+                document.body.removeChild(overlayElement);
+                document.body.removeChild(popup);
+                confirmCallback(button.value);
+            };
+        }
+
+       for (index in buttonsArray) {
+           console.log ("index: ", index);
+
+           element = document.getElementById("popup-button-" + buttonsArray[index]);
+           element.addEventListener("click", createListener(element), false);
+       }
+    },
+
+    vibrate: function(milliseconds) {
+        console.log ("milliseconds" , milliseconds);
+
+        if (navigator.vibrate) {
+            navigator.vibrate(milliseconds);
+        }
+        else {
+            console.log ("cordova/plugin/tizen/Notification, vibrate API does not exists");
+        }
+    },
+
+    beep: function(count) {
+        console.log ("count" , count);
+        soundBeat.play(count);
+    }
+};
+
+
+
+});
+
+// file: lib/tizen/plugin/tizen/SoundBeat.js
+define("cordova/plugin/tizen/SoundBeat", function(require, exports, module) {
+/*global webkitAudioContext:false */
+/*
+ *  SoundBeat
+ * used by Notification Manager beep method
+ *
+ * This class provides sounds play
+ *
+ * uses W3C  Web Audio API
+ * uses BufferLoader object
+ *
+ * NOTE: the W3C Web Audio doc tells we do not need to recreate the audio
+ *       context to play a sound but only the audiosourcenode (createBufferSource)
+ *       in the webkit implementation we have to.
+ *
+ */
+
+var BufferLoader = require('cordova/plugin/tizen/BufferLoader');
+
+function SoundBeat(urlList) {
+    this.context = null;
+    this.urlList = urlList || null;
+    this.buffers = null;
+}
+
+/*
+ * This method play a loaded sounds on the Device
+ * @param {Number} times Number of times to play loaded sounds.
+ *
+ */
+SoundBeat.prototype.play = function(times) {
+
+    var i = 0, sources = [], that = this;
+
+    function finishedLoading (bufferList) {
+        that.buffers = bufferList;
+
+        for (i = 0; i < that.buffers.length ; i +=1) {
+            if (that.context) {
+                sources[i] = that.context.createBufferSource();
+
+                sources[i].buffer = that.buffers[i];
+                sources[i].connect (that.context.destination);
+
+                sources[i].loop = true;
+                sources[i].noteOn (0);
+                sources[i].noteOff(sources[i].buffer.duration * times);
+            }
+        }
+    }
+
+    if (webkitAudioContext !== null) {
+        this.context = new webkitAudioContext();
+    }
+    else {
+        console.log ("SoundBeat.prototype.play, w3c web audio api not supported");
+        this.context = null;
+    }
+
+    if (this.context === null) {
+        console.log ("SoundBeat.prototype.play, cannot create audio context object");
+        return;
+    }
+
+    this.bufferLoader = new BufferLoader (this.context, this.urlList, finishedLoading);
+    if (this.bufferLoader === null) {
+        console.log ("SoundBeat.prototype.play, cannot create buffer loader object");
+        return;
+    }
+
+    this.bufferLoader.load();
+};
+
+module.exports = SoundBeat;
+
+});
+
+// file: lib/tizen/plugin/tizen/contacts.js
+define("cordova/plugin/tizen/contacts", function(require, exports, module) {
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils');
+
+module.exports = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     *
+     * @return array of Contacts matching search criteria
+     */
+    find : function(fields, successCB, failCB, options) {
+
+        // Success callback is required. Throw exception if not specified.
+        if (typeof successCB !== 'function') {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+
+        // Search qualifier is required and cannot be empty.
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+            return;
+        }
+
+        // options are optional
+        var filter ="",
+            multiple = false,
+            contacts = [],
+            tizenFilter = null;
+
+        if (options) {
+            filter = options.filter || "";
+            multiple =  options.multiple || false;
+        }
+
+        if (filter){
+            tizenFilter = ContactUtils.buildFilterExpression(fields, filter);
+        }
+
+        tizen.contact.getDefaultAddressBook().find(
+            function(tizenContacts) {
+                if (multiple) {
+                    for (var index in tizenContacts) {
+                        contacts.push(ContactUtils.createContact(tizenContacts[index], fields));
+                    }
+                }
+                else {
+                    contacts.push(ContactUtils.createContact(tizenContacts[0], fields));
+                }
+
+                // return results
+                successCB(contacts);
+            },
+            function(error) {
+                if (typeof failCB === 'function') {
+                    failCB(ContactError.UNKNOWN_ERROR);
+                }
+            },
+            tizenFilter,
+            null);
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/manager.js
+define("cordova/plugin/tizen/manager", function(require, exports, module) {
+var cordova = require('cordova');
+
+module.exports = {
+    exec: function (successCallback, errorCallback, clazz, action, args) {
+        var plugin = require('cordova/plugin/tizen/' + clazz);
+
+        if (plugin && typeof plugin[action] === 'function') {
+            var result = plugin[action](successCallback, errorCallback, args);
+            return result || {status: cordova.callbackStatus.NO_RESULT};
+        }
+
+        return {"status" : cordova.callbackStatus.CLASS_NOT_FOUND_EXCEPTION, "message" : "Function " + clazz + "::" + action + " cannot be found"};
+    },
+    resume: function () {},
+    pause: function () {},
+    destroy: function () {}
+};
+
+});
+
+// file: lib/common/utils.js
+define("cordova/utils", function(require, exports, module) {
+var utils = exports;
+
+/**
+ * Returns an indication of whether the argument is an array or not
+ */
+utils.isArray = function(a) {
+    return Object.prototype.toString.call(a) == '[object Array]';
+};
+
+/**
+ * Returns an indication of whether the argument is a Date or not
+ */
+utils.isDate = function(d) {
+    return Object.prototype.toString.call(d) == '[object Date]';
+};
+
+/**
+ * Does a deep clone of the object.
+ */
+utils.clone = function(obj) {
+    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
+        return obj;
+    }
+
+    var retVal, i;
+
+    if(utils.isArray(obj)){
+        retVal = [];
+        for(i = 0; i < obj.length; ++i){
+            retVal.push(utils.clone(obj[i]));
+        }
+        return retVal;
+    }
+
+    retVal = {};
+    for(i in obj){
+        if(!(i in retVal) || retVal[i] != obj[i]) {
+            retVal[i] = utils.clone(obj[i]);
+        }
+    }
+    return retVal;
+};
+
+/**
+ * Returns a wrappered version of the function
+ */
+utils.close = function(context, func, params) {
+    if (typeof params == 'undefined') {
+        return function() {
+            return func.apply(context, arguments);
+        };
+    } else {
+        return function() {
+            return func.apply(context, params);
+        };
+    }
+};
+
+/**
+ * Create a UUID
+ */
+utils.createUUID = function() {
+    return UUIDcreatePart(4) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(6);
+};
+
+/**
+ * Extends a child object from a parent object using classical inheritance
+ * pattern.
+ */
+utils.extend = (function() {
+    // proxy used to establish prototype chain
+    var F = function() {};
+    // extend Child from Parent
+    return function(Child, Parent) {
+        F.prototype = Parent.prototype;
+        Child.prototype = new F();
+        Child.__super__ = Parent.prototype;
+        Child.prototype.constructor = Child;
+    };
+}());
+
+/**
+ * Alerts a message in any available way: alert or console.log.
+ */
+utils.alert = function(msg) {
+    if (alert) {
+        alert(msg);
+    } else if (console && console.log) {
+        console.log(msg);
+    }
+};
+
+/**
+ * Formats a string and arguments following it ala sprintf()
+ *
+ * see utils.vformat() for more information
+ */
+utils.format = function(formatString /* ,... */) {
+    var args = [].slice.call(arguments, 1);
+    return utils.vformat(formatString, args);
+};
+
+/**
+ * Formats a string and arguments following it ala vsprintf()
+ *
+ * format chars:
+ *   %j - format arg as JSON
+ *   %o - format arg as JSON
+ *   %c - format arg as ''
+ *   %% - replace with '%'
+ * any other char following % will format it's
+ * arg via toString().
+ *
+ * for rationale, see FireBug's Console API:
+ *    http://getfirebug.com/wiki/index.php/Console_API
+ */
+utils.vformat = function(formatString, args) {
+    if (formatString === null || formatString === undefined) return "";
+    if (arguments.length == 1) return formatString.toString();
+    if (typeof formatString != "string") return formatString.toString();
+
+    var pattern = /(.*?)%(.)(.*)/;
+    var rest    = formatString;
+    var result  = [];
+
+    while (args.length) {
+        var arg   = args.shift();
+        var match = pattern.exec(rest);
+
+        if (!match) break;
+
+        rest = match[3];
+
+        result.push(match[1]);
+
+        if (match[2] == '%') {
+            result.push('%');
+            args.unshift(arg);
+            continue;
+        }
+
+        result.push(formatted(arg, match[2]));
+    }
+
+    result.push(rest);
+
+    return result.join('');
+};
+
+//------------------------------------------------------------------------------
+function UUIDcreatePart(length) {
+    var uuidpart = "";
+    for (var i=0; i<length; i++) {
+        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
+        if (uuidchar.length == 1) {
+            uuidchar = "0" + uuidchar;
+        }
+        uuidpart += uuidchar;
+    }
+    return uuidpart;
+}
+
+//------------------------------------------------------------------------------
+function formatted(object, formatChar) {
+
+    try {
+        switch(formatChar) {
+            case 'j':
+            case 'o': return JSON.stringify(object);
+            case 'c': return '';
+        }
+    }
+    catch (e) {
+        return "error JSON.stringify()ing argument: " + e;
+    }
+
+    if ((object === null) || (object === undefined)) {
+        return Object.prototype.toString.call(object);
+    }
+
+    return object.toString();
+}
+
+});
+
+
+window.cordova = require('cordova');
+
+// file: lib/scripts/bootstrap.js
+(function (context) {
+    var channel = require("cordova/channel"),
+        _self = {
+            boot: function () {
+                /**
+                 * Create all cordova objects once page has fully loaded and native side is ready.
+                 */
+                channel.join(function() {
+                    var builder = require('cordova/builder'),
+                        base = require('cordova/common'),
+                        platform = require('cordova/platform');
+
+                    // Drop the common globals into the window object, but be nice and don't overwrite anything.
+                    builder.build(base.objects).intoButDontClobber(window);
+
+                    // Drop the platform-specific globals into the window object
+                    // and clobber any existing object.
+                    builder.build(platform.objects).intoAndClobber(window);
+
+                    // Merge the platform-specific overrides/enhancements into
+                    // the window object.
+                    if (typeof platform.merges !== 'undefined') {
+                        builder.build(platform.merges).intoAndMerge(window);
+                    }
+
+                    // Call the platform-specific initialization
+                    platform.initialize();
+
+                    // Fire event to notify that all objects are created
+                    channel.onCordovaReady.fire();
+
+                    // Fire onDeviceReady event once all constructors have run and
+                    // cordova info has been received from native side.
+                    channel.join(function() {
+                        require('cordova').fireDocumentEvent('deviceready');
+                    }, channel.deviceReadyChannelsArray);
+
+                }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);
+            }
+        };
+
+    // boot up once native side is ready
+    channel.onNativeReady.subscribeOnce(_self.boot);
+
+    // _nativeReady is global variable that the native side can set
+    // to signify that the native code is ready. It is a global since
+    // it may be called before any cordova JS is ready.
+    if (window._nativeReady) {
+        channel.onNativeReady.fire();
+    }
+
+}(window));
+
+// file: lib/scripts/bootstrap-tizen.js
+require('cordova/channel').onNativeReady.fire();
+
+
+})();
\ No newline at end of file
diff --git a/framework/fake-native-tizen.js b/framework/fake-native-tizen.js
new file mode 100644
index 0000000..6bf15a1
--- /dev/null
+++ b/framework/fake-native-tizen.js
@@ -0,0 +1,9 @@
+var tizen = {
+	systeminfo: {}
+};
+
+tizen.systeminfo.getPropertyValue = function(name, successCallback, errorCallback) {
+	if (name === "Device") {
+		successCallback({model:"Tizen device", imei:"111111111", version:"1.0"});
+	}
+};
diff --git a/framework/icon.png b/framework/icon.png
new file mode 100644
index 0000000..03b3849
--- /dev/null
+++ b/framework/icon.png
Binary files differ
diff --git a/framework/index.html b/framework/index.html
new file mode 100644
index 0000000..5dff21e
--- /dev/null
+++ b/framework/index.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<script src="cordova-1.7.0.js"></script>
+		<link rel="stylesheet" type="text/css" href="tizen.css" />
+	</head>
+
+	<body>
+		<script>
+			document.addEventListener('deviceready', function () {
+				// Cordova is ready, do all your stuf here
+				console.log("Cordova is ready for platform " + window.device.platform + " v" + window.device.version + "!");
+			}, false);
+		</script>
+	</body>
+</html>
diff --git a/framework/sounds/beep.wav b/framework/sounds/beep.wav
new file mode 100644
index 0000000..1e9797c
--- /dev/null
+++ b/framework/sounds/beep.wav
Binary files differ
diff --git a/framework/tizen.css b/framework/tizen.css
new file mode 100644
index 0000000..8993e0f
--- /dev/null
+++ b/framework/tizen.css
@@ -0,0 +1,62 @@
+.ui-popupwindow-screen {
+	background: #000000;
+	opacity: 0.4;
+}
+.ui-popupwindow {
+	background: #828282;
+	padding: 1px 1px;
+	color: white;
+	width: 80%;
+	margin-left: 10%;
+}
+
+.popup-title {
+	background: #018ccc;
+	padding: 5px 5px;
+}
+
+.popup-title p {
+	padding: 0px;
+	margin: 0px;
+	text-align: center;
+}
+
+.popup-text {
+	background: #2d2d2d;
+	padding: 5px 5px;
+}
+
+.popup-text p {
+	padding: 0px;
+	margin: 0px;
+	text-align: center;
+	vertical-align: middle;
+	line-height:100px;
+}
+
+.popup-button-bg {
+	background: #424242;
+	padding: 5px 5px;
+}
+
+.popup-button-bg ul {
+	list-style-type:none;
+	width: 80%;
+	margin-left: 10%;
+	text-align: center;
+	padding: 0px;
+}
+
+.popup-button-bg li {
+	display: inline;
+}
+
+.popup-button-bg li input {
+	border-radius:4px 4px 4px 4px;
+	border: 0px;
+	background: #545454;
+	padding:5px 15px;
+	color: white;
+	min-width: 80px;
+	margin: 0px 5px;
+}
diff --git a/js/cordova.tizen-debug.js b/js/cordova.tizen-debug.js
new file mode 100644
index 0000000..03c7512
--- /dev/null
+++ b/js/cordova.tizen-debug.js
@@ -0,0 +1,114 @@
+// commit 7dd17b00544742d14ecdeff2148a66480680f12b
+
+// File generated at :: Thu Jul 26 2012 17:32:56 GMT+0200 (CEST)
+
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+;(function() {
+
+try {eval("var require,\n    define;\n\n(function () {\n    var modules = {};\n\n    function build(module) {\n        var factory = module.factory;\n        module.exports = {};\n        delete module.factory;\n        factory(require, module.exports, module);\n        return module.exports;\n    }\n\n    require = function (id) {\n        if (!modules[id]) {\n            throw \"module \" + id + \" not found\";\n        }\n        return modules[id].factory ? build(modules[id]) : modules[id].exports;\n    };\n\n    define = function (id, factory) {\n        if (modules[id]) {\n            throw \"module \" + id + \" already defined\";\n        }\n\n        modules[id] = {\n            id: id,\n            factory: factory\n        };\n    };\n\n    define.remove = function (id) {\n        delete modules[id];\n    };\n\n})();\n\n//Export for use in node\nif (typeof module === \"object\" && typeof require === \"function\") {\n    module.exports.require = require;\n    module.exports.define = define;\n}\n//@ sourceURL=lib/scripts/require.js")} catch(e) {console.log("exception: in lib/scripts/require.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova\", function(require, exports, module) {\nvar channel = require('cordova/channel');\n\n/**\n * Listen for DOMContentLoaded and notify our channel subscribers.\n */\ndocument.addEventListener('DOMContentLoaded', function() {\n    channel.onDOMContentLoaded.fire();\n}, false);\nif (document.readyState == 'complete' || document.readyState == 'interactive') {\n    channel.onDOMContentLoaded.fire();\n}\n\n/**\n * Intercept calls to addEventListener + removeEventListener and handle deviceready,\n * resume, and pause events.\n */\nvar m_document_addEventListener = document.addEventListener;\nvar m_document_removeEventListener = document.removeEventListener;\nvar m_window_addEventListener = window.addEventListener;\nvar m_window_removeEventListener = window.removeEventListener;\n\n/**\n * Houses custom event handlers to intercept on document + window event listeners.\n */\nvar documentEventHandlers = {},\n    windowEventHandlers = {};\n\ndocument.addEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    if (typeof documentEventHandlers[e] != 'undefined') {\n        if (evt === 'deviceready') {\n            documentEventHandlers[e].subscribeOnce(handler);\n        } else {\n            documentEventHandlers[e].subscribe(handler);\n        }\n    } else {\n        m_document_addEventListener.call(document, evt, handler, capture);\n    }\n};\n\nwindow.addEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    if (typeof windowEventHandlers[e] != 'undefined') {\n        windowEventHandlers[e].subscribe(handler);\n    } else {\n        m_window_addEventListener.call(window, evt, handler, capture);\n    }\n};\n\ndocument.removeEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    // If unsubcribing from an event that is handled by a plugin\n    if (typeof documentEventHandlers[e] != \"undefined\") {\n        documentEventHandlers[e].unsubscribe(handler);\n    } else {\n        m_document_removeEventListener.call(document, evt, handler, capture);\n    }\n};\n\nwindow.removeEventListener = function(evt, handler, capture) {\n    var e = evt.toLowerCase();\n    // If unsubcribing from an event that is handled by a plugin\n    if (typeof windowEventHandlers[e] != \"undefined\") {\n        windowEventHandlers[e].unsubscribe(handler);\n    } else {\n        m_window_removeEventListener.call(window, evt, handler, capture);\n    }\n};\n\nfunction createEvent(type, data) {\n    var event = document.createEvent('Events');\n    event.initEvent(type, false, false);\n    if (data) {\n        for (var i in data) {\n            if (data.hasOwnProperty(i)) {\n                event[i] = data[i];\n            }\n        }\n    }\n    return event;\n}\n\nif(typeof window.console === \"undefined\") {\n    window.console = {\n        log:function(){}\n    };\n}\n\nvar cordova = {\n    define:define,\n    require:require,\n    /**\n     * Methods to add/remove your own addEventListener hijacking on document + window.\n     */\n    addWindowEventHandler:function(event, opts) {\n        return (windowEventHandlers[event] = channel.create(event, opts));\n    },\n    addDocumentEventHandler:function(event, opts) {\n        return (documentEventHandlers[event] = channel.create(event, opts));\n    },\n    removeWindowEventHandler:function(event) {\n        delete windowEventHandlers[event];\n    },\n    removeDocumentEventHandler:function(event) {\n        delete documentEventHandlers[event];\n    },\n    /**\n     * Retreive original event handlers that were replaced by Cordova\n     *\n     * @return object\n     */\n    getOriginalHandlers: function() {\n        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},\n        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};\n    },\n    /**\n     * Method to fire event from native code\n     */\n    fireDocumentEvent: function(type, data) {\n        var evt = createEvent(type, data);\n        if (typeof documentEventHandlers[type] != 'undefined') {\n            setTimeout(function() {\n                documentEventHandlers[type].fire(evt);\n            }, 0);\n        } else {\n            document.dispatchEvent(evt);\n        }\n    },\n    fireWindowEvent: function(type, data) {\n        var evt = createEvent(type,data);\n        if (typeof windowEventHandlers[type] != 'undefined') {\n            setTimeout(function() {\n                windowEventHandlers[type].fire(evt);\n            }, 0);\n        } else {\n            window.dispatchEvent(evt);\n        }\n    },\n    // TODO: this is Android only; think about how to do this better\n    shuttingDown:false,\n    UsePolling:false,\n    // END TODO\n\n    // TODO: iOS only\n    // This queue holds the currently executing command and all pending\n    // commands executed with cordova.exec().\n    commandQueue:[],\n    // Indicates if we're currently in the middle of flushing the command\n    // queue on the native side.\n    commandQueueFlushing:false,\n    // END TODO\n    /**\n     * Plugin callback mechanism.\n     */\n    callbackId: 0,\n    callbacks:  {},\n    callbackStatus: {\n        NO_RESULT: 0,\n        OK: 1,\n        CLASS_NOT_FOUND_EXCEPTION: 2,\n        ILLEGAL_ACCESS_EXCEPTION: 3,\n        INSTANTIATION_EXCEPTION: 4,\n        MALFORMED_URL_EXCEPTION: 5,\n        IO_EXCEPTION: 6,\n        INVALID_ACTION: 7,\n        JSON_EXCEPTION: 8,\n        ERROR: 9\n    },\n\n    /**\n     * Called by native code when returning successful result from an action.\n     *\n     * @param callbackId\n     * @param args\n     */\n    callbackSuccess: function(callbackId, args) {\n        if (cordova.callbacks[callbackId]) {\n\n            // If result is to be sent to callback\n            if (args.status == cordova.callbackStatus.OK) {\n                try {\n                    if (cordova.callbacks[callbackId].success) {\n                        cordova.callbacks[callbackId].success(args.message);\n                    }\n                }\n                catch (e) {\n                    console.log(\"Error in success callback: \"+callbackId+\" = \"+e);\n                }\n            }\n\n            // Clear callback if not expecting any more results\n            if (!args.keepCallback) {\n                delete cordova.callbacks[callbackId];\n            }\n        }\n    },\n\n    /**\n     * Called by native code when returning error result from an action.\n     *\n     * @param callbackId\n     * @param args\n     */\n    callbackError: function(callbackId, args) {\n        if (cordova.callbacks[callbackId]) {\n            try {\n                if (cordova.callbacks[callbackId].fail) {\n                    cordova.callbacks[callbackId].fail(args.message);\n                }\n            }\n            catch (e) {\n                console.log(\"Error in error callback: \"+callbackId+\" = \"+e);\n            }\n\n            // Clear callback if not expecting any more results\n            if (!args.keepCallback) {\n                delete cordova.callbacks[callbackId];\n            }\n        }\n    },\n    addConstructor: function(func) {\n        channel.onCordovaReady.subscribeOnce(function() {\n            try {\n                func();\n            } catch(e) {\n                console.log(\"Failed to run constructor: \" + e);\n            }\n        });\n    }\n};\n\n// Register pause, resume and deviceready channels as events on document.\nchannel.onPause = cordova.addDocumentEventHandler('pause');\nchannel.onResume = cordova.addDocumentEventHandler('resume');\nchannel.onDeviceReady = cordova.addDocumentEventHandler('deviceready');\n\nmodule.exports = cordova;\n\n});\n\n//@ sourceURL=lib/cordova.js")} catch(e) {console.log("exception: in lib/cordova.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/builder\", function(require, exports, module) {\nvar utils = require('cordova/utils');\n\nfunction each(objects, func, context) {\n    for (var prop in objects) {\n        if (objects.hasOwnProperty(prop)) {\n            func.apply(context, [objects[prop], prop]);\n        }\n    }\n}\n\nfunction include(parent, objects, clobber, merge) {\n    each(objects, function (obj, key) {\n        try {\n          var result = obj.path ? require(obj.path) : {};\n\n          if (clobber) {\n              // Clobber if it doesn't exist.\n              if (typeof parent[key] === 'undefined') {\n                  parent[key] = result;\n              } else if (typeof obj.path !== 'undefined') {\n                  // If merging, merge properties onto parent, otherwise, clobber.\n                  if (merge) {\n                      recursiveMerge(parent[key], result);\n                  } else {\n                      parent[key] = result;\n                  }\n              }\n              result = parent[key];\n          } else {\n            // Overwrite if not currently defined.\n            if (typeof parent[key] == 'undefined') {\n              parent[key] = result;\n            } else if (merge && typeof obj.path !== 'undefined') {\n              // If merging, merge parent onto result\n              recursiveMerge(result, parent[key]);\n              parent[key] = result;\n            } else {\n              // Set result to what already exists, so we can build children into it if they exist.\n              result = parent[key];\n            }\n          }\n\n          if (obj.children) {\n            include(result, obj.children, clobber, merge);\n          }\n        } catch(e) {\n          utils.alert('Exception building cordova JS globals: ' + e + ' for key \"' + key + '\"');\n        }\n    });\n}\n\n/**\n * Merge properties from one object onto another recursively.  Properties from\n * the src object will overwrite existing target property.\n *\n * @param target Object to merge properties into.\n * @param src Object to merge properties from.\n */\nfunction recursiveMerge(target, src) {\n    for (var prop in src) {\n        if (src.hasOwnProperty(prop)) {\n            if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) {\n                // If the target object is a constructor override off prototype.\n                target.prototype[prop] = src[prop];\n            } else {\n                target[prop] = typeof src[prop] === 'object' ? recursiveMerge(\n                        target[prop], src[prop]) : src[prop];\n            }\n        }\n    }\n    return target;\n}\n\nmodule.exports = {\n    build: function (objects) {\n        return {\n            intoButDontClobber: function (target) {\n                include(target, objects, false, false);\n            },\n            intoAndClobber: function(target) {\n                include(target, objects, true, false);\n            },\n            intoAndMerge: function(target) {\n                include(target, objects, true, true);\n            }\n        };\n    }\n};\n\n});\n\n//@ sourceURL=lib/common/builder.js")} catch(e) {console.log("exception: in lib/common/builder.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/channel\", function(require, exports, module) {\nvar utils = require('cordova/utils');\n\n/**\n * Custom pub-sub \"channel\" that can have functions subscribed to it\n * This object is used to define and control firing of events for\n * cordova initialization.\n *\n * The order of events during page load and Cordova startup is as follows:\n *\n * onDOMContentLoaded         Internal event that is received when the web page is loaded and parsed.\n * onNativeReady              Internal event that indicates the Cordova native side is ready.\n * onCordovaReady             Internal event fired when all Cordova JavaScript objects have been created.\n * onCordovaInfoReady         Internal event fired when device properties are available.\n * onCordovaConnectionReady   Internal event fired when the connection property has been set.\n * onDeviceReady              User event fired to indicate that Cordova is ready\n * onResume                   User event fired to indicate a start/resume lifecycle event\n * onPause                    User event fired to indicate a pause lifecycle event\n * onDestroy                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).\n *\n * The only Cordova events that user code should register for are:\n *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript\n *      pause                 App has moved to background\n *      resume                App has returned to foreground\n *\n * Listeners can be registered as:\n *      document.addEventListener(\"deviceready\", myDeviceReadyListener, false);\n *      document.addEventListener(\"resume\", myResumeListener, false);\n *      document.addEventListener(\"pause\", myPauseListener, false);\n *\n * The DOM lifecycle events should be used for saving and restoring state\n *      window.onload\n *      window.onunload\n *\n */\n\n/**\n * Channel\n * @constructor\n * @param type  String the channel name\n * @param opts  Object options to pass into the channel, currently\n *                     supports:\n *                     onSubscribe: callback that fires when\n *                       something subscribes to the Channel. Sets\n *                       context to the Channel.\n *                     onUnsubscribe: callback that fires when\n *                       something unsubscribes to the Channel. Sets\n *                       context to the Channel.\n */\nvar Channel = function(type, opts) {\n    this.type = type;\n    this.handlers = {};\n    this.numHandlers = 0;\n    this.guid = 1;\n    this.fired = false;\n    this.enabled = true;\n    this.events = {\n        onSubscribe:null,\n        onUnsubscribe:null\n    };\n    if (opts) {\n        if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe;\n        if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe;\n    }\n},\n    channel = {\n        /**\n         * Calls the provided function only after all of the channels specified\n         * have been fired.\n         */\n        join: function (h, c) {\n            var i = c.length;\n            var len = i;\n            var f = function() {\n                if (!(--i)) h();\n            };\n            for (var j=0; j<len; j++) {\n                !c[j].fired?c[j].subscribeOnce(f):i--;\n            }\n            if (!i) h();\n        },\n        create: function (type, opts) {\n            channel[type] = new Channel(type, opts);\n            return channel[type];\n        },\n\n        /**\n         * cordova Channels that must fire before \"deviceready\" is fired.\n         */\n        deviceReadyChannelsArray: [],\n        deviceReadyChannelsMap: {},\n\n        /**\n         * Indicate that a feature needs to be initialized before it is ready to be used.\n         * This holds up Cordova's \"deviceready\" event until the feature has been initialized\n         * and Cordova.initComplete(feature) is called.\n         *\n         * @param feature {String}     The unique feature name\n         */\n        waitForInitialization: function(feature) {\n            if (feature) {\n                var c = null;\n                if (this[feature]) {\n                    c = this[feature];\n                }\n                else {\n                    c = this.create(feature);\n                }\n                this.deviceReadyChannelsMap[feature] = c;\n                this.deviceReadyChannelsArray.push(c);\n            }\n        },\n\n        /**\n         * Indicate that initialization code has completed and the feature is ready to be used.\n         *\n         * @param feature {String}     The unique feature name\n         */\n        initializationComplete: function(feature) {\n            var c = this.deviceReadyChannelsMap[feature];\n            if (c) {\n                c.fire();\n            }\n        }\n    };\n\nfunction forceFunction(f) {\n    if (f === null || f === undefined || typeof f != 'function') throw \"Function required as first argument!\";\n}\n\n/**\n * Subscribes the given function to the channel. Any time that\n * Channel.fire is called so too will the function.\n * Optionally specify an execution context for the function\n * and a guid that can be used to stop subscribing to the channel.\n * Returns the guid.\n */\nChannel.prototype.subscribe = function(f, c, g) {\n    // need a function to call\n    forceFunction(f);\n\n    var func = f;\n    if (typeof c == \"object\") { func = utils.close(c, f); }\n\n    g = g || func.observer_guid || f.observer_guid;\n    if (!g) {\n        // first time we've seen this subscriber\n        g = this.guid++;\n    }\n    else {\n        // subscriber already handled; dont set it twice\n        return g;\n    }\n    func.observer_guid = g;\n    f.observer_guid = g;\n    this.handlers[g] = func;\n    this.numHandlers++;\n    if (this.events.onSubscribe) this.events.onSubscribe.call(this);\n    if (this.fired) func.call(this);\n    return g;\n};\n\n/**\n * Like subscribe but the function is only called once and then it\n * auto-unsubscribes itself.\n */\nChannel.prototype.subscribeOnce = function(f, c) {\n    // need a function to call\n    forceFunction(f);\n\n    var g = null;\n    var _this = this;\n    var m = function() {\n        f.apply(c || null, arguments);\n        _this.unsubscribe(g);\n    };\n    if (this.fired) {\n        if (typeof c == \"object\") { f = utils.close(c, f); }\n        f.apply(this, this.fireArgs);\n    } else {\n        g = this.subscribe(m);\n    }\n    return g;\n};\n\n/**\n * Unsubscribes the function with the given guid from the channel.\n */\nChannel.prototype.unsubscribe = function(g) {\n    // need a function to unsubscribe\n    if (g === null || g === undefined) { throw \"You must pass _something_ into Channel.unsubscribe\"; }\n\n    if (typeof g == 'function') { g = g.observer_guid; }\n    var handler = this.handlers[g];\n    if (handler) {\n        if (handler.observer_guid) handler.observer_guid=null;\n        this.handlers[g] = null;\n        delete this.handlers[g];\n        this.numHandlers--;\n        if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);\n    }\n};\n\n/**\n * Calls all functions subscribed to this channel.\n */\nChannel.prototype.fire = function(e) {\n    if (this.enabled) {\n        var fail = false;\n        this.fired = true;\n        for (var item in this.handlers) {\n            var handler = this.handlers[item];\n            if (typeof handler == 'function') {\n                var rv = (handler.apply(this, arguments)===false);\n                fail = fail || rv;\n            }\n        }\n        this.fireArgs = arguments;\n        return !fail;\n    }\n    return true;\n};\n\n// defining them here so they are ready super fast!\n// DOM event that is received when the web page is loaded and parsed.\nchannel.create('onDOMContentLoaded');\n\n// Event to indicate the Cordova native side is ready.\nchannel.create('onNativeReady');\n\n// Event to indicate that all Cordova JavaScript objects have been created\n// and it's time to run plugin constructors.\nchannel.create('onCordovaReady');\n\n// Event to indicate that device properties are available\nchannel.create('onCordovaInfoReady');\n\n// Event to indicate that the connection property has been set.\nchannel.create('onCordovaConnectionReady');\n\n// Event to indicate that Cordova is ready\nchannel.create('onDeviceReady');\n\n// Event to indicate a resume lifecycle event\nchannel.create('onResume');\n\n// Event to indicate a pause lifecycle event\nchannel.create('onPause');\n\n// Event to indicate a destroy lifecycle event\nchannel.create('onDestroy');\n\n// Channels that must fire before \"deviceready\" is fired.\nchannel.waitForInitialization('onCordovaReady');\nchannel.waitForInitialization('onCordovaConnectionReady');\n\nmodule.exports = channel;\n\n});\n\n//@ sourceURL=lib/common/channel.js")} catch(e) {console.log("exception: in lib/common/channel.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/common\", function(require, exports, module) {\nmodule.exports = {\n    objects: {\n        cordova: {\n            path: 'cordova',\n            children: {\n                exec: {\n                    path: 'cordova/exec'\n                },\n                logger: {\n                    path: 'cordova/plugin/logger'\n                }\n            }\n        },\n        Cordova: {\n            children: {\n                exec: {\n                    path: 'cordova/exec'\n                }\n            }\n        },\n        PhoneGap:{\n            children: {\n                exec: {\n                    path: 'cordova/exec'\n                }\n            }\n        },\n        navigator: {\n            children: {\n                notification: {\n                    path: 'cordova/plugin/notification'\n                },\n                accelerometer: {\n                    path: 'cordova/plugin/accelerometer'\n                },\n                battery: {\n                    path: 'cordova/plugin/battery'\n                },\n                camera:{\n                    path: 'cordova/plugin/Camera'\n                },\n                compass:{\n                    path: 'cordova/plugin/compass'\n                },\n                contacts: {\n                    path: 'cordova/plugin/contacts'\n                },\n                device:{\n                    children:{\n                        capture: {\n                            path: 'cordova/plugin/capture'\n                        }\n                    }\n                },\n                geolocation: {\n                    path: 'cordova/plugin/geolocation'\n                },\n                network: {\n                    children: {\n                        connection: {\n                            path: 'cordova/plugin/network'\n                        }\n                    }\n                },\n                splashscreen: {\n                    path: 'cordova/plugin/splashscreen'\n                }\n            }\n        },\n        Acceleration: {\n            path: 'cordova/plugin/Acceleration'\n        },\n        Camera:{\n            path: 'cordova/plugin/CameraConstants'\n        },\n        CameraPopoverOptions: {\n            path: 'cordova/plugin/CameraPopoverOptions'\n        },\n        CaptureError: {\n            path: 'cordova/plugin/CaptureError'\n        },\n        CaptureAudioOptions:{\n            path: 'cordova/plugin/CaptureAudioOptions'\n        },\n        CaptureImageOptions: {\n            path: 'cordova/plugin/CaptureImageOptions'\n        },\n        CaptureVideoOptions: {\n            path: 'cordova/plugin/CaptureVideoOptions'\n        },\n        CompassHeading:{\n            path: 'cordova/plugin/CompassHeading'\n        },\n        CompassError:{\n            path: 'cordova/plugin/CompassError'\n        },\n        ConfigurationData: {\n            path: 'cordova/plugin/ConfigurationData'\n        },\n        Connection: {\n            path: 'cordova/plugin/Connection'\n        },\n        Contact: {\n            path: 'cordova/plugin/Contact'\n        },\n        ContactAddress: {\n            path: 'cordova/plugin/ContactAddress'\n        },\n        ContactError: {\n            path: 'cordova/plugin/ContactError'\n        },\n        ContactField: {\n            path: 'cordova/plugin/ContactField'\n        },\n        ContactFindOptions: {\n            path: 'cordova/plugin/ContactFindOptions'\n        },\n        ContactName: {\n            path: 'cordova/plugin/ContactName'\n        },\n        ContactOrganization: {\n            path: 'cordova/plugin/ContactOrganization'\n        },\n        Coordinates: {\n            path: 'cordova/plugin/Coordinates'\n        },\n        device: {\n            path: 'cordova/plugin/device'\n        },\n        DirectoryEntry: {\n            path: 'cordova/plugin/DirectoryEntry'\n        },\n        DirectoryReader: {\n            path: 'cordova/plugin/DirectoryReader'\n        },\n        Entry: {\n            path: 'cordova/plugin/Entry'\n        },\n        File: {\n            path: 'cordova/plugin/File'\n        },\n        FileEntry: {\n            path: 'cordova/plugin/FileEntry'\n        },\n        FileError: {\n            path: 'cordova/plugin/FileError'\n        },\n        FileReader: {\n            path: 'cordova/plugin/FileReader'\n        },\n        FileSystem: {\n            path: 'cordova/plugin/FileSystem'\n        },\n        FileTransfer: {\n            path: 'cordova/plugin/FileTransfer'\n        },\n        FileTransferError: {\n            path: 'cordova/plugin/FileTransferError'\n        },\n        FileUploadOptions: {\n            path: 'cordova/plugin/FileUploadOptions'\n        },\n        FileUploadResult: {\n            path: 'cordova/plugin/FileUploadResult'\n        },\n        FileWriter: {\n            path: 'cordova/plugin/FileWriter'\n        },\n        Flags: {\n            path: 'cordova/plugin/Flags'\n        },\n        LocalFileSystem: {\n            path: 'cordova/plugin/LocalFileSystem'\n        },\n        Media: {\n            path: 'cordova/plugin/Media'\n        },\n        MediaError: {\n            path: 'cordova/plugin/MediaError'\n        },\n        MediaFile: {\n            path: 'cordova/plugin/MediaFile'\n        },\n        MediaFileData:{\n            path: 'cordova/plugin/MediaFileData'\n        },\n        Metadata:{\n            path: 'cordova/plugin/Metadata'\n        },\n        Position: {\n            path: 'cordova/plugin/Position'\n        },\n        PositionError: {\n            path: 'cordova/plugin/PositionError'\n        },\n        ProgressEvent: {\n            path: 'cordova/plugin/ProgressEvent'\n        },\n        requestFileSystem:{\n            path: 'cordova/plugin/requestFileSystem'\n        },\n        resolveLocalFileSystemURI:{\n            path: 'cordova/plugin/resolveLocalFileSystemURI'\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/common/common.js")} catch(e) {console.log("exception: in lib/common/common.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/exec\", function(require, exports, module) {\n/**\n * Execute a cordova command.  It is up to the native side whether this action\n * is synchronous or asynchronous.  The native side can return:\n *      Synchronous: PluginResult object as a JSON string\n *      Asynchrounous: Empty string \"\"\n * If async, the native side will cordova.callbackSuccess or cordova.callbackError,\n * depending upon the result of the action.\n *\n * @param {Function} successCB  The success callback\n * @param {Function} failCB     The fail callback\n * @param {String} service      The name of the service to use\n * @param {String} action       Action to be run in cordova\n * @param {String[]} [args]     Zero or more arguments to pass to the method\n */\n\nvar tizen = require('cordova/plugin/tizen/manager'),\n    cordova = require('cordova'),\n    utils = require('cordova/utils');\n\nmodule.exports = function(successCB, failCB, service, action, args) {\n\n    try {\n        var v = tizen.exec(successCB, failCB, service, action, args);\n\n        // If status is OK, then return value back to caller\n        if (v.status == cordova.callbackStatus.OK) {\n\n            // If there is a success callback, then call it now with returned value\n            if (successCB) {\n                try {\n                    successCB(v.message);\n                }\n                catch (e) {\n                    console.log(\"Error in success callback: \"+ service + \".\" + action + \" = \" + e);\n                }\n\n            }\n            return v.message;\n        } else if (v.status == cordova.callbackStatus.NO_RESULT) {\n            // Nothing to do here\n        } else {\n            // If error, then display error\n            console.log(\"Error: \" + service + \".\" + action + \" Status=\" + v.status + \" Message=\" + v.message);\n\n            // If there is a fail callback, then call it now with returned value\n            if (failCB) {\n                try {\n                    failCB(v.message);\n                }\n                catch (e) {\n                    console.log(\"Error in error callback: \" + service + \".\" + action + \" = \"+e);\n                }\n            }\n            return null;\n        }\n    } catch (e) {\n        utils.alert(\"Error: \" + e);\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/exec.js")} catch(e) {console.log("exception: in lib/tizen/exec.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/platform\", function(require, exports, module) {\nmodule.exports = {\n    id: \"tizen\",\n    initialize: function() {},\n    objects: {\n        device: {\n            path: \"cordova/plugin/tizen/Device\"\n        },\n        File: { // exists natively, override\n            path: \"cordova/plugin/File\"\n        },\n        FileReader: { // exists natively, override\n            path: \"cordova/plugin/FileReader\"\n        },\n        FileError: { //exists natively, override\n            path: \"cordova/plugin/FileError\"\n        }\n    },\n    merges: {\n        MediaError: { // exists natively\n            path: \"cordova/plugin/tizen/MediaError\"\n        },\n        navigator: {\n            children: {\n                device: {\n                    path: \"cordova/plugin/tizen/Device\"\n                },\n                contacts: {\n                    path: \"cordova/plugin/tizen/contacts\"\n                },\n               notification: {\n                   path: \"cordova/plugin/tizen/Notification\"\n               }\n            }\n        },\n        Contact: {\n            path: \"cordova/plugin/tizen/Contact\"\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/platform.js")} catch(e) {console.log("exception: in lib/tizen/platform.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Acceleration\", function(require, exports, module) {\nvar Acceleration = function(x, y, z, timestamp) {\n    this.x = x;\n    this.y = y;\n    this.z = z;\n    this.timestamp = timestamp || (new Date()).getTime();\n};\n\nmodule.exports = Acceleration;\n\n});\n\n//@ sourceURL=lib/common/plugin/Acceleration.js")} catch(e) {console.log("exception: in lib/common/plugin/Acceleration.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Camera\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    Camera = require('cordova/plugin/CameraConstants');\n\nvar cameraExport = {};\n\n// Tack on the Camera Constants to the base camera plugin.\nfor (var key in Camera) {\n    cameraExport[key] = Camera[key];\n}\n\n/**\n * Gets a picture from source defined by \"options.sourceType\", and returns the\n * image as defined by the \"options.destinationType\" option.\n\n * The defaults are sourceType=CAMERA and destinationType=FILE_URI.\n *\n * @param {Function} successCallback\n * @param {Function} errorCallback\n * @param {Object} options\n */\ncameraExport.getPicture = function(successCallback, errorCallback, options) {\n    // successCallback required\n    if (typeof successCallback != \"function\") {\n        console.log(\"Camera Error: successCallback is not a function\");\n        return;\n    }\n\n    // errorCallback optional\n    if (errorCallback && (typeof errorCallback != \"function\")) {\n        console.log(\"Camera Error: errorCallback is not a function\");\n        return;\n    }\n\n    var quality = 50;\n    if (options && typeof options.quality == \"number\") {\n        quality = options.quality;\n    } else if (options && typeof options.quality == \"string\") {\n        var qlity = parseInt(options.quality, 10);\n        if (isNaN(qlity) === false) {\n            quality = qlity.valueOf();\n        }\n    }\n\n    var destinationType = Camera.DestinationType.FILE_URI;\n    if (typeof options.destinationType == \"number\") {\n        destinationType = options.destinationType;\n    }\n\n    var sourceType = Camera.PictureSourceType.CAMERA;\n    if (typeof options.sourceType == \"number\") {\n        sourceType = options.sourceType;\n    }\n\n    var targetWidth = -1;\n    if (typeof options.targetWidth == \"number\") {\n        targetWidth = options.targetWidth;\n    } else if (typeof options.targetWidth == \"string\") {\n        var width = parseInt(options.targetWidth, 10);\n        if (isNaN(width) === false) {\n            targetWidth = width.valueOf();\n        }\n    }\n\n    var targetHeight = -1;\n    if (typeof options.targetHeight == \"number\") {\n        targetHeight = options.targetHeight;\n    } else if (typeof options.targetHeight == \"string\") {\n        var height = parseInt(options.targetHeight, 10);\n        if (isNaN(height) === false) {\n            targetHeight = height.valueOf();\n        }\n    }\n\n    var encodingType = Camera.EncodingType.JPEG;\n    if (typeof options.encodingType == \"number\") {\n        encodingType = options.encodingType;\n    }\n\n    var mediaType = Camera.MediaType.PICTURE;\n    if (typeof options.mediaType == \"number\") {\n        mediaType = options.mediaType;\n    }\n    var allowEdit = false;\n    if (typeof options.allowEdit == \"boolean\") {\n        allowEdit = options.allowEdit;\n    } else if (typeof options.allowEdit == \"number\") {\n        allowEdit = options.allowEdit <= 0 ? false : true;\n    }\n    var correctOrientation = false;\n    if (typeof options.correctOrientation == \"boolean\") {\n        correctOrientation = options.correctOrientation;\n    } else if (typeof options.correctOrientation == \"number\") {\n        correctOrientation = options.correctOrientation <=0 ? false : true;\n    }\n    var saveToPhotoAlbum = false;\n    if (typeof options.saveToPhotoAlbum == \"boolean\") {\n        saveToPhotoAlbum = options.saveToPhotoAlbum;\n    } else if (typeof options.saveToPhotoAlbum == \"number\") {\n        saveToPhotoAlbum = options.saveToPhotoAlbum <=0 ? false : true;\n    }\n    var popoverOptions = null;\n    if (typeof options.popoverOptions == \"object\") {\n        popoverOptions = options.popoverOptions;\n    }\n\n    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,\n                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];\n\n    exec(successCallback, errorCallback, \"Camera\", \"takePicture\", args);\n};\n\ncameraExport.cleanup = function(successCallback, errorCallback) {\n    exec(successCallback, errorCallback, \"Camera\", \"cleanup\", []);\n};\n\nmodule.exports = cameraExport;\n});\n\n//@ sourceURL=lib/common/plugin/Camera.js")} catch(e) {console.log("exception: in lib/common/plugin/Camera.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CameraConstants\", function(require, exports, module) {\nmodule.exports = {\n  DestinationType:{\n    DATA_URL: 0,         // Return base64 encoded string\n    FILE_URI: 1          // Return file uri (content://media/external/images/media/2 for Android)\n  },\n  EncodingType:{\n    JPEG: 0,             // Return JPEG encoded image\n    PNG: 1               // Return PNG encoded image\n  },\n  MediaType:{\n    PICTURE: 0,          // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType\n    VIDEO: 1,            // allow selection of video only, ONLY RETURNS URL\n    ALLMEDIA : 2         // allow selection from all media types\n  },\n  PictureSourceType:{\n    PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)\n    CAMERA : 1,          // Take picture from camera\n    SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)\n  },\n  PopoverArrowDirection:{\n      ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover\n      ARROW_DOWN : 2,\n      ARROW_LEFT : 4,\n      ARROW_RIGHT : 8,\n      ARROW_ANY : 15\n  }\n};\n});\n\n//@ sourceURL=lib/common/plugin/CameraConstants.js")} catch(e) {console.log("exception: in lib/common/plugin/CameraConstants.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CameraPopoverOptions\", function(require, exports, module) {\nvar Camera = require('cordova/plugin/CameraConstants');\n\n/**\n * Encapsulates options for iOS Popover image picker\n */\nvar CameraPopoverOptions = function(x,y,width,height,arrowDir){\n    // information of rectangle that popover should be anchored to\n    this.x = x || 0;\n    this.y = y || 32;\n    this.width = width || 320;\n    this.height = height || 480;\n    // The direction of the popover arrow\n    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;\n};\n\nmodule.exports = CameraPopoverOptions;\n});\n\n//@ sourceURL=lib/common/plugin/CameraPopoverOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/CameraPopoverOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureAudioOptions\", function(require, exports, module) {\n/**\n * Encapsulates all audio capture operation configuration options.\n */\nvar CaptureAudioOptions = function(){\n    // Upper limit of sound clips user can record. Value must be equal or greater than 1.\n    this.limit = 1;\n    // Maximum duration of a single sound clip in seconds.\n    this.duration = 0;\n    // The selected audio mode. Must match with one of the elements in supportedAudioModes array.\n    this.mode = null;\n};\n\nmodule.exports = CaptureAudioOptions;\n});\n\n//@ sourceURL=lib/common/plugin/CaptureAudioOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/CaptureAudioOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureError\", function(require, exports, module) {\n/**\n * The CaptureError interface encapsulates all errors in the Capture API.\n */\nvar CaptureError = function(c) {\n   this.code = c || null;\n};\n\n// Camera or microphone failed to capture image or sound.\nCaptureError.CAPTURE_INTERNAL_ERR = 0;\n// Camera application or audio capture application is currently serving other capture request.\nCaptureError.CAPTURE_APPLICATION_BUSY = 1;\n// Invalid use of the API (e.g. limit parameter has value less than one).\nCaptureError.CAPTURE_INVALID_ARGUMENT = 2;\n// User exited camera application or audio capture application before capturing anything.\nCaptureError.CAPTURE_NO_MEDIA_FILES = 3;\n// The requested capture operation is not supported.\nCaptureError.CAPTURE_NOT_SUPPORTED = 20;\n\nmodule.exports = CaptureError;\n});\n\n//@ sourceURL=lib/common/plugin/CaptureError.js")} catch(e) {console.log("exception: in lib/common/plugin/CaptureError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureImageOptions\", function(require, exports, module) {\n/**\n * Encapsulates all image capture operation configuration options.\n */\nvar CaptureImageOptions = function(){\n    // Upper limit of images user can take. Value must be equal or greater than 1.\n    this.limit = 1;\n    // The selected image mode. Must match with one of the elements in supportedImageModes array.\n    this.mode = null;\n};\n\nmodule.exports = CaptureImageOptions;\n});\n\n//@ sourceURL=lib/common/plugin/CaptureImageOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/CaptureImageOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CaptureVideoOptions\", function(require, exports, module) {\n/**\n * Encapsulates all video capture operation configuration options.\n */\nvar CaptureVideoOptions = function(){\n    // Upper limit of videos user can record. Value must be equal or greater than 1.\n    this.limit = 1;\n    // Maximum duration of a single video clip in seconds.\n    this.duration = 0;\n    // The selected video mode. Must match with one of the elements in supportedVideoModes array.\n    this.mode = null;\n};\n\nmodule.exports = CaptureVideoOptions;\n});\n\n//@ sourceURL=lib/common/plugin/CaptureVideoOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/CaptureVideoOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CompassError\", function(require, exports, module) {\n/**\n *  CompassError.\n *  An error code assigned by an implementation when an error has occured\n * @constructor\n */\nvar CompassError = function(err) {\n    this.code = (err !== undefined ? err : null);\n};\n\nCompassError.COMPASS_INTERNAL_ERR = 0;\nCompassError.COMPASS_NOT_SUPPORTED = 20;\n\nmodule.exports = CompassError;\n});\n\n//@ sourceURL=lib/common/plugin/CompassError.js")} catch(e) {console.log("exception: in lib/common/plugin/CompassError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/CompassHeading\", function(require, exports, module) {\nvar CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {\n  this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null);\n  this.trueHeading = (trueHeading !== undefined ? trueHeading : null);\n  this.headingAccuracy = (headingAccuracy !== undefined ? headingAccuracy : null);\n  this.timestamp = (timestamp !== undefined ? timestamp : new Date().getTime());\n};\n\nmodule.exports = CompassHeading;\n});\n\n//@ sourceURL=lib/common/plugin/CompassHeading.js")} catch(e) {console.log("exception: in lib/common/plugin/CompassHeading.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ConfigurationData\", function(require, exports, module) {\n/**\n * Encapsulates a set of parameters that the capture device supports.\n */\nfunction ConfigurationData() {\n    // The ASCII-encoded string in lower case representing the media type.\n    this.type = null;\n    // The height attribute represents height of the image or video in pixels.\n    // In the case of a sound clip this attribute has value 0.\n    this.height = 0;\n    // The width attribute represents width of the image or video in pixels.\n    // In the case of a sound clip this attribute has value 0\n    this.width = 0;\n}\n\nmodule.exports = ConfigurationData;\n});\n\n//@ sourceURL=lib/common/plugin/ConfigurationData.js")} catch(e) {console.log("exception: in lib/common/plugin/ConfigurationData.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Connection\", function(require, exports, module) {\n/**\n * Network status\n */\nmodule.exports = {\n        UNKNOWN: \"unknown\",\n        ETHERNET: \"ethernet\",\n        WIFI: \"wifi\",\n        CELL_2G: \"2g\",\n        CELL_3G: \"3g\",\n        CELL_4G: \"4g\",\n        NONE: \"none\"\n};\n});\n\n//@ sourceURL=lib/common/plugin/Connection.js")} catch(e) {console.log("exception: in lib/common/plugin/Connection.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Contact\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    ContactError = require('cordova/plugin/ContactError'),\n    utils = require('cordova/utils');\n\n/**\n* Converts primitives into Complex Object\n* Currently only used for Date fields\n*/\nfunction convertIn(contact) {\n    var value = contact.birthday;\n    try {\n      contact.birthday = new Date(parseFloat(value));\n    } catch (exception){\n      console.log(\"Cordova Contact convertIn error: exception creating date.\");\n    }\n    return contact;\n}\n\n/**\n* Converts Complex objects into primitives\n* Only conversion at present is for Dates.\n**/\n\nfunction convertOut(contact) {\n    var value = contact.birthday;\n    if (value !== null) {\n        // try to make it a Date object if it is not already\n        if (!utils.isDate(value)){\n            try {\n                value = new Date(value);\n            } catch(exception){\n                value = null;\n            }\n        }\n        if (utils.isDate(value)){\n            value = value.valueOf(); // convert to milliseconds\n        }\n        contact.birthday = value;\n    }\n    return contact;\n}\n\n/**\n* Contains information about a single contact.\n* @constructor\n* @param {DOMString} id unique identifier\n* @param {DOMString} displayName\n* @param {ContactName} name\n* @param {DOMString} nickname\n* @param {Array.<ContactField>} phoneNumbers array of phone numbers\n* @param {Array.<ContactField>} emails array of email addresses\n* @param {Array.<ContactAddress>} addresses array of addresses\n* @param {Array.<ContactField>} ims instant messaging user ids\n* @param {Array.<ContactOrganization>} organizations\n* @param {DOMString} birthday contact's birthday\n* @param {DOMString} note user notes about contact\n* @param {Array.<ContactField>} photos\n* @param {Array.<ContactField>} categories\n* @param {Array.<ContactField>} urls contact's web sites\n*/\nvar Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,\n    ims, organizations, birthday, note, photos, categories, urls) {\n    this.id = id || null;\n    this.rawId = null;\n    this.displayName = displayName || null;\n    this.name = name || null; // ContactName\n    this.nickname = nickname || null;\n    this.phoneNumbers = phoneNumbers || null; // ContactField[]\n    this.emails = emails || null; // ContactField[]\n    this.addresses = addresses || null; // ContactAddress[]\n    this.ims = ims || null; // ContactField[]\n    this.organizations = organizations || null; // ContactOrganization[]\n    this.birthday = birthday || null;\n    this.note = note || null;\n    this.photos = photos || null; // ContactField[]\n    this.categories = categories || null; // ContactField[]\n    this.urls = urls || null; // ContactField[]\n};\n\n/**\n* Removes contact from device storage.\n* @param successCB success callback\n* @param errorCB error callback\n*/\nContact.prototype.remove = function(successCB, errorCB) {\n    var fail = function(code) {\n        errorCB(new ContactError(code));\n    };\n    if (this.id === null) {\n        fail(ContactError.UNKNOWN_ERROR);\n    }\n    else {\n        exec(successCB, fail, \"Contacts\", \"remove\", [this.id]);\n    }\n};\n\n/**\n* Creates a deep copy of this Contact.\n* With the contact ID set to null.\n* @return copy of this Contact\n*/\nContact.prototype.clone = function() {\n    var clonedContact = utils.clone(this);\n    var i;\n    clonedContact.id = null;\n    clonedContact.rawId = null;\n    // Loop through and clear out any id's in phones, emails, etc.\n    if (clonedContact.phoneNumbers) {\n        for (i = 0; i < clonedContact.phoneNumbers.length; i++) {\n            clonedContact.phoneNumbers[i].id = null;\n        }\n    }\n    if (clonedContact.emails) {\n        for (i = 0; i < clonedContact.emails.length; i++) {\n            clonedContact.emails[i].id = null;\n        }\n    }\n    if (clonedContact.addresses) {\n        for (i = 0; i < clonedContact.addresses.length; i++) {\n            clonedContact.addresses[i].id = null;\n        }\n    }\n    if (clonedContact.ims) {\n        for (i = 0; i < clonedContact.ims.length; i++) {\n            clonedContact.ims[i].id = null;\n        }\n    }\n    if (clonedContact.organizations) {\n        for (i = 0; i < clonedContact.organizations.length; i++) {\n            clonedContact.organizations[i].id = null;\n        }\n    }\n    if (clonedContact.categories) {\n        for (i = 0; i < clonedContact.categories.length; i++) {\n            clonedContact.categories[i].id = null;\n        }\n    }\n    if (clonedContact.photos) {\n        for (i = 0; i < clonedContact.photos.length; i++) {\n            clonedContact.photos[i].id = null;\n        }\n    }\n    if (clonedContact.urls) {\n        for (i = 0; i < clonedContact.urls.length; i++) {\n            clonedContact.urls[i].id = null;\n        }\n    }\n    return clonedContact;\n};\n\n/**\n* Persists contact to device storage.\n* @param successCB success callback\n* @param errorCB error callback\n*/\nContact.prototype.save = function(successCB, errorCB) {\n  var fail = function(code) {\n      errorCB(new ContactError(code));\n  };\n    var success = function(result) {\n      if (result) {\n          if (typeof successCB === 'function') {\n              var fullContact = require('cordova/plugin/contacts').create(result);\n              successCB(convertIn(fullContact));\n          }\n      }\n      else {\n          // no Entry object returned\n          fail(ContactError.UNKNOWN_ERROR);\n      }\n  };\n    var dupContact = convertOut(utils.clone(this));\n    exec(success, fail, \"Contacts\", \"save\", [dupContact]);\n};\n\n\nmodule.exports = Contact;\n\n});\n\n//@ sourceURL=lib/common/plugin/Contact.js")} catch(e) {console.log("exception: in lib/common/plugin/Contact.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactAddress\", function(require, exports, module) {\n/**\n* Contact address.\n* @constructor\n* @param {DOMString} id unique identifier, should only be set by native code\n* @param formatted // NOTE: not a W3C standard\n* @param streetAddress\n* @param locality\n* @param region\n* @param postalCode\n* @param country\n*/\n\nvar ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {\n    this.id = null;\n    this.pref = (typeof pref != 'undefined' ? pref : false);\n    this.type = type || null;\n    this.formatted = formatted || null;\n    this.streetAddress = streetAddress || null;\n    this.locality = locality || null;\n    this.region = region || null;\n    this.postalCode = postalCode || null;\n    this.country = country || null;\n};\n\nmodule.exports = ContactAddress;\n});\n\n//@ sourceURL=lib/common/plugin/ContactAddress.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactAddress.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactError\", function(require, exports, module) {\n/**\n *  ContactError.\n *  An error code assigned by an implementation when an error has occured\n * @constructor\n */\nvar ContactError = function(err) {\n    this.code = (typeof err != 'undefined' ? err : null);\n};\n\n/**\n * Error codes\n */\nContactError.UNKNOWN_ERROR = 0;\nContactError.INVALID_ARGUMENT_ERROR = 1;\nContactError.TIMEOUT_ERROR = 2;\nContactError.PENDING_OPERATION_ERROR = 3;\nContactError.IO_ERROR = 4;\nContactError.NOT_SUPPORTED_ERROR = 5;\nContactError.PERMISSION_DENIED_ERROR = 20;\n\nmodule.exports = ContactError;\n});\n\n//@ sourceURL=lib/common/plugin/ContactError.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactField\", function(require, exports, module) {\n/**\n* Generic contact field.\n* @constructor\n* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard\n* @param type\n* @param value\n* @param pref\n*/\nvar ContactField = function(type, value, pref) {\n    this.id = null;\n    this.type = (type && type.toString()) || null;\n    this.value = (value && value.toString()) || null;\n    this.pref = (typeof pref != 'undefined' ? pref : false);\n};\n\nmodule.exports = ContactField;\n});\n\n//@ sourceURL=lib/common/plugin/ContactField.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactField.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactFindOptions\", function(require, exports, module) {\n/**\n * ContactFindOptions.\n * @constructor\n * @param filter used to match contacts against\n * @param multiple boolean used to determine if more than one contact should be returned\n */\n\nvar ContactFindOptions = function(filter, multiple) {\n    this.filter = filter || '';\n    this.multiple = (typeof multiple != 'undefined' ? multiple : false);\n};\n\nmodule.exports = ContactFindOptions;\n});\n\n//@ sourceURL=lib/common/plugin/ContactFindOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactFindOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactName\", function(require, exports, module) {\n/**\n* Contact name.\n* @constructor\n* @param formatted // NOTE: not part of W3C standard\n* @param familyName\n* @param givenName\n* @param middle\n* @param prefix\n* @param suffix\n*/\nvar ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {\n    this.formatted = formatted || null;\n    this.familyName = familyName || null;\n    this.givenName = givenName || null;\n    this.middleName = middle || null;\n    this.honorificPrefix = prefix || null;\n    this.honorificSuffix = suffix || null;\n};\n\nmodule.exports = ContactName;\n});\n\n//@ sourceURL=lib/common/plugin/ContactName.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactName.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ContactOrganization\", function(require, exports, module) {\n/**\n* Contact organization.\n* @constructor\n* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard\n* @param name\n* @param dept\n* @param title\n* @param startDate\n* @param endDate\n* @param location\n* @param desc\n*/\n\nvar ContactOrganization = function(pref, type, name, dept, title) {\n    this.id = null;\n    this.pref = (typeof pref != 'undefined' ? pref : false);\n    this.type = type || null;\n    this.name = name || null;\n    this.department = dept || null;\n    this.title = title || null;\n};\n\nmodule.exports = ContactOrganization;\n});\n\n//@ sourceURL=lib/common/plugin/ContactOrganization.js")} catch(e) {console.log("exception: in lib/common/plugin/ContactOrganization.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Coordinates\", function(require, exports, module) {\n/**\n * This class contains position information.\n * @param {Object} lat\n * @param {Object} lng\n * @param {Object} alt\n * @param {Object} acc\n * @param {Object} head\n * @param {Object} vel\n * @param {Object} altacc\n * @constructor\n */\nvar Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {\n    /**\n     * The latitude of the position.\n     */\n    this.latitude = lat;\n    /**\n     * The longitude of the position,\n     */\n    this.longitude = lng;\n    /**\n     * The accuracy of the position.\n     */\n    this.accuracy = acc;\n    /**\n     * The altitude of the position.\n     */\n    this.altitude = (alt !== undefined ? alt : null);\n    /**\n     * The direction the device is moving at the position.\n     */\n    this.heading = (head !== undefined ? head : null);\n    /**\n     * The velocity with which the device is moving at the position.\n     */\n    this.speed = (vel !== undefined ? vel : null);\n\n    if (this.speed === 0 || this.speed === null) {\n        this.heading = NaN;\n    }\n\n    /**\n     * The altitude accuracy of the position.\n     */\n    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;\n};\n\nmodule.exports = Coordinates;\n\n});\n\n//@ sourceURL=lib/common/plugin/Coordinates.js")} catch(e) {console.log("exception: in lib/common/plugin/Coordinates.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/DirectoryEntry\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    Entry = require('cordova/plugin/Entry'),\n    FileError = require('cordova/plugin/FileError'),\n    DirectoryReader = require('cordova/plugin/DirectoryReader');\n\n/**\n * An interface representing a directory on the file system.\n *\n * {boolean} isFile always false (readonly)\n * {boolean} isDirectory always true (readonly)\n * {DOMString} name of the directory, excluding the path leading to it (readonly)\n * {DOMString} fullPath the absolute full path to the directory (readonly)\n * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)\n */\nvar DirectoryEntry = function(name, fullPath) {\n     DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]);\n};\n\nutils.extend(DirectoryEntry, Entry);\n\n/**\n * Creates a new DirectoryReader to read entries from this directory\n */\nDirectoryEntry.prototype.createReader = function() {\n    return new DirectoryReader(this.fullPath);\n};\n\n/**\n * Creates or looks up a directory\n *\n * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory\n * @param {Flags} options to create or excluively create the directory\n * @param {Function} successCallback is called with the new entry\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var entry = new DirectoryEntry(result.name, result.fullPath);\n        successCallback(entry);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getDirectory\", [this.fullPath, path, options]);\n};\n\n/**\n * Deletes a directory and all of it's contents\n *\n * @param {Function} successCallback is called with no parameters\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(successCallback, fail, \"File\", \"removeRecursively\", [this.fullPath]);\n};\n\n/**\n * Creates or looks up a file\n *\n * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file\n * @param {Flags} options to create or excluively create the file\n * @param {Function} successCallback is called with the new entry\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var FileEntry = require('cordova/plugin/FileEntry');\n        var entry = new FileEntry(result.name, result.fullPath);\n        successCallback(entry);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getFile\", [this.fullPath, path, options]);\n};\n\nmodule.exports = DirectoryEntry;\n\n});\n\n//@ sourceURL=lib/common/plugin/DirectoryEntry.js")} catch(e) {console.log("exception: in lib/common/plugin/DirectoryEntry.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/DirectoryReader\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError') ;\n\n/**\n * An interface that lists the files and directories in a directory.\n */\nfunction DirectoryReader(path) {\n    this.path = path || null;\n}\n\n/**\n * Returns a list of entries from a directory.\n *\n * @param {Function} successCallback is called with a list of entries\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var retVal = [];\n        for (var i=0; i<result.length; i++) {\n            var entry = null;\n            if (result[i].isDirectory) {\n                entry = new (require('cordova/plugin/DirectoryEntry'))();\n            }\n            else if (result[i].isFile) {\n                entry = new (require('cordova/plugin/FileEntry'))();\n            }\n            entry.isDirectory = result[i].isDirectory;\n            entry.isFile = result[i].isFile;\n            entry.name = result[i].name;\n            entry.fullPath = result[i].fullPath;\n            retVal.push(entry);\n        }\n        successCallback(retVal);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"readEntries\", [this.path]);\n};\n\nmodule.exports = DirectoryReader;\n\n});\n\n//@ sourceURL=lib/common/plugin/DirectoryReader.js")} catch(e) {console.log("exception: in lib/common/plugin/DirectoryReader.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Entry\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError'),\n    Metadata = require('cordova/plugin/Metadata');\n\n/**\n * Represents a file or directory on the local file system.\n *\n * @param isFile\n *            {boolean} true if Entry is a file (readonly)\n * @param isDirectory\n *            {boolean} true if Entry is a directory (readonly)\n * @param name\n *            {DOMString} name of the file or directory, excluding the path\n *            leading to it (readonly)\n * @param fullPath\n *            {DOMString} the absolute full path to the file or directory\n *            (readonly)\n */\nfunction Entry(isFile, isDirectory, name, fullPath, fileSystem) {\n    this.isFile = (typeof isFile != 'undefined'?isFile:false);\n    this.isDirectory = (typeof isDirectory != 'undefined'?isDirectory:false);\n    this.name = name || '';\n    this.fullPath = fullPath || '';\n    this.filesystem = fileSystem || null;\n}\n\n/**\n * Look up the metadata of the entry.\n *\n * @param successCallback\n *            {Function} is called with a Metadata object\n * @param errorCallback\n *            {Function} is called with a FileError\n */\nEntry.prototype.getMetadata = function(successCallback, errorCallback) {\n  var success = typeof successCallback !== 'function' ? null : function(lastModified) {\n      var metadata = new Metadata(lastModified);\n      successCallback(metadata);\n  };\n  var fail = typeof errorCallback !== 'function' ? null : function(code) {\n      errorCallback(new FileError(code));\n  };\n\n  exec(success, fail, \"File\", \"getMetadata\", [this.fullPath]);\n};\n\n/**\n * Set the metadata of the entry.\n *\n * @param successCallback\n *            {Function} is called with a Metadata object\n * @param errorCallback\n *            {Function} is called with a FileError\n * @param metadataObject\n *            {Object} keys and values to set\n */\nEntry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {\n\n  exec(successCallback, errorCallback, \"File\", \"setMetadata\", [this.fullPath, metadataObject]);\n};\n\n/**\n * Move a file or directory to a new location.\n *\n * @param parent\n *            {DirectoryEntry} the directory to which to move this entry\n * @param newName\n *            {DOMString} new name of the entry, defaults to the current name\n * @param successCallback\n *            {Function} called with the new DirectoryEntry object\n * @param errorCallback\n *            {Function} called with a FileError\n */\nEntry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {\n    var fail = function(code) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(code));\n        }\n    };\n    // user must specify parent Entry\n    if (!parent) {\n        fail(FileError.NOT_FOUND_ERR);\n        return;\n    }\n    // source path\n    var srcPath = this.fullPath,\n        // entry name\n        name = newName || this.name,\n        success = function(entry) {\n            if (entry) {\n                if (typeof successCallback === 'function') {\n                    // create appropriate Entry object\n                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);\n                    try {\n                        successCallback(result);\n                    }\n                    catch (e) {\n                        console.log('Error invoking callback: ' + e);\n                    }\n                }\n            }\n            else {\n                // no Entry object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n\n    // copy\n    exec(success, fail, \"File\", \"moveTo\", [srcPath, parent.fullPath, name]);\n};\n\n/**\n * Copy a directory to a different location.\n *\n * @param parent\n *            {DirectoryEntry} the directory to which to copy the entry\n * @param newName\n *            {DOMString} new name of the entry, defaults to the current name\n * @param successCallback\n *            {Function} called with the new Entry object\n * @param errorCallback\n *            {Function} called with a FileError\n */\nEntry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {\n    var fail = function(code) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(code));\n        }\n    };\n\n    // user must specify parent Entry\n    if (!parent) {\n        fail(FileError.NOT_FOUND_ERR);\n        return;\n    }\n\n        // source path\n    var srcPath = this.fullPath,\n        // entry name\n        name = newName || this.name,\n        // success callback\n        success = function(entry) {\n            if (entry) {\n                if (typeof successCallback === 'function') {\n                    // create appropriate Entry object\n                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);\n                    try {\n                        successCallback(result);\n                    }\n                    catch (e) {\n                        console.log('Error invoking callback: ' + e);\n                    }\n                }\n            }\n            else {\n                // no Entry object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n\n    // copy\n    exec(success, fail, \"File\", \"copyTo\", [srcPath, parent.fullPath, name]);\n};\n\n/**\n * Return a URL that can be used to identify this entry.\n */\nEntry.prototype.toURL = function() {\n    // fullPath attribute contains the full URL\n    return this.fullPath;\n};\n\n/**\n * Returns a URI that can be used to identify this entry.\n *\n * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.\n * @return uri\n */\nEntry.prototype.toURI = function(mimeType) {\n    console.log(\"DEPRECATED: Update your code to use 'toURL'\");\n    // fullPath attribute contains the full URI\n    return this.toURL();\n};\n\n/**\n * Remove a file or directory. It is an error to attempt to delete a\n * directory that is not empty. It is an error to attempt to delete a\n * root directory of a file system.\n *\n * @param successCallback {Function} called with no parameters\n * @param errorCallback {Function} called with a FileError\n */\nEntry.prototype.remove = function(successCallback, errorCallback) {\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(successCallback, fail, \"File\", \"remove\", [this.fullPath]);\n};\n\n/**\n * Look up the parent DirectoryEntry of this entry.\n *\n * @param successCallback {Function} called with the parent DirectoryEntry object\n * @param errorCallback {Function} called with a FileError\n */\nEntry.prototype.getParent = function(successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');\n        var entry = new DirectoryEntry(result.name, result.fullPath);\n        successCallback(entry);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getParent\", [this.fullPath]);\n};\n\nmodule.exports = Entry;\n});\n\n//@ sourceURL=lib/common/plugin/Entry.js")} catch(e) {console.log("exception: in lib/common/plugin/Entry.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/File\", function(require, exports, module) {\n/**\n * Constructor.\n * name {DOMString} name of the file, without path information\n * fullPath {DOMString} the full path of the file, including the name\n * type {DOMString} mime type\n * lastModifiedDate {Date} last modified date\n * size {Number} size of the file in bytes\n */\n\nvar File = function(name, fullPath, type, lastModifiedDate, size){\n    this.name = name || '';\n    this.fullPath = fullPath || null;\n    this.type = type || null;\n    this.lastModifiedDate = lastModifiedDate || null;\n    this.size = size || 0;\n};\n\nmodule.exports = File;\n});\n\n//@ sourceURL=lib/common/plugin/File.js")} catch(e) {console.log("exception: in lib/common/plugin/File.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileEntry\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    Entry = require('cordova/plugin/Entry'),\n    FileWriter = require('cordova/plugin/FileWriter'),\n    File = require('cordova/plugin/File'),\n    FileError = require('cordova/plugin/FileError');\n\n/**\n * An interface representing a file on the file system.\n *\n * {boolean} isFile always true (readonly)\n * {boolean} isDirectory always false (readonly)\n * {DOMString} name of the file, excluding the path leading to it (readonly)\n * {DOMString} fullPath the absolute full path to the file (readonly)\n * {FileSystem} filesystem on which the file resides (readonly)\n */\nvar FileEntry = function(name, fullPath) {\n     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);\n};\n\nutils.extend(FileEntry, Entry);\n\n/**\n * Creates a new FileWriter associated with the file that this FileEntry represents.\n *\n * @param {Function} successCallback is called with the new FileWriter\n * @param {Function} errorCallback is called with a FileError\n */\nFileEntry.prototype.createWriter = function(successCallback, errorCallback) {\n    this.file(function(filePointer) {\n        var writer = new FileWriter(filePointer);\n\n        if (writer.fileName === null || writer.fileName === \"\") {\n            if (typeof errorCallback === \"function\") {\n                errorCallback(new FileError(FileError.INVALID_STATE_ERR));\n            }\n        } else {\n            if (typeof successCallback === \"function\") {\n                successCallback(writer);\n            }\n        }\n    }, errorCallback);\n};\n\n/**\n * Returns a File that represents the current state of the file that this FileEntry represents.\n *\n * @param {Function} successCallback is called with the new File object\n * @param {Function} errorCallback is called with a FileError\n */\nFileEntry.prototype.file = function(successCallback, errorCallback) {\n    var win = typeof successCallback !== 'function' ? null : function(f) {\n        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);\n        successCallback(file);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getFileMetadata\", [this.fullPath]);\n};\n\n\nmodule.exports = FileEntry;\n});\n\n//@ sourceURL=lib/common/plugin/FileEntry.js")} catch(e) {console.log("exception: in lib/common/plugin/FileEntry.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileError\", function(require, exports, module) {\n/**\n * FileError\n */\nfunction FileError(error) {\n  this.code = error || null;\n}\n\n// File error codes\n// Found in DOMException\nFileError.NOT_FOUND_ERR = 1;\nFileError.SECURITY_ERR = 2;\nFileError.ABORT_ERR = 3;\n\n// Added by File API specification\nFileError.NOT_READABLE_ERR = 4;\nFileError.ENCODING_ERR = 5;\nFileError.NO_MODIFICATION_ALLOWED_ERR = 6;\nFileError.INVALID_STATE_ERR = 7;\nFileError.SYNTAX_ERR = 8;\nFileError.INVALID_MODIFICATION_ERR = 9;\nFileError.QUOTA_EXCEEDED_ERR = 10;\nFileError.TYPE_MISMATCH_ERR = 11;\nFileError.PATH_EXISTS_ERR = 12;\n\nmodule.exports = FileError;\n});\n\n//@ sourceURL=lib/common/plugin/FileError.js")} catch(e) {console.log("exception: in lib/common/plugin/FileError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileReader\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError'),\n    ProgressEvent = require('cordova/plugin/ProgressEvent');\n\n/**\n * This class reads the mobile device file system.\n *\n * For Android:\n *      The root directory is the root of the file system.\n *      To read from the SD card, the file name is \"sdcard/my_file.txt\"\n * @constructor\n */\nvar FileReader = function() {\n    this.fileName = \"\";\n\n    this.readyState = 0; // FileReader.EMPTY\n\n    // File data\n    this.result = null;\n\n    // Error\n    this.error = null;\n\n    // Event handlers\n    this.onloadstart = null;    // When the read starts.\n    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total)\n    this.onload = null;         // When the read has successfully completed.\n    this.onerror = null;        // When the read has failed (see errors).\n    this.onloadend = null;      // When the request has completed (either in success or failure).\n    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.\n};\n\n// States\nFileReader.EMPTY = 0;\nFileReader.LOADING = 1;\nFileReader.DONE = 2;\n\n/**\n * Abort reading file.\n */\nFileReader.prototype.abort = function() {\n    this.result = null;\n\n    if (this.readyState == FileReader.DONE || this.readyState == FileReader.EMPTY) {\n      return;\n    }\n\n    this.readyState = FileReader.DONE;\n\n    // If abort callback\n    if (typeof this.onabort === 'function') {\n        this.onabort(new ProgressEvent('abort', {target:this}));\n    }\n    // If load end callback\n    if (typeof this.onloadend === 'function') {\n        this.onloadend(new ProgressEvent('loadend', {target:this}));\n    }\n};\n\n/**\n * Read text file.\n *\n * @param file          {File} File object containing file properties\n * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)\n */\nFileReader.prototype.readAsText = function(file, encoding) {\n    // Figure out pathing\n    this.fileName = '';\n    if (typeof file.fullPath === 'undefined') {\n        this.fileName = file;\n    } else {\n        this.fileName = file.fullPath;\n    }\n\n    // Already loading something\n    if (this.readyState == FileReader.LOADING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // LOADING state\n    this.readyState = FileReader.LOADING;\n\n    // If loadstart callback\n    if (typeof this.onloadstart === \"function\") {\n        this.onloadstart(new ProgressEvent(\"loadstart\", {target:this}));\n    }\n\n    // Default encoding is UTF-8\n    var enc = encoding ? encoding : \"UTF-8\";\n\n    var me = this;\n\n    // Read file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // Save result\n            me.result = r;\n\n            // If onload callback\n            if (typeof me.onload === \"function\") {\n                me.onload(new ProgressEvent(\"load\", {target:me}));\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            // null result\n            me.result = null;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {target:me}));\n            }\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        }, \"File\", \"readAsText\", [this.fileName, enc]);\n};\n\n\n/**\n * Read file and return data as a base64 encoded data url.\n * A data url is of the form:\n *      data:[<mediatype>][;base64],<data>\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsDataURL = function(file) {\n    this.fileName = \"\";\n    if (typeof file.fullPath === \"undefined\") {\n        this.fileName = file;\n    } else {\n        this.fileName = file.fullPath;\n    }\n\n    // Already loading something\n    if (this.readyState == FileReader.LOADING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // LOADING state\n    this.readyState = FileReader.LOADING;\n\n    // If loadstart callback\n    if (typeof this.onloadstart === \"function\") {\n        this.onloadstart(new ProgressEvent(\"loadstart\", {target:this}));\n    }\n\n    var me = this;\n\n    // Read file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            // Save result\n            me.result = r;\n\n            // If onload callback\n            if (typeof me.onload === \"function\") {\n                me.onload(new ProgressEvent(\"load\", {target:me}));\n            }\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileReader.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileReader.DONE;\n\n            me.result = null;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {target:me}));\n            }\n\n            // If onloadend callback\n            if (typeof me.onloadend === \"function\") {\n                me.onloadend(new ProgressEvent(\"loadend\", {target:me}));\n            }\n        }, \"File\", \"readAsDataURL\", [this.fileName]);\n};\n\n/**\n * Read file and return data as a binary data.\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsBinaryString = function(file) {\n    // TODO - Can't return binary data to browser.\n    console.log('method \"readAsBinaryString\" is not supported at this time.');\n};\n\n/**\n * Read file and return data as a binary data.\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsArrayBuffer = function(file) {\n    // TODO - Can't return binary data to browser.\n    console.log('This method is not supported at this time.');\n};\n\nmodule.exports = FileReader;\n});\n\n//@ sourceURL=lib/common/plugin/FileReader.js")} catch(e) {console.log("exception: in lib/common/plugin/FileReader.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileSystem\", function(require, exports, module) {\nvar DirectoryEntry = require('cordova/plugin/DirectoryEntry');\n\n/**\n * An interface representing a file system\n *\n * @constructor\n * {DOMString} name the unique name of the file system (readonly)\n * {DirectoryEntry} root directory of the file system (readonly)\n */\nvar FileSystem = function(name, root) {\n    this.name = name || null;\n    if (root) {\n        this.root = new DirectoryEntry(root.name, root.fullPath);\n    }\n};\n\nmodule.exports = FileSystem;\n\n});\n\n//@ sourceURL=lib/common/plugin/FileSystem.js")} catch(e) {console.log("exception: in lib/common/plugin/FileSystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileTransfer\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileTransferError = require('cordova/plugin/FileTransferError');\n\n/**\n * FileTransfer uploads a file to a remote server.\n * @constructor\n */\nvar FileTransfer = function() {};\n\n/**\n* Given an absolute file path, uploads a file on the device to a remote server\n* using a multipart HTTP request.\n* @param filePath {String}           Full path of the file on the device\n* @param server {String}             URL of the server to receive the file\n* @param successCallback (Function}  Callback to be invoked when upload has completed\n* @param errorCallback {Function}    Callback to be invoked upon error\n* @param options {FileUploadOptions} Optional parameters such as file name and mimetype\n* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n*/\nFileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {\n    // sanity parameter checking\n    if (!filePath || !server) throw new Error(\"FileTransfer.upload requires filePath and server URL parameters at the minimum.\");\n    // check for options\n    var fileKey = null;\n    var fileName = null;\n    var mimeType = null;\n    var params = null;\n    var chunkedMode = true;\n    if (options) {\n        fileKey = options.fileKey;\n        fileName = options.fileName;\n        mimeType = options.mimeType;\n        if (options.chunkedMode !== null || typeof options.chunkedMode != \"undefined\") {\n            chunkedMode = options.chunkedMode;\n        }\n        if (options.params) {\n            params = options.params;\n        }\n        else {\n            params = {};\n        }\n    }\n\n    var fail = function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);\n        errorCallback(error);\n    };\n\n    exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]);\n};\n\n/**\n * Downloads a file form a given URL and saves it to the specified directory.\n * @param source {String}          URL of the server to receive the file\n * @param target {String}         Full path of the file on the device\n * @param successCallback (Function}  Callback to be invoked when upload has completed\n * @param errorCallback {Function}    Callback to be invoked upon error\n */\nFileTransfer.prototype.download = function(source, target, successCallback, errorCallback) {\n    // sanity parameter checking\n    if (!source || !target) throw new Error(\"FileTransfer.download requires source URI and target URI parameters at the minimum.\");\n    var win = function(result) {\n        var entry = null;\n        if (result.isDirectory) {\n            entry = new (require('cordova/plugin/DirectoryEntry'))();\n        }\n        else if (result.isFile) {\n            entry = new (require('cordova/plugin/FileEntry'))();\n        }\n        entry.isDirectory = result.isDirectory;\n        entry.isFile = result.isFile;\n        entry.name = result.name;\n        entry.fullPath = result.fullPath;\n        successCallback(entry);\n    };\n\n    var fail = function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);\n        errorCallback(error);\n    };\n\n    exec(win, errorCallback, 'FileTransfer', 'download', [source, target]);\n};\n\nmodule.exports = FileTransfer;\n\n});\n\n//@ sourceURL=lib/common/plugin/FileTransfer.js")} catch(e) {console.log("exception: in lib/common/plugin/FileTransfer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileTransferError\", function(require, exports, module) {\n/**\n * FileTransferError\n * @constructor\n */\nvar FileTransferError = function(code, source, target, status) {\n    this.code = code || null;\n    this.source = source || null;\n    this.target = target || null;\n    this.http_status = status || null;\n};\n\nFileTransferError.FILE_NOT_FOUND_ERR = 1;\nFileTransferError.INVALID_URL_ERR = 2;\nFileTransferError.CONNECTION_ERR = 3;\n\nmodule.exports = FileTransferError;\n\n});\n\n//@ sourceURL=lib/common/plugin/FileTransferError.js")} catch(e) {console.log("exception: in lib/common/plugin/FileTransferError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileUploadOptions\", function(require, exports, module) {\n/**\n * Options to customize the HTTP request used to upload files.\n * @constructor\n * @param fileKey {String}   Name of file request parameter.\n * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.\n * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.\n * @param params {Object}    Object with key: value params to send to the server.\n */\nvar FileUploadOptions = function(fileKey, fileName, mimeType, params) {\n    this.fileKey = fileKey || null;\n    this.fileName = fileName || null;\n    this.mimeType = mimeType || null;\n    this.params = params || null;\n};\n\nmodule.exports = FileUploadOptions;\n});\n\n//@ sourceURL=lib/common/plugin/FileUploadOptions.js")} catch(e) {console.log("exception: in lib/common/plugin/FileUploadOptions.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileUploadResult\", function(require, exports, module) {\n/**\n * FileUploadResult\n * @constructor\n */\nvar FileUploadResult = function() {\n    this.bytesSent = 0;\n    this.responseCode = null;\n    this.response = null;\n};\n\nmodule.exports = FileUploadResult;\n});\n\n//@ sourceURL=lib/common/plugin/FileUploadResult.js")} catch(e) {console.log("exception: in lib/common/plugin/FileUploadResult.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/FileWriter\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    FileError = require('cordova/plugin/FileError'),\n    ProgressEvent = require('cordova/plugin/ProgressEvent');\n\n/**\n * This class writes to the mobile device file system.\n *\n * For Android:\n *      The root directory is the root of the file system.\n *      To write to the SD card, the file name is \"sdcard/my_file.txt\"\n *\n * @constructor\n * @param file {File} File object containing file properties\n * @param append if true write to the end of the file, otherwise overwrite the file\n */\nvar FileWriter = function(file) {\n    this.fileName = \"\";\n    this.length = 0;\n    if (file) {\n        this.fileName = file.fullPath || file;\n        this.length = file.size || 0;\n    }\n    // default is to write at the beginning of the file\n    this.position = 0;\n\n    this.readyState = 0; // EMPTY\n\n    this.result = null;\n\n    // Error\n    this.error = null;\n\n    // Event handlers\n    this.onwritestart = null;   // When writing starts\n    this.onprogress = null;     // While writing the file, and reporting partial file data\n    this.onwrite = null;        // When the write has successfully completed.\n    this.onwriteend = null;     // When the request has completed (either in success or failure).\n    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.\n    this.onerror = null;        // When the write has failed (see errors).\n};\n\n// States\nFileWriter.INIT = 0;\nFileWriter.WRITING = 1;\nFileWriter.DONE = 2;\n\n/**\n * Abort writing file.\n */\nFileWriter.prototype.abort = function() {\n    // check for invalid state\n    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // set error\n    this.error = new FileError(FileError.ABORT_ERR);\n\n    this.readyState = FileWriter.DONE;\n\n    // If abort callback\n    if (typeof this.onabort === \"function\") {\n        this.onabort(new ProgressEvent(\"abort\", {\"target\":this}));\n    }\n\n    // If write end callback\n    if (typeof this.onwriteend === \"function\") {\n        this.onwriteend(new ProgressEvent(\"writeend\", {\"target\":this}));\n    }\n};\n\n/**\n * Writes data to the file\n *\n * @param text to be written\n */\nFileWriter.prototype.write = function(text) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // WRITING state\n    this.readyState = FileWriter.WRITING;\n\n    var me = this;\n\n    // If onwritestart callback\n    if (typeof me.onwritestart === \"function\") {\n        me.onwritestart(new ProgressEvent(\"writestart\", {\"target\":me}));\n    }\n\n    // Write file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // position always increases by bytes written because file would be extended\n            me.position += r;\n            // The length of the file is now where we are done writing.\n\n            me.length = me.position;\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // If onwrite callback\n            if (typeof me.onwrite === \"function\") {\n                me.onwrite(new ProgressEvent(\"write\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        }, \"File\", \"write\", [this.fileName, text, this.position]);\n};\n\n/**\n * Moves the file pointer to the location specified.\n *\n * If the offset is a negative number the position of the file\n * pointer is rewound.  If the offset is greater than the file\n * size the position is set to the end of the file.\n *\n * @param offset is the location to move the file pointer to.\n */\nFileWriter.prototype.seek = function(offset) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    if (!offset && offset !== 0) {\n        return;\n    }\n\n    // See back from end of file.\n    if (offset < 0) {\n        this.position = Math.max(offset + this.length, 0);\n    }\n    // Offset is bigger then file size so set position\n    // to the end of the file.\n    else if (offset > this.length) {\n        this.position = this.length;\n    }\n    // Offset is between 0 and file size so set the position\n    // to start writing.\n    else {\n        this.position = offset;\n    }\n};\n\n/**\n * Truncates the file to the size specified.\n *\n * @param size to chop the file at.\n */\nFileWriter.prototype.truncate = function(size) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // WRITING state\n    this.readyState = FileWriter.WRITING;\n\n    var me = this;\n\n    // If onwritestart callback\n    if (typeof me.onwritestart === \"function\") {\n        me.onwritestart(new ProgressEvent(\"writestart\", {\"target\":this}));\n    }\n\n    // Write file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Update the length of the file\n            me.length = r;\n            me.position = Math.min(me.position, r);\n\n            // If onwrite callback\n            if (typeof me.onwrite === \"function\") {\n                me.onwrite(new ProgressEvent(\"write\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        }, \"File\", \"truncate\", [this.fileName, size]);\n};\n\nmodule.exports = FileWriter;\n\n});\n\n//@ sourceURL=lib/common/plugin/FileWriter.js")} catch(e) {console.log("exception: in lib/common/plugin/FileWriter.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Flags\", function(require, exports, module) {\n/**\n * Supplies arguments to methods that lookup or create files and directories.\n *\n * @param create\n *            {boolean} file or directory if it doesn't exist\n * @param exclusive\n *            {boolean} used with create; if true the command will fail if\n *            target path exists\n */\nfunction Flags(create, exclusive) {\n    this.create = create || false;\n    this.exclusive = exclusive || false;\n}\n\nmodule.exports = Flags;\n});\n\n//@ sourceURL=lib/common/plugin/Flags.js")} catch(e) {console.log("exception: in lib/common/plugin/Flags.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/LocalFileSystem\", function(require, exports, module) {\nvar exec = require('cordova/exec');\n\n/**\n * Represents a local file system.\n */\nvar LocalFileSystem = function() {\n\n};\n\nLocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence\nLocalFileSystem.PERSISTENT = 1; //persistent\n\nmodule.exports = LocalFileSystem;\n});\n\n//@ sourceURL=lib/common/plugin/LocalFileSystem.js")} catch(e) {console.log("exception: in lib/common/plugin/LocalFileSystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Media\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec');\n\nvar mediaObjects = {};\n\n/**\n * This class provides access to the device media, interfaces to both sound and video\n *\n * @constructor\n * @param src                   The file name or url to play\n * @param successCallback       The callback to be called when the file is done playing or recording.\n *                                  successCallback()\n * @param errorCallback         The callback to be called if there is an error.\n *                                  errorCallback(int errorCode) - OPTIONAL\n * @param statusCallback        The callback to be called when media status has changed.\n *                                  statusCallback(int statusCode) - OPTIONAL\n */\nvar Media = function(src, successCallback, errorCallback, statusCallback) {\n\n    // successCallback optional\n    if (successCallback && (typeof successCallback !== \"function\")) {\n        console.log(\"Media Error: successCallback is not a function\");\n        return;\n    }\n\n    // errorCallback optional\n    if (errorCallback && (typeof errorCallback !== \"function\")) {\n        console.log(\"Media Error: errorCallback is not a function\");\n        return;\n    }\n\n    // statusCallback optional\n    if (statusCallback && (typeof statusCallback !== \"function\")) {\n        console.log(\"Media Error: statusCallback is not a function\");\n        return;\n    }\n\n    this.id = utils.createUUID();\n    mediaObjects[this.id] = this;\n    this.src = src;\n    this.successCallback = successCallback;\n    this.errorCallback = errorCallback;\n    this.statusCallback = statusCallback;\n    this._duration = -1;\n    this._position = -1;\n    exec(null, this.errorCallback, \"Media\", \"create\", [this.id, this.src]);\n};\n\n// Media messages\nMedia.MEDIA_STATE = 1;\nMedia.MEDIA_DURATION = 2;\nMedia.MEDIA_POSITION = 3;\nMedia.MEDIA_ERROR = 9;\n\n// Media states\nMedia.MEDIA_NONE = 0;\nMedia.MEDIA_STARTING = 1;\nMedia.MEDIA_RUNNING = 2;\nMedia.MEDIA_PAUSED = 3;\nMedia.MEDIA_STOPPED = 4;\nMedia.MEDIA_MSG = [\"None\", \"Starting\", \"Running\", \"Paused\", \"Stopped\"];\n\n// \"static\" function to return existing objs.\nMedia.get = function(id) {\n    return mediaObjects[id];\n};\n\n/**\n * Start or resume playing audio file.\n */\nMedia.prototype.play = function(options) {\n    exec(null, null, \"Media\", \"startPlayingAudio\", [this.id, this.src, options]);\n};\n\n/**\n * Stop playing audio file.\n */\nMedia.prototype.stop = function() {\n    var me = this;\n    exec(function() {\n        me._position = 0;\n        me.successCallback();\n    }, this.errorCallback, \"Media\", \"stopPlayingAudio\", [this.id]);\n};\n\n/**\n * Seek or jump to a new time in the track..\n */\nMedia.prototype.seekTo = function(milliseconds) {\n    var me = this;\n    exec(function(p) {\n        me._position = p;\n    }, this.errorCallback, \"Media\", \"seekToAudio\", [this.id, milliseconds]);\n};\n\n/**\n * Pause playing audio file.\n */\nMedia.prototype.pause = function() {\n    exec(null, this.errorCallback, \"Media\", \"pausePlayingAudio\", [this.id]);\n};\n\n/**\n * Get duration of an audio file.\n * The duration is only set for audio that is playing, paused or stopped.\n *\n * @return      duration or -1 if not known.\n */\nMedia.prototype.getDuration = function() {\n    return this._duration;\n};\n\n/**\n * Get position of audio.\n */\nMedia.prototype.getCurrentPosition = function(success, fail) {\n    var me = this;\n    exec(function(p) {\n        me._position = p;\n        success(p);\n    }, fail, \"Media\", \"getCurrentPositionAudio\", [this.id]);\n};\n\n/**\n * Start recording audio file.\n */\nMedia.prototype.startRecord = function() {\n    exec(this.successCallback, this.errorCallback, \"Media\", \"startRecordingAudio\", [this.id, this.src]);\n};\n\n/**\n * Stop recording audio file.\n */\nMedia.prototype.stopRecord = function() {\n    exec(this.successCallback, this.errorCallback, \"Media\", \"stopRecordingAudio\", [this.id]);\n};\n\n/**\n * Release the resources.\n */\nMedia.prototype.release = function() {\n    exec(null, this.errorCallback, \"Media\", \"release\", [this.id]);\n};\n\n/**\n * Adjust the volume.\n */\nMedia.prototype.setVolume = function(volume) {\n    exec(null, null, \"Media\", \"setVolume\", [this.id, volume]);\n};\n\n/**\n * Audio has status update.\n * PRIVATE\n *\n * @param id            The media object id (string)\n * @param status        The status code (int)\n * @param msg           The status message (string)\n */\nMedia.onStatus = function(id, msg, value) {\n    var media = mediaObjects[id];\n    // If state update\n    if (msg === Media.MEDIA_STATE) {\n        if (value === Media.MEDIA_STOPPED) {\n            if (media.successCallback) {\n                media.successCallback();\n            }\n        }\n        if (media.statusCallback) {\n            media.statusCallback(value);\n        }\n    }\n    else if (msg === Media.MEDIA_DURATION) {\n        media._duration = value;\n    }\n    else if (msg === Media.MEDIA_ERROR) {\n        if (media.errorCallback) {\n            // value should be a MediaError object when msg == MEDIA_ERROR\n            media.errorCallback(value);\n        }\n    }\n    else if (msg === Media.MEDIA_POSITION) {\n        media._position = value;\n    }\n};\n\nmodule.exports = Media;\n});\n\n//@ sourceURL=lib/common/plugin/Media.js")} catch(e) {console.log("exception: in lib/common/plugin/Media.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/MediaError\", function(require, exports, module) {\n/**\n * This class contains information about any Media errors.\n * @constructor\n */\nvar MediaError = function(code, msg) {\n    this.code = (code !== undefined ? code : null);\n    this.message = msg || \"\";\n};\n\nMediaError.MEDIA_ERR_NONE_ACTIVE    = 0;\nMediaError.MEDIA_ERR_ABORTED        = 1;\nMediaError.MEDIA_ERR_NETWORK        = 2;\nMediaError.MEDIA_ERR_DECODE         = 3;\nMediaError.MEDIA_ERR_NONE_SUPPORTED = 4;\n\nmodule.exports = MediaError;\n});\n\n//@ sourceURL=lib/common/plugin/MediaError.js")} catch(e) {console.log("exception: in lib/common/plugin/MediaError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/MediaFile\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    File = require('cordova/plugin/File'),\n    CaptureError = require('cordova/plugin/CaptureError');\n/**\n * Represents a single file.\n *\n * name {DOMString} name of the file, without path information\n * fullPath {DOMString} the full path of the file, including the name\n * type {DOMString} mime type\n * lastModifiedDate {Date} last modified date\n * size {Number} size of the file in bytes\n */\nvar MediaFile = function(name, fullPath, type, lastModifiedDate, size){\n    MediaFile.__super__.constructor.apply(this, arguments);\n};\n\nutils.extend(MediaFile, File);\n\n/**\n * Request capture format data for a specific file and type\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n */\nMediaFile.prototype.getFormatData = function(successCallback, errorCallback) {\n    if (typeof this.fullPath === \"undefined\" || this.fullPath === null) {\n        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));\n    } else {\n        exec(successCallback, errorCallback, \"Capture\", \"getFormatData\", [this.fullPath, this.type]);\n    }\n};\n\n// TODO: can we axe this?\n/**\n * Casts a PluginResult message property  (array of objects) to an array of MediaFile objects\n * (used in Objective-C and Android)\n *\n * @param {PluginResult} pluginResult\n */\nMediaFile.cast = function(pluginResult) {\n    var mediaFiles = [];\n    for (var i=0; i<pluginResult.message.length; i++) {\n        var mediaFile = new MediaFile();\n        mediaFile.name = pluginResult.message[i].name;\n        mediaFile.fullPath = pluginResult.message[i].fullPath;\n        mediaFile.type = pluginResult.message[i].type;\n        mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate;\n        mediaFile.size = pluginResult.message[i].size;\n        mediaFiles.push(mediaFile);\n    }\n    pluginResult.message = mediaFiles;\n    return pluginResult;\n};\n\nmodule.exports = MediaFile;\n\n});\n\n//@ sourceURL=lib/common/plugin/MediaFile.js")} catch(e) {console.log("exception: in lib/common/plugin/MediaFile.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/MediaFileData\", function(require, exports, module) {\n/**\n * MediaFileData encapsulates format information of a media file.\n *\n * @param {DOMString} codecs\n * @param {long} bitrate\n * @param {long} height\n * @param {long} width\n * @param {float} duration\n */\nvar MediaFileData = function(codecs, bitrate, height, width, duration){\n    this.codecs = codecs || null;\n    this.bitrate = bitrate || 0;\n    this.height = height || 0;\n    this.width = width || 0;\n    this.duration = duration || 0;\n};\n\nmodule.exports = MediaFileData;\n});\n\n//@ sourceURL=lib/common/plugin/MediaFileData.js")} catch(e) {console.log("exception: in lib/common/plugin/MediaFileData.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Metadata\", function(require, exports, module) {\n/**\n * Information about the state of the file or directory\n *\n * {Date} modificationTime (readonly)\n */\nvar Metadata = function(time) {\n    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);\n};\n\nmodule.exports = Metadata;\n});\n\n//@ sourceURL=lib/common/plugin/Metadata.js")} catch(e) {console.log("exception: in lib/common/plugin/Metadata.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/Position\", function(require, exports, module) {\nvar Coordinates = require('cordova/plugin/Coordinates');\n\nvar Position = function(coords, timestamp) {\n    if (coords) {\n        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);\n    } else {\n        this.coords = new Coordinates();\n    }\n    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();\n};\n\nmodule.exports = Position;\n\n});\n\n//@ sourceURL=lib/common/plugin/Position.js")} catch(e) {console.log("exception: in lib/common/plugin/Position.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/PositionError\", function(require, exports, module) {\n/**\n * Position error object\n *\n * @constructor\n * @param code\n * @param message\n */\nvar PositionError = function(code, message) {\n    this.code = code || null;\n    this.message = message || '';\n};\n\nPositionError.PERMISSION_DENIED = 1;\nPositionError.POSITION_UNAVAILABLE = 2;\nPositionError.TIMEOUT = 3;\n\nmodule.exports = PositionError;\n});\n\n//@ sourceURL=lib/common/plugin/PositionError.js")} catch(e) {console.log("exception: in lib/common/plugin/PositionError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/ProgressEvent\", function(require, exports, module) {\n// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill\n// Feature test: See if we can instantiate a native ProgressEvent;\n// if so, use that approach,\n// otherwise fill-in with our own implementation.\n//\n// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.\nvar ProgressEvent = (function() {\n    /*\n    var createEvent = function(data) {\n        var event = document.createEvent('Events');\n        event.initEvent('ProgressEvent', false, false);\n        if (data) {\n            for (var i in data) {\n                if (data.hasOwnProperty(i)) {\n                    event[i] = data[i];\n                }\n            }\n            if (data.target) {\n                // TODO: cannot call <some_custom_object>.dispatchEvent\n                // need to first figure out how to implement EventTarget\n            }\n        }\n        return event;\n    };\n    try {\n        var ev = createEvent({type:\"abort\",target:document});\n        return function ProgressEvent(type, data) {\n            data.type = type;\n            return createEvent(data);\n        };\n    } catch(e){\n    */\n        return function ProgressEvent(type, dict) {\n            this.type = type;\n            this.bubbles = false;\n            this.cancelBubble = false;\n            this.cancelable = false;\n            this.lengthComputable = false;\n            this.loaded = dict && dict.loaded ? dict.loaded : 0;\n            this.total = dict && dict.total ? dict.total : 0;\n            this.target = dict && dict.target ? dict.target : null;\n        };\n    //}\n})();\n\nmodule.exports = ProgressEvent;\n});\n\n//@ sourceURL=lib/common/plugin/ProgressEvent.js")} catch(e) {console.log("exception: in lib/common/plugin/ProgressEvent.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/accelerometer\", function(require, exports, module) {\n/**\n * This class provides access to device accelerometer data.\n * @constructor\n */\nvar utils = require(\"cordova/utils\"),\n    exec = require(\"cordova/exec\"),\n    Acceleration = require('cordova/plugin/Acceleration');\n\n// Is the accel sensor running?\nvar running = false;\n\n// Keeps reference to watchAcceleration calls.\nvar timers = {};\n\n// Array of listeners; used to keep track of when we should call start and stop.\nvar listeners = [];\n\n// Last returned acceleration object from native\nvar accel = null;\n\n// Tells native to start.\nfunction start() {\n    exec(function(a) {\n        var tempListeners = listeners.slice(0);\n        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);\n        for (var i = 0, l = tempListeners.length; i < l; i++) {\n            tempListeners[i].win(accel);\n        }\n    }, function(e) {\n        var tempListeners = listeners.slice(0);\n        for (var i = 0, l = tempListeners.length; i < l; i++) {\n            tempListeners[i].fail(e);\n        }\n    }, \"Accelerometer\", \"start\", []);\n    running = true;\n}\n\n// Tells native to stop.\nfunction stop() {\n    exec(null, null, \"Accelerometer\", \"stop\", []);\n    running = false;\n}\n\n// Adds a callback pair to the listeners array\nfunction createCallbackPair(win, fail) {\n    return {win:win, fail:fail};\n}\n\n// Removes a win/fail listener pair from the listeners array\nfunction removeListeners(l) {\n    var idx = listeners.indexOf(l);\n    if (idx > -1) {\n        listeners.splice(idx, 1);\n        if (listeners.length === 0) {\n            stop();\n        }\n    }\n}\n\nvar accelerometer = {\n    /**\n     * Asynchronously aquires the current acceleration.\n     *\n     * @param {Function} successCallback    The function to call when the acceleration data is available\n     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)\n     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)\n     */\n    getCurrentAcceleration: function(successCallback, errorCallback, options) {\n        // successCallback required\n        if (typeof successCallback !== \"function\") {\n            throw \"getCurrentAcceleration must be called with at least a success callback function as first parameter.\";\n        }\n\n        var p;\n        var win = function(a) {\n            removeListeners(p);\n            successCallback(a);\n        };\n        var fail = function(e) {\n            removeListeners(p);\n            errorCallback(e);\n        };\n\n        p = createCallbackPair(win, fail);\n        listeners.push(p);\n\n        if (!running) {\n            start();\n        }\n    },\n\n    /**\n     * Asynchronously aquires the acceleration repeatedly at a given interval.\n     *\n     * @param {Function} successCallback    The function to call each time the acceleration data is available\n     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)\n     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)\n     * @return String                       The watch id that must be passed to #clearWatch to stop watching.\n     */\n    watchAcceleration: function(successCallback, errorCallback, options) {\n        // Default interval (10 sec)\n        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;\n\n        // successCallback required\n        if (typeof successCallback !== \"function\") {\n            throw \"watchAcceleration must be called with at least a success callback function as first parameter.\";\n        }\n\n        // Keep reference to watch id, and report accel readings as often as defined in frequency\n        var id = utils.createUUID();\n\n        var p = createCallbackPair(function(){}, function(e) {\n            removeListeners(p);\n            errorCallback(e);\n        });\n        listeners.push(p);\n\n        timers[id] = {\n            timer:window.setInterval(function() {\n                if (accel) {\n                    successCallback(accel);\n                }\n            }, frequency),\n            listeners:p\n        };\n\n        if (running) {\n            // If we're already running then immediately invoke the success callback\n            // but only if we have retreived a value, sample code does not check for null ...\n            if(accel) {\n                successCallback(accel);\n            }\n        } else {\n            start();\n        }\n\n        return id;\n    },\n\n    /**\n     * Clears the specified accelerometer watch.\n     *\n     * @param {String} id       The id of the watch returned from #watchAcceleration.\n     */\n    clearWatch: function(id) {\n        // Stop javascript timer & remove from timer list\n        if (id && timers[id]) {\n            window.clearInterval(timers[id].timer);\n            removeListeners(timers[id].listeners);\n            delete timers[id];\n        }\n    }\n};\n\nmodule.exports = accelerometer;\n\n});\n\n//@ sourceURL=lib/common/plugin/accelerometer.js")} catch(e) {console.log("exception: in lib/common/plugin/accelerometer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/battery\", function(require, exports, module) {\n/**\n * This class contains information about the current battery status.\n * @constructor\n */\nvar cordova = require('cordova'),\n    exec = require('cordova/exec');\n\nfunction handlers() {\n  return battery.channels.batterystatus.numHandlers +\n         battery.channels.batterylow.numHandlers +\n         battery.channels.batterycritical.numHandlers;\n}\n\nvar Battery = function() {\n    this._level = null;\n    this._isPlugged = null;\n    // Create new event handlers on the window (returns a channel instance)\n    var subscriptionEvents = {\n      onSubscribe:this.onSubscribe,\n      onUnsubscribe:this.onUnsubscribe\n    };\n    this.channels = {\n      batterystatus:cordova.addWindowEventHandler(\"batterystatus\", subscriptionEvents),\n      batterylow:cordova.addWindowEventHandler(\"batterylow\", subscriptionEvents),\n      batterycritical:cordova.addWindowEventHandler(\"batterycritical\", subscriptionEvents)\n    };\n};\n/**\n * Event handlers for when callbacks get registered for the battery.\n * Keep track of how many handlers we have so we can start and stop the native battery listener\n * appropriately (and hopefully save on battery life!).\n */\nBattery.prototype.onSubscribe = function() {\n  var me = battery;\n  // If we just registered the first handler, make sure native listener is started.\n  if (handlers() === 1) {\n    exec(me._status, me._error, \"Battery\", \"start\", []);\n  }\n};\n\nBattery.prototype.onUnsubscribe = function() {\n  var me = battery;\n\n  // If we just unregistered the last handler, make sure native listener is stopped.\n  if (handlers() === 0) {\n      exec(null, null, \"Battery\", \"stop\", []);\n  }\n};\n\n/**\n * Callback for battery status\n *\n * @param {Object} info            keys: level, isPlugged\n */\nBattery.prototype._status = function(info) {\n    if (info) {\n        var me = battery;\n    var level = info.level;\n        if (me._level !== level || me._isPlugged !== info.isPlugged) {\n            // Fire batterystatus event\n            cordova.fireWindowEvent(\"batterystatus\", info);\n\n            // Fire low battery event\n            if (level === 20 || level === 5) {\n                if (level === 20) {\n                    cordova.fireWindowEvent(\"batterylow\", info);\n                }\n                else {\n                    cordova.fireWindowEvent(\"batterycritical\", info);\n                }\n            }\n        }\n        me._level = level;\n        me._isPlugged = info.isPlugged;\n    }\n};\n\n/**\n * Error callback for battery start\n */\nBattery.prototype._error = function(e) {\n    console.log(\"Error initializing Battery: \" + e);\n};\n\nvar battery = new Battery();\n\nmodule.exports = battery;\n});\n\n//@ sourceURL=lib/common/plugin/battery.js")} catch(e) {console.log("exception: in lib/common/plugin/battery.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/capture\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    MediaFile = require('cordova/plugin/MediaFile');\n\n/**\n * Launches a capture of different types.\n *\n * @param (DOMString} type\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureVideoOptions} options\n */\nfunction _capture(type, successCallback, errorCallback, options) {\n    var win = function(pluginResult) {\n        var mediaFiles = [];\n        var i;\n        for (i = 0; i < pluginResult.length; i++) {\n            var mediaFile = new MediaFile();\n            mediaFile.name = pluginResult[i].name;\n            mediaFile.fullPath = pluginResult[i].fullPath;\n            mediaFile.type = pluginResult[i].type;\n            mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;\n            mediaFile.size = pluginResult[i].size;\n            mediaFiles.push(mediaFile);\n        }\n        successCallback(mediaFiles);\n    };\n    exec(win, errorCallback, \"Capture\", type, [options]);\n}\n/**\n * The Capture interface exposes an interface to the camera and microphone of the hosting device.\n */\nfunction Capture() {\n    this.supportedAudioModes = [];\n    this.supportedImageModes = [];\n    this.supportedVideoModes = [];\n}\n\n/**\n * Launch audio recorder application for recording audio clip(s).\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureAudioOptions} options\n */\nCapture.prototype.captureAudio = function(successCallback, errorCallback, options){\n    _capture(\"captureAudio\", successCallback, errorCallback, options);\n};\n\n/**\n * Launch camera application for taking image(s).\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureImageOptions} options\n */\nCapture.prototype.captureImage = function(successCallback, errorCallback, options){\n    _capture(\"captureImage\", successCallback, errorCallback, options);\n};\n\n/**\n * Launch device camera application for recording video(s).\n *\n * @param {Function} successCB\n * @param {Function} errorCB\n * @param {CaptureVideoOptions} options\n */\nCapture.prototype.captureVideo = function(successCallback, errorCallback, options){\n    _capture(\"captureVideo\", successCallback, errorCallback, options);\n};\n\n\nmodule.exports = new Capture();\n\n});\n\n//@ sourceURL=lib/common/plugin/capture.js")} catch(e) {console.log("exception: in lib/common/plugin/capture.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/compass\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    utils = require('cordova/utils'),\n    CompassHeading = require('cordova/plugin/CompassHeading'),\n    CompassError = require('cordova/plugin/CompassError'),\n    timers = {},\n    compass = {\n        /**\n         * Asynchronously acquires the current heading.\n         * @param {Function} successCallback The function to call when the heading\n         * data is available\n         * @param {Function} errorCallback The function to call when there is an error\n         * getting the heading data.\n         * @param {CompassOptions} options The options for getting the heading data (not used).\n         */\n        getCurrentHeading:function(successCallback, errorCallback, options) {\n            // successCallback required\n            if (typeof successCallback !== \"function\") {\n              console.log(\"Compass Error: successCallback is not a function\");\n              return;\n            }\n\n            // errorCallback optional\n            if (errorCallback && (typeof errorCallback !== \"function\")) {\n              console.log(\"Compass Error: errorCallback is not a function\");\n              return;\n            }\n\n            var win = function(result) {\n                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);\n                successCallback(ch);\n            };\n            var fail = function(code) {\n                var ce = new CompassError(code);\n                errorCallback(ce);\n            };\n\n            // Get heading\n            exec(win, fail, \"Compass\", \"getHeading\", [options]);\n        },\n\n        /**\n         * Asynchronously acquires the heading repeatedly at a given interval.\n         * @param {Function} successCallback The function to call each time the heading\n         * data is available\n         * @param {Function} errorCallback The function to call when there is an error\n         * getting the heading data.\n         * @param {HeadingOptions} options The options for getting the heading data\n         * such as timeout and the frequency of the watch. For iOS, filter parameter\n         * specifies to watch via a distance filter rather than time.\n         */\n        watchHeading:function(successCallback, errorCallback, options) {\n            // Default interval (100 msec)\n            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;\n            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;\n\n            // successCallback required\n            if (typeof successCallback !== \"function\") {\n              console.log(\"Compass Error: successCallback is not a function\");\n              return;\n            }\n\n            // errorCallback optional\n            if (errorCallback && (typeof errorCallback !== \"function\")) {\n              console.log(\"Compass Error: errorCallback is not a function\");\n              return;\n            }\n\n            var id = utils.createUUID();\n            if (filter > 0) {\n                // is an iOS request for watch by filter, no timer needed\n                timers[id] = \"iOS\";\n                compass.getCurrentHeading(successCallback, errorCallback, options);\n            } else {\n                // Start watch timer to get headings\n                timers[id] = window.setInterval(function() {\n                    compass.getCurrentHeading(successCallback, errorCallback);\n                }, frequency);\n            }\n\n            return id;\n        },\n\n        /**\n         * Clears the specified heading watch.\n         * @param {String} watchId The ID of the watch returned from #watchHeading.\n         */\n        clearWatch:function(id) {\n            // Stop javascript timer & remove from timer list\n            if (id && timers[id]) {\n                if (timers[id] != \"iOS\") {\n                      clearInterval(timers[id]);\n                  } else {\n                    // is iOS watch by filter so call into device to stop\n                    exec(null, null, \"Compass\", \"stopHeading\", []);\n                }\n                delete timers[id];\n            }\n        }\n    };\n\nmodule.exports = compass;\n});\n\n//@ sourceURL=lib/common/plugin/compass.js")} catch(e) {console.log("exception: in lib/common/plugin/compass.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/console-via-logger\", function(require, exports, module) {\n//------------------------------------------------------------------------------\n\nvar logger = require(\"cordova/plugin/logger\");\nvar utils  = require(\"cordova/utils\");\n\n//------------------------------------------------------------------------------\n// object that we're exporting\n//------------------------------------------------------------------------------\nvar console = module.exports;\n\n//------------------------------------------------------------------------------\n// copy of the original console object\n//------------------------------------------------------------------------------\nvar WinConsole = window.console;\n\n//------------------------------------------------------------------------------\n// whether to use the logger\n//------------------------------------------------------------------------------\nvar UseLogger = false;\n\n//------------------------------------------------------------------------------\n// Timers\n//------------------------------------------------------------------------------\nvar Timers = {};\n\n//------------------------------------------------------------------------------\n// used for unimplemented methods\n//------------------------------------------------------------------------------\nfunction noop() {}\n\n//------------------------------------------------------------------------------\n// used for unimplemented methods\n//------------------------------------------------------------------------------\nconsole.useLogger = function (value) {\n    if (arguments.length) UseLogger = !!value;\n\n    if (UseLogger) {\n        if (logger.useConsole()) {\n            throw new Error(\"console and logger are too intertwingly\");\n        }\n    }\n\n    return UseLogger;\n};\n\n//------------------------------------------------------------------------------\nconsole.log = function() {\n    if (logger.useConsole()) return;\n    logger.log.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.error = function() {\n    if (logger.useConsole()) return;\n    logger.error.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.warn = function() {\n    if (logger.useConsole()) return;\n    logger.warn.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.info = function() {\n    if (logger.useConsole()) return;\n    logger.info.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.debug = function() {\n    if (logger.useConsole()) return;\n    logger.debug.apply(logger, [].slice.call(arguments));\n};\n\n//------------------------------------------------------------------------------\nconsole.assert = function(expression) {\n    if (expression) return;\n\n    var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));\n    console.log(\"ASSERT: \" + message);\n};\n\n//------------------------------------------------------------------------------\nconsole.clear = function() {};\n\n//------------------------------------------------------------------------------\nconsole.dir = function(object) {\n    console.log(\"%o\", object);\n};\n\n//------------------------------------------------------------------------------\nconsole.dirxml = function(node) {\n    console.log(node.innerHTML);\n};\n\n//------------------------------------------------------------------------------\nconsole.trace = noop;\n\n//------------------------------------------------------------------------------\nconsole.group = console.log;\n\n//------------------------------------------------------------------------------\nconsole.groupCollapsed = console.log;\n\n//------------------------------------------------------------------------------\nconsole.groupEnd = noop;\n\n//------------------------------------------------------------------------------\nconsole.time = function(name) {\n    Timers[name] = new Date().valueOf();\n};\n\n//------------------------------------------------------------------------------\nconsole.timeEnd = function(name) {\n    var timeStart = Timers[name];\n    if (!timeStart) {\n        console.warn(\"unknown timer: \" + name);\n        return;\n    }\n\n    var timeElapsed = new Date().valueOf() - timeStart;\n    console.log(name + \": \" + timeElapsed + \"ms\");\n};\n\n//------------------------------------------------------------------------------\nconsole.timeStamp = noop;\n\n//------------------------------------------------------------------------------\nconsole.profile = noop;\n\n//------------------------------------------------------------------------------\nconsole.profileEnd = noop;\n\n//------------------------------------------------------------------------------\nconsole.count = noop;\n\n//------------------------------------------------------------------------------\nconsole.exception = console.log;\n\n//------------------------------------------------------------------------------\nconsole.table = function(data, columns) {\n    console.log(\"%o\", data);\n};\n\n//------------------------------------------------------------------------------\n// return a new function that calls both functions passed as args\n//------------------------------------------------------------------------------\nfunction wrapperedOrigCall(orgFunc, newFunc) {\n    return function() {\n        var args = [].slice.call(arguments);\n        try { orgFunc.apply(WinConsole, args); } catch (e) {}\n        try { newFunc.apply(console,    args); } catch (e) {}\n    };\n}\n\n//------------------------------------------------------------------------------\n// For every function that exists in the original console object, that\n// also exists in the new console object, wrap the new console method\n// with one that calls both\n//------------------------------------------------------------------------------\nfor (var key in console) {\n    if (typeof WinConsole[key] == \"function\") {\n        console[key] = wrapperedOrigCall(WinConsole[key], console[key]);\n    }\n}\n\n});\n\n//@ sourceURL=lib/common/plugin/console-via-logger.js")} catch(e) {console.log("exception: in lib/common/plugin/console-via-logger.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/contacts\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    ContactError = require('cordova/plugin/ContactError'),\n    utils = require('cordova/utils'),\n    Contact = require('cordova/plugin/Contact');\n\n/**\n* Represents a group of Contacts.\n* @constructor\n*/\nvar contacts = {\n    /**\n     * Returns an array of Contacts matching the search criteria.\n     * @param fields that should be searched\n     * @param successCB success callback\n     * @param errorCB error callback\n     * @param {ContactFindOptions} options that can be applied to contact searching\n     * @return array of Contacts matching search criteria\n     */\n    find:function(fields, successCB, errorCB, options) {\n        if (!successCB) {\n            throw new TypeError(\"You must specify a success callback for the find command.\");\n        }\n        if (!fields || (utils.isArray(fields) && fields.length === 0)) {\n            if (typeof errorCB === \"function\") {\n                errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));\n            }\n        } else {\n            var win = function(result) {\n                var cs = [];\n                for (var i = 0, l = result.length; i < l; i++) {\n                    cs.push(contacts.create(result[i]));\n                }\n                successCB(cs);\n            };\n            exec(win, errorCB, \"Contacts\", \"search\", [fields, options]);\n        }\n    },\n\n    /**\n     * This function creates a new contact, but it does not persist the contact\n     * to device storage. To persist the contact to device storage, invoke\n     * contact.save().\n     * @param properties an object who's properties will be examined to create a new Contact\n     * @returns new Contact object\n     */\n    create:function(properties) {\n        var i;\n        var contact = new Contact();\n        for (i in properties) {\n            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {\n                contact[i] = properties[i];\n            }\n        }\n        return contact;\n    }\n};\n\nmodule.exports = contacts;\n\n});\n\n//@ sourceURL=lib/common/plugin/contacts.js")} catch(e) {console.log("exception: in lib/common/plugin/contacts.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/device\", function(require, exports, module) {\nvar channel = require('cordova/channel'),\n    utils = require('cordova/utils'),\n    exec = require('cordova/exec');\n\n// Tell cordova channel to wait on the CordovaInfoReady event\nchannel.waitForInitialization('onCordovaInfoReady');\n\n/**\n * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the\n * phone, etc.\n * @constructor\n */\nfunction Device() {\n    this.available = false;\n    this.platform = null;\n    this.version = null;\n    this.name = null;\n    this.uuid = null;\n    this.cordova = null;\n\n    var me = this;\n\n    channel.onCordovaReady.subscribeOnce(function() {\n        me.getInfo(function(info) {\n            me.available = true;\n            me.platform = info.platform;\n            me.version = info.version;\n            me.name = info.name;\n            me.uuid = info.uuid;\n            me.cordova = info.cordova;\n            channel.onCordovaInfoReady.fire();\n        },function(e) {\n            me.available = false;\n            utils.alert(\"[ERROR] Error initializing Cordova: \" + e);\n        });\n    });\n}\n\n/**\n * Get device info\n *\n * @param {Function} successCallback The function to call when the heading data is available\n * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)\n */\nDevice.prototype.getInfo = function(successCallback, errorCallback) {\n\n    // successCallback required\n    if (typeof successCallback !== \"function\") {\n        console.log(\"Device Error: successCallback is not a function\");\n        return;\n    }\n\n    // errorCallback optional\n    if (errorCallback && (typeof errorCallback !== \"function\")) {\n        console.log(\"Device Error: errorCallback is not a function\");\n        return;\n    }\n\n    // Get info\n    exec(successCallback, errorCallback, \"Device\", \"getDeviceInfo\", []);\n};\n\nmodule.exports = new Device();\n\n});\n\n//@ sourceURL=lib/common/plugin/device.js")} catch(e) {console.log("exception: in lib/common/plugin/device.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/geolocation\", function(require, exports, module) {\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    PositionError = require('cordova/plugin/PositionError'),\n    Position = require('cordova/plugin/Position');\n\nvar timers = {};   // list of timers in use\n\n// Returns default params, overrides if provided with values\nfunction parseParameters(options) {\n    var opt = {\n        maximumAge: 0,\n        enableHighAccuracy: false,\n        timeout: Infinity\n    };\n\n    if (options) {\n        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {\n            opt.maximumAge = options.maximumAge;\n        }\n        if (options.enableHighAccuracy !== undefined) {\n            opt.enableHighAccuracy = options.enableHighAccuracy;\n        }\n        if (options.timeout !== undefined && !isNaN(options.timeout)) {\n            if (options.timeout < 0) {\n                opt.timeout = 0;\n            } else {\n                opt.timeout = options.timeout;\n            }\n        }\n    }\n\n    return opt;\n}\n\n// Returns a timeout failure, closed over a specified timeout value and error callback.\nfunction createTimeout(errorCallback, timeout) {\n    var t = setTimeout(function() {\n        clearTimeout(t);\n        t = null;\n        errorCallback({\n            code:PositionError.TIMEOUT,\n            message:\"Position retrieval timed out.\"\n        });\n    }, timeout);\n    return t;\n}\n\nvar geolocation = {\n    lastPosition:null, // reference to last known (cached) position returned\n    /**\n   * Asynchronously aquires the current position.\n   *\n   * @param {Function} successCallback    The function to call when the position data is available\n   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)\n   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)\n   */\n    getCurrentPosition:function(successCallback, errorCallback, options) {\n        if (arguments.length === 0) {\n            throw new Error(\"getCurrentPosition must be called with at least one argument.\");\n        }\n        options = parseParameters(options);\n\n        // Timer var that will fire an error callback if no position is retrieved from native\n        // before the \"timeout\" param provided expires\n        var timeoutTimer = null;\n\n        var win = function(p) {\n            clearTimeout(timeoutTimer);\n            if (!timeoutTimer) {\n                // Timeout already happened, or native fired error callback for\n                // this geo request.\n                // Don't continue with success callback.\n                return;\n            }\n            var pos = new Position(\n                {\n                    latitude:p.latitude,\n                    longitude:p.longitude,\n                    altitude:p.altitude,\n                    accuracy:p.accuracy,\n                    heading:p.heading,\n                    velocity:p.velocity,\n                    altitudeAccuracy:p.altitudeAccuracy\n                },\n                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))\n            );\n            geolocation.lastPosition = pos;\n            successCallback(pos);\n        };\n        var fail = function(e) {\n            clearTimeout(timeoutTimer);\n            timeoutTimer = null;\n            var err = new PositionError(e.code, e.message);\n            if (errorCallback) {\n                errorCallback(err);\n            }\n        };\n\n        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just\n        // fire the success callback with the cached position.\n        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {\n            successCallback(geolocation.lastPosition);\n        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.\n        } else if (options.timeout === 0) {\n            fail({\n                code:PositionError.TIMEOUT,\n                message:\"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter.\"\n            });\n        // Otherwise we have to call into native to retrieve a position.\n        } else {\n            if (options.timeout !== Infinity) {\n                // If the timeout value was not set to Infinity (default), then\n                // set up a timeout function that will fire the error callback\n                // if no successful position was retrieved before timeout expired.\n                timeoutTimer = createTimeout(fail, options.timeout);\n            } else {\n                // This is here so the check in the win function doesn't mess stuff up\n                // may seem weird but this guarantees timeoutTimer is\n                // always truthy before we call into native\n                timeoutTimer = true;\n            }\n            exec(win, fail, \"Geolocation\", \"getLocation\", [options.enableHighAccuracy, options.maximumAge]);\n        }\n        return timeoutTimer;\n    },\n    /**\n     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,\n     * the successCallback is called with the new location.\n     *\n     * @param {Function} successCallback    The function to call each time the location data is available\n     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)\n     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)\n     * @return String                       The watch id that must be passed to #clearWatch to stop watching.\n     */\n    watchPosition:function(successCallback, errorCallback, options) {\n        if (arguments.length === 0) {\n            throw new Error(\"watchPosition must be called with at least one argument.\");\n        }\n        options = parseParameters(options);\n\n        var id = utils.createUUID();\n\n        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition\n        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);\n\n        var fail = function(e) {\n            clearTimeout(timers[id]);\n            var err = new PositionError(e.code, e.message);\n            if (errorCallback) {\n                errorCallback(err);\n            }\n        };\n\n        var win = function(p) {\n            clearTimeout(timers[id]);\n            if (options.timeout !== Infinity) {\n                timers[id] = createTimeout(fail, options.timeout);\n            }\n            var pos = new Position(\n                {\n                    latitude:p.latitude,\n                    longitude:p.longitude,\n                    altitude:p.altitude,\n                    accuracy:p.accuracy,\n                    heading:p.heading,\n                    velocity:p.velocity,\n                    altitudeAccuracy:p.altitudeAccuracy\n                },\n                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))\n            );\n            geolocation.lastPosition = pos;\n            successCallback(pos);\n        };\n\n        exec(win, fail, \"Geolocation\", \"addWatch\", [id, options.enableHighAccuracy]);\n\n        return id;\n    },\n    /**\n     * Clears the specified heading watch.\n     *\n     * @param {String} id       The ID of the watch returned from #watchPosition\n     */\n    clearWatch:function(id) {\n        if (id && timers[id] !== undefined) {\n            clearTimeout(timers[id]);\n            delete timers[id];\n            exec(null, null, \"Geolocation\", \"clearWatch\", [id]);\n        }\n    }\n};\n\nmodule.exports = geolocation;\n\n});\n\n//@ sourceURL=lib/common/plugin/geolocation.js")} catch(e) {console.log("exception: in lib/common/plugin/geolocation.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/logger\", function(require, exports, module) {\n//------------------------------------------------------------------------------\n// The logger module exports the following properties/functions:\n//\n// LOG                          - constant for the level LOG\n// ERROR                        - constant for the level ERROR\n// WARN                         - constant for the level WARN\n// INFO                         - constant for the level INFO\n// DEBUG                        - constant for the level DEBUG\n// logLevel()                   - returns current log level\n// logLevel(value)              - sets and returns a new log level\n// useConsole()                 - returns whether logger is using console\n// useConsole(value)            - sets and returns whether logger is using console\n// log(message,...)             - logs a message at level LOG\n// error(message,...)           - logs a message at level ERROR\n// warn(message,...)            - logs a message at level WARN\n// info(message,...)            - logs a message at level INFO\n// debug(message,...)           - logs a message at level DEBUG\n// logLevel(level,message,...)  - logs a message specified level\n//\n//------------------------------------------------------------------------------\n\nvar logger = exports;\n\nvar exec    = require('cordova/exec');\nvar utils   = require('cordova/utils');\n\nvar UseConsole   = true;\nvar Queued       = [];\nvar DeviceReady  = false;\nvar CurrentLevel;\n\n/**\n * Logging levels\n */\n\nvar Levels = [\n    \"LOG\",\n    \"ERROR\",\n    \"WARN\",\n    \"INFO\",\n    \"DEBUG\"\n];\n\n/*\n * add the logging levels to the logger object and\n * to a separate levelsMap object for testing\n */\n\nvar LevelsMap = {};\nfor (var i=0; i<Levels.length; i++) {\n    var level = Levels[i];\n    LevelsMap[level] = i;\n    logger[level]    = level;\n}\n\nCurrentLevel = LevelsMap.WARN;\n\n/**\n * Getter/Setter for the logging level\n *\n * Returns the current logging level.\n *\n * When a value is passed, sets the logging level to that value.\n * The values should be one of the following constants:\n *    logger.LOG\n *    logger.ERROR\n *    logger.WARN\n *    logger.INFO\n *    logger.DEBUG\n *\n * The value used determines which messages get printed.  The logging\n * values above are in order, and only messages logged at the logging\n * level or above will actually be displayed to the user.  Eg, the\n * default level is WARN, so only messages logged with LOG, ERROR, or\n * WARN will be displayed; INFO and DEBUG messages will be ignored.\n */\nlogger.level = function (value) {\n    if (arguments.length) {\n        if (LevelsMap[value] === null) {\n            throw new Error(\"invalid logging level: \" + value);\n        }\n        CurrentLevel = LevelsMap[value];\n    }\n\n    return Levels[CurrentLevel];\n};\n\n/**\n * Getter/Setter for the useConsole functionality\n *\n * When useConsole is true, the logger will log via the\n * browser 'console' object.  Otherwise, it will use the\n * native Logger plugin.\n */\nlogger.useConsole = function (value) {\n    if (arguments.length) UseConsole = !!value;\n\n    if (UseConsole) {\n        if (typeof console == \"undefined\") {\n            throw new Error(\"global console object is not defined\");\n        }\n\n        if (typeof console.log != \"function\") {\n            throw new Error(\"global console object does not have a log function\");\n        }\n\n        if (typeof console.useLogger == \"function\") {\n            if (console.useLogger()) {\n                throw new Error(\"console and logger are too intertwingly\");\n            }\n        }\n    }\n\n    return UseConsole;\n};\n\n/**\n * Logs a message at the LOG level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.log   = function(message) { logWithArgs(\"LOG\",   arguments); };\n\n/**\n * Logs a message at the ERROR level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.error = function(message) { logWithArgs(\"ERROR\", arguments); };\n\n/**\n * Logs a message at the WARN level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.warn  = function(message) { logWithArgs(\"WARN\",  arguments); };\n\n/**\n * Logs a message at the INFO level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.info  = function(message) { logWithArgs(\"INFO\",  arguments); };\n\n/**\n * Logs a message at the DEBUG level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.debug = function(message) { logWithArgs(\"DEBUG\", arguments); };\n\n// log at the specified level with args\nfunction logWithArgs(level, args) {\n    args = [level].concat([].slice.call(args));\n    logger.logLevel.apply(logger, args);\n}\n\n/**\n * Logs a message at the specified level.\n *\n * Parameters passed after message are used applied to\n * the message with utils.format()\n */\nlogger.logLevel = function(level, message /* , ... */) {\n    // format the message with the parameters\n    var formatArgs = [].slice.call(arguments, 2);\n    message    = utils.vformat(message, formatArgs);\n\n    if (LevelsMap[level] === null) {\n        throw new Error(\"invalid logging level: \" + level);\n    }\n\n    if (LevelsMap[level] > CurrentLevel) return;\n\n    // queue the message if not yet at deviceready\n    if (!DeviceReady && !UseConsole) {\n        Queued.push([level, message]);\n        return;\n    }\n\n    // if not using the console, use the native logger\n    if (!UseConsole) {\n        exec(null, null, \"Logger\", \"logLevel\", [level, message]);\n        return;\n    }\n\n    // make sure console is not using logger\n    if (console.__usingCordovaLogger) {\n        throw new Error(\"console and logger are too intertwingly\");\n    }\n\n    // log to the console\n    switch (level) {\n        case logger.LOG:   console.log(message); break;\n        case logger.ERROR: console.log(\"ERROR: \" + message); break;\n        case logger.WARN:  console.log(\"WARN: \"  + message); break;\n        case logger.INFO:  console.log(\"INFO: \"  + message); break;\n        case logger.DEBUG: console.log(\"DEBUG: \" + message); break;\n    }\n};\n\n// when deviceready fires, log queued messages\nlogger.__onDeviceReady = function() {\n    if (DeviceReady) return;\n\n    DeviceReady = true;\n\n    for (var i=0; i<Queued.length; i++) {\n        var messageArgs = Queued[i];\n        logger.logLevel(messageArgs[0], messageArgs[1]);\n    }\n\n    Queued = null;\n};\n\n// add a deviceready event to log queued messages\ndocument.addEventListener(\"deviceready\", logger.__onDeviceReady, false);\n\n});\n\n//@ sourceURL=lib/common/plugin/logger.js")} catch(e) {console.log("exception: in lib/common/plugin/logger.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/network\", function(require, exports, module) {\nvar exec = require('cordova/exec'),\n    cordova = require('cordova'),\n    channel = require('cordova/channel');\n\nvar NetworkConnection = function () {\n    this.type = null;\n    this._firstRun = true;\n    this._timer = null;\n    this.timeout = 500;\n\n    var me = this;\n\n    channel.onCordovaReady.subscribeOnce(function() {\n        me.getInfo(function (info) {\n            me.type = info;\n            if (info === \"none\") {\n                // set a timer if still offline at the end of timer send the offline event\n                me._timer = setTimeout(function(){\n                    cordova.fireDocumentEvent(\"offline\");\n                    me._timer = null;\n                    }, me.timeout);\n            } else {\n                // If there is a current offline event pending clear it\n                if (me._timer !== null) {\n                    clearTimeout(me._timer);\n                    me._timer = null;\n                }\n                cordova.fireDocumentEvent(\"online\");\n            }\n\n            // should only fire this once\n            if (me._firstRun) {\n                me._firstRun = false;\n                channel.onCordovaConnectionReady.fire();\n            }\n        },\n        function (e) {\n            // If we can't get the network info we should still tell Cordova\n            // to fire the deviceready event.\n            if (me._firstRun) {\n                me._firstRun = false;\n                channel.onCordovaConnectionReady.fire();\n            }\n            console.log(\"Error initializing Network Connection: \" + e);\n        });\n    });\n};\n\n/**\n * Get connection info\n *\n * @param {Function} successCallback The function to call when the Connection data is available\n * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)\n */\nNetworkConnection.prototype.getInfo = function (successCallback, errorCallback) {\n    // Get info\n    exec(successCallback, errorCallback, \"NetworkStatus\", \"getConnectionInfo\", []);\n};\n\nmodule.exports = new NetworkConnection();\n});\n\n//@ sourceURL=lib/common/plugin/network.js")} catch(e) {console.log("exception: in lib/common/plugin/network.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/notification\", function(require, exports, module) {\nvar exec = require('cordova/exec');\n\n/**\n * Provides access to notifications on the device.\n */\n\nmodule.exports = {\n\n    /**\n     * Open a native alert dialog, with a customizable title and button text.\n     *\n     * @param {String} message              Message to print in the body of the alert\n     * @param {Function} completeCallback   The callback that is called when user clicks on a button.\n     * @param {String} title                Title of the alert dialog (default: Alert)\n     * @param {String} buttonLabel          Label of the close button (default: OK)\n     */\n    alert: function(message, completeCallback, title, buttonLabel) {\n        var _title = (title || \"Alert\");\n        var _buttonLabel = (buttonLabel || \"OK\");\n        exec(completeCallback, null, \"Notification\", \"alert\", [message, _title, _buttonLabel]);\n    },\n\n    /**\n     * Open a native confirm dialog, with a customizable title and button text.\n     * The result that the user selects is returned to the result callback.\n     *\n     * @param {String} message              Message to print in the body of the alert\n     * @param {Function} resultCallback     The callback that is called when user clicks on a button.\n     * @param {String} title                Title of the alert dialog (default: Confirm)\n     * @param {String} buttonLabels         Comma separated list of the labels of the buttons (default: 'OK,Cancel')\n     */\n    confirm: function(message, resultCallback, title, buttonLabels) {\n        var _title = (title || \"Confirm\");\n        var _buttonLabels = (buttonLabels || \"OK,Cancel\");\n        exec(resultCallback, null, \"Notification\", \"confirm\", [message, _title, _buttonLabels]);\n    },\n\n    /**\n     * Causes the device to vibrate.\n     *\n     * @param {Integer} mills       The number of milliseconds to vibrate for.\n     */\n    vibrate: function(mills) {\n        exec(null, null, \"Notification\", \"vibrate\", [mills]);\n    },\n\n    /**\n     * Causes the device to beep.\n     * On Android, the default notification ringtone is played \"count\" times.\n     *\n     * @param {Integer} count       The number of beeps.\n     */\n    beep: function(count) {\n        exec(null, null, \"Notification\", \"beep\", [count]);\n    }\n};\n});\n\n//@ sourceURL=lib/common/plugin/notification.js")} catch(e) {console.log("exception: in lib/common/plugin/notification.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/requestFileSystem\", function(require, exports, module) {\nvar FileError = require('cordova/plugin/FileError'),\n    FileSystem = require('cordova/plugin/FileSystem'),\n    exec = require('cordova/exec');\n\n/**\n * Request a file system in which to store application data.\n * @param type  local file system type\n * @param size  indicates how much storage space, in bytes, the application expects to need\n * @param successCallback  invoked with a FileSystem object\n * @param errorCallback  invoked if error occurs retrieving file system\n */\nvar requestFileSystem = function(type, size, successCallback, errorCallback) {\n    var fail = function(code) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(code));\n        }\n    };\n\n    if (type < 0 || type > 3) {\n        fail(FileError.SYNTAX_ERR);\n    } else {\n        // if successful, return a FileSystem object\n        var success = function(file_system) {\n            if (file_system) {\n                if (typeof successCallback === 'function') {\n                    // grab the name and root from the file system object\n                    var result = new FileSystem(file_system.name, file_system.root);\n                    successCallback(result);\n                }\n            }\n            else {\n                // no FileSystem object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n        exec(success, fail, \"File\", \"requestFileSystem\", [type, size]);\n    }\n};\n\nmodule.exports = requestFileSystem;\n});\n\n//@ sourceURL=lib/common/plugin/requestFileSystem.js")} catch(e) {console.log("exception: in lib/common/plugin/requestFileSystem.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/resolveLocalFileSystemURI\", function(require, exports, module) {\nvar DirectoryEntry = require('cordova/plugin/DirectoryEntry'),\n    FileEntry = require('cordova/plugin/FileEntry'),\n    FileError = require('cordova/plugin/FileError'),\n    exec = require('cordova/exec');\n\n/**\n * Look up file system Entry referred to by local URI.\n * @param {DOMString} uri  URI referring to a local file or directory\n * @param successCallback  invoked with Entry object corresponding to URI\n * @param errorCallback    invoked if error occurs retrieving file system entry\n */\nmodule.exports = function(uri, successCallback, errorCallback) {\n    // error callback\n    var fail = function(error) {\n        if (typeof errorCallback === 'function') {\n            errorCallback(new FileError(error));\n        }\n    };\n    // sanity check for 'not:valid:filename'\n    if(!uri || uri.split(\":\").length > 2) {\n        setTimeout( function() {\n            fail(FileError.ENCODING_ERR);\n        },0);\n        return;\n    }\n    // if successful, return either a file or directory entry\n    var success = function(entry) {\n        var result;\n        if (entry) {\n            if (typeof successCallback === 'function') {\n                // create appropriate Entry object\n                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);\n                try {\n                    successCallback(result);\n                }\n                catch (e) {\n                    console.log('Error invoking callback: ' + e);\n                }\n            }\n        }\n        else {\n            // no Entry object returned\n            fail(FileError.NOT_FOUND_ERR);\n        }\n    };\n\n    exec(success, fail, \"File\", \"resolveLocalFileSystemURI\", [uri]);\n};\n\n});\n\n//@ sourceURL=lib/common/plugin/resolveLocalFileSystemURI.js")} catch(e) {console.log("exception: in lib/common/plugin/resolveLocalFileSystemURI.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/splashscreen\", function(require, exports, module) {\nvar exec = require('cordova/exec');\n\nvar splashscreen = {\n    show:function() {\n        exec(null, null, \"SplashScreen\", \"show\", []);\n    },\n    hide:function() {\n        exec(null, null, \"SplashScreen\", \"hide\", []);\n    }\n};\n\nmodule.exports = splashscreen;\n});\n\n//@ sourceURL=lib/common/plugin/splashscreen.js")} catch(e) {console.log("exception: in lib/common/plugin/splashscreen.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Accelerometer\", function(require, exports, module) {\nvar callback = null;\n\nmodule.exports = {\n    start: function (successCallback, errorCallback) {\n        window.removeEventListener(\"devicemotion\", callback);\n        callback = function (motion) {\n            successCallback({\n                x: motion.accelerationIncludingGravity.x,\n                y: motion.accelerationIncludingGravity.y,\n                z: motion.accelerationIncludingGravity.z,\n                timestamp: motion.timeStamp\n            });\n        };\n        window.addEventListener(\"devicemotion\", callback);\n    },\n    stop: function (successCallback, errorCallback) {\n        window.removeEventListener(\"devicemotion\", callback);\n    }\n};\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Accelerometer.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Accelerometer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Battery\", function(require, exports, module) {\n/*global tizen:false */\nvar id = null;\n\nmodule.exports = {\n    start: function(successCallback, errorCallback) {\n        var tizenSuccessCallback = function(power) {\n            if (successCallback) {\n                successCallback({level: Math.round(power.level * 100), isPlugged: power.isCharging});\n            }\n        };\n\n        if (id === null) {\n            id = tizen.systeminfo.addPropertyValueChangeListener(\"Power\", tizenSuccessCallback);\n        }\n        tizen.systeminfo.getPropertyValue(\"Power\", tizenSuccessCallback, errorCallback);\n    },\n\n    stop: function(successCallback, errorCallback) {\n        tizen.systeminfo.removePropertyValueChangeListener(id);\n        id = null;\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Battery.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Battery.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/BufferLoader\", function(require, exports, module) {\n/*\n * Buffer Loader Object\n * This class provides a sound buffer for one or more sounds\n * holded in a local file located by an url\n *\n * uses W3C  Web Audio API\n *\n * @constructor\n *\n * @param {AudioContext} audio context object\n * @param {Array} urlList, array of url for sound to load\n * @param {function} callback , called after buffer was loaded\n *\n */\n\nfunction BufferLoader(context, urlList, callback) {\n    this.context = context;\n    this.urlList = urlList;\n    this.onload = callback;\n    this.bufferList = [];\n    this.loadCount = 0;\n}\n\n/*\n * This method loads a sound into a buffer\n * @param {Array} urlList, array of url for sound to load\n * @param {Number} index, buffer index in the array where to load the url sound\n *\n */\n\nBufferLoader.prototype.loadBuffer = function(url, index) {\n    // Load buffer asynchronously\n    var request = null,\n        loader = null;\n\n    request = new XMLHttpRequest();\n\n    if (request === null) {\n        console.log (\"BufferLoader.prototype.loadBuffer, cannot allocate XML http request\");\n        return;\n    }\n\n    request.open(\"GET\", url, true);\n    request.responseType = \"arraybuffer\";\n\n    loader = this;\n\n    request.onload = function() {\n    // Asynchronously decode the audio file data in request.response\n    loader.context.decodeAudioData(\n        request.response,\n        function(buffer) {\n                if (!buffer) {\n                    console.log (\"BufferLoader.prototype.loadBuffer,error decoding file data: \" + url);\n                    return;\n                }\n\n                loader.bufferList[index] = buffer;\n\n                if (++loader.loadCount == loader.urlList.length) {\n                    loader.onload(loader.bufferList);\n                }\n            }\n        );\n    };\n\n    request.onerror = function() {\n        console.log (\"BufferLoader.prototype.loadBuffer, XHR error\");\n    };\n\n    request.send();\n};\n\n/*\n * This method loads all sounds identified by their url\n * and that where given to the object constructor\n *\n */\n\nBufferLoader.prototype.load = function() {\n    for (var i = 0; i < this.urlList.length; ++i) {\n        this.loadBuffer(this.urlList[i], i);\n    }\n};\n\nmodule.exports = BufferLoader;\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/BufferLoader.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/BufferLoader.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Camera\", function(require, exports, module) {\n/*global tizen:false */\nvar Camera = require('cordova/plugin/CameraConstants');\n\nfunction makeReplyCallback(successCallback, errorCallback) {\n    return {\n        onsuccess: function(reply) {\n            if (reply.length > 0) {\n                successCallback(reply[0].value);\n            } else {\n                errorCallback('Picture selection aborted');\n            }\n        },\n        onfail: function() {\n           console.log('The service launch failed');\n        }\n    };\n}\n\nmodule.exports = {\n    takePicture: function(successCallback, errorCallback, args) {\n        var destinationType = args[1],\n            sourceType = args[2],\n            encodingType = args[5],\n            mediaType = args[6];\n            // Not supported\n            /*\n            quality = args[0]\n            targetWidth = args[3]\n            targetHeight = args[4]\n            allowEdit = args[7]\n            correctOrientation = args[8]\n            saveToPhotoAlbum = args[9]\n            */\n\n        if (destinationType !== Camera.DestinationType.FILE_URI) {\n            errorCallback('DestinationType not supported');\n            return;\n        }\n        if (mediaType !== Camera.MediaType.PICTURE) {\n            errorCallback('MediaType not supported');\n            return;\n        }\n\n        var mimeType;\n        if (encodingType === Camera.EncodingType.JPEG) {\n            mimeType = 'image/jpeg';\n        } else if (encodingType === Camera.EncodingType.PNG) {\n            mimeType = 'image/png';\n        } else {\n            mimeType = 'image/*';\n        }\n\n        var serviceId;\n        if (sourceType === Camera.PictureSourceType.CAMERA) {\n            serviceId = 'http://tizen.org/appsvc/operation/create_content';\n        } else {\n            serviceId = 'http://tizen.org/appsvc/operation/pick';\n        }\n\n        var service = new tizen.ApplicationService(serviceId, null, mimeType, null);\n        tizen.application.launchService(service, null, null,\n                function(error) { errorCallback(error.message); },\n                makeReplyCallback(successCallback, errorCallback));\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Camera.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Camera.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Compass\", function(require, exports, module) {\nvar CompassError = require('cordova/plugin/CompassError'),\n    callback = null, ready = false;\n\nmodule.exports = {\n    getHeading: function(successCallback, errorCallback) {\n        if (window.DeviceOrientationEvent !== undefined) {\n            callback = function (orientation) {\n                var heading = 360 - orientation.alpha;\n                if (ready) {\n                    successCallback({\n                        magneticHeading: heading,\n                        trueHeading: heading,\n                        headingAccuracy: 0,\n                        timestamp: orientation.timeStamp\n                    });\n                    window.removeEventListener(\"deviceorientation\", callback);\n                }\n                ready = true;\n            };\n            ready = false; // workaround invalid first event value returned by WRT\n            window.addEventListener(\"deviceorientation\", callback);\n        }\n        else {\n            errorCallback(CompassError.COMPASS_NOT_SUPPORTED);\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Compass.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Compass.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Contact\", function(require, exports, module) {\n/*global tizen:false */\nvar ContactError = require('cordova/plugin/ContactError'),\n    ContactUtils = require('cordova/plugin/tizen/ContactUtils'),\n    utils = require('cordova/utils'),\n    exec = require('cordova/exec');\n\n// ------------------\n// Utility functions\n// ------------------\n\n\n/**\n * Retrieves a Tizen Contact object from the device by its unique id.\n *\n * @param uid\n *            Unique id of the contact on the device\n * @return {tizen.Contact} Tizen Contact object or null if contact with\n *         specified id is not found\n */\nvar findByUniqueId = function(id) {\n\n    if (!id) {\n        return null;\n    }\n\n    var tizenContact = null;\n\n    tizen.contact.getDefaultAddressBook().find(\n        function _successCallback(contacts){\n            tizenContact = contacts[0];\n        },\n        function _errorCallback(error){\n            console.log(\"tizen find error \" + error);\n        },\n        new tizen.AttributeFilter('id', 'CONTAINS', id),\n        new tizen.SortMode('id', 'ASC'));\n\n    return tizenContact || null;\n};\n\n\nvar traceTizenContact = function (tizenContact) {\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.id \" + tizenContact.id);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.lastUpdated \" + tizenContact.lastUpdated);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.name \" + tizenContact.name);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.account \" + tizenContact.account);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.addresses \" + tizenContact.addresses);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.photoURI \" + tizenContact.photoURI);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.phoneNumbers \" + tizenContact.phoneNumbers);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.emails \" + tizenContact.emails);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.birthday \" + tizenContact.birthday);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.organization \" + tizenContact.organization);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.notes \" + tizenContact.notes);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.urls \" + tizenContact.isFavorite);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.isFavorite \" + tizenContact.isFavorite);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.ringtonesURI \" + tizenContact.ringtonesURI);\n    console.log(\"cordova/plugin/tizen/Contact/  tizenContact.categories \" + tizenContact.categories);\n};\n\n\n/**\n * Creates a Tizen contact object from the W3C Contact object and persists\n * it to device storage.\n *\n * @param {Contact}\n *            contact The contact to save\n * @return a new contact object with all properties set\n */\nvar saveToDevice = function(contact) {\n\n    if (!contact) {\n        return;\n    }\n\n    var tizenContact = null;\n    var update = false;\n    var i = 0;\n\n    // if the underlying Tizen Contact object already exists, retrieve it for\n    // update\n    if (contact.id) {\n        // we must attempt to retrieve the BlackBerry contact from the device\n        // because this may be an update operation\n        tizenContact = findByUniqueId(contact.id);\n    }\n\n    // contact not found on device, create a new one\n    if (!tizenContact) {\n        tizenContact = new tizen.Contact();\n    }\n    // update the existing contact\n    else {\n        update = true;\n    }\n\n    // NOTE: The user may be working with a partial Contact object, because only\n    // user-specified Contact fields are returned from a find operation (blame\n    // the W3C spec). If this is an update to an existing Contact, we don't\n    // want to clear an attribute from the contact database simply because the\n    // Contact object that the user passed in contains a null value for that\n    // attribute. So we only copy the non-null Contact attributes to the\n    // Tizen Contact object before saving.\n    //\n    // This means that a user must explicitly set a Contact attribute to a\n    // non-null value in order to update it in the contact database.\n    //\n    traceTizenContact (tizenContact);\n\n    // display name\n    if (contact.displayName !== null) {\n        if (tizenContact.name === null) {\n            tizenContact.name = new tizen.ContactName();\n        }\n        if (tizenContact.name !== null) {\n            tizenContact.name.displayName = contact.displayName;\n        }\n    }\n\n    // name\n    if (contact.name !== null) {\n        if (contact.name.givenName) {\n            if (tizenContact.name === null) {\n                tizenContact.name = new tizen.ContactName();\n            }\n            if (tizenContact.name !== null) {\n                tizenContact.name.firstName = contact.name.givenName;\n            }\n        }\n\n        if  (contact.name.middleName) {\n            if (tizenContact.name === null) {\n                tizenContact.name = new tizen.ContactName();\n            }\n            if (tizenContact.name !== null) {\n                tizenContact.name.middleName = contact.name.middleName;\n            }\n        }\n\n        if (contact.name.familyName) {\n            if (tizenContact.name === null) {\n                tizenContact.name = new tizen.ContactName();\n            }\n            if (tizenContact.name !== null) {\n                tizenContact.name.lastName = contact.name.familyName;\n            }\n        }\n\n        if (contact.name.honorificPrefix) {\n            if (tizenContact.name === null) {\n                tizenContact.name = new tizen.ContactName();\n            }\n            if (tizenContact.name !== null) {\n                tizenContact.name.prefix = contact.name.honorificPrefix;\n            }\n        }\n    }\n\n    // nickname\n    if (contact.nickname !== null) {\n        if (tizenContact.name === null) {\n            tizenContact.name = new tizen.ContactName();\n        }\n        if (tizenContact.name !== null) {\n            if (!utils.isArray(tizenContact.name.nicknames))\n            {\n                tizenContact.name.nicknames = [];\n            }\n            tizenContact.name.nicknames[0] = contact.nickname;\n        }\n    }\n    else {\n        tizenContact.name.nicknames = [];\n    }\n\n    // note\n    if (contact.note !== null) {\n        if (tizenContact.note === null) {\n            tizenContact.note = [];\n        }\n        if (tizenContact.note !== null) {\n            tizenContact.note[0] = contact.note;\n        }\n    }\n\n    // photos\n    if (contact.photos && utils.isArray(contact.emails) && contact.emails.length > 0) {\n        tizenContact.photoURI = contact.photos[0];\n    }\n\n    if (utils.isDate(contact.birthday)) {\n        if (!utils.isDate(tizenContact.birthday)) {\n            tizenContact.birthday = new Date();\n        }\n        if (utils.isDate(tizenContact.birthday)) {\n            tizenContact.birthday.setDate(contact.birthday.getDate());\n        }\n    }\n\n    // Tizen supports many addresses\n    if (utils.isArray(contact.emails)) {\n\n        // if this is an update, re initialize email addresses\n        if (update) {\n            // doit on effacer sur un update??????\n        }\n\n        // copy the first three email addresses found\n        var emails = [];\n        for (i = 0; i < contact.emails.length; i += 1) {\n            var emailTypes = [];\n\n            emailTypes.push (contact.emails[i].type);\n\n            if (contact.emails[i].pref) {\n                emailTypes.push (\"PREF\");\n            }\n\n            emails.push(\n                new tizen.ContactEmailAddress(\n                    contact.emails[i].value,\n                    emailTypes)\n            );\n        }\n        tizenContact.emails = emails.length > 0 ? emails : [];\n    }\n    else {\n        tizenContact.emails = [];\n    }\n\n    // Tizen supports many phone numbers\n    // copy into appropriate fields based on type\n    if (utils.isArray(contact.phoneNumbers)) {\n        // if this is an update, re-initialize phone numbers\n        if (update) {\n        }\n\n        var phoneNumbers = [];\n\n        for (i = 0; i < contact.phoneNumbers.length; i += 1) {\n\n            if (!contact.phoneNumbers[i] || !contact.phoneNumbers[i].value) {\n                continue;\n            }\n\n             var phoneTypes = [];\n             phoneTypes.push (contact.phoneNumbers[i].type);\n\n             if (contact.phoneNumbers[i].pref) {\n                 phoneTypes.push (\"PREF\");\n             }\n\n            phoneNumbers.push(\n                new tizen.ContactPhoneNumber(\n                    contact.phoneNumbers[i].value,\n                    phoneTypes)\n            );\n        }\n\n        tizenContact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : [];\n    } else {\n        tizenContact.phoneNumbers = [];\n    }\n\n    if (utils.isArray(contact.addresses)) {\n        // if this is an update, re-initialize addresses\n        if (update) {\n        }\n\n        var addresses = [],\n            address = null;\n\n        for ( i = 0; i < contact.addresses.length; i += 1) {\n            address = contact.addresses[i];\n\n            if (!address || address.id === undefined || address.pref === undefined || address.type === undefined || address.formatted === undefined) {\n                continue;\n            }\n\n            var addressTypes = [];\n            addressTypes.push (address.type);\n\n            if (address.pref) {\n                addressTypes.push (\"PREF\");\n            }\n\n            addresses.push(\n                new tizen.ContactAddress({\n                         country:                   address.country,\n                         region :                   address.region,\n                         city:                      address.locality,\n                         streetAddress:             address.streetAddress,\n                         additionalInformation:     \"\",\n                         postalCode:                address.postalCode,\n                         types :                    addressTypes\n                }));\n\n        }\n        tizenContact.addresses = addresses.length > 0 ? addresses : [];\n\n    } else{\n        tizenContact.addresses = [];\n    }\n\n    // copy first url found to BlackBerry 'webpage' field\n    if (utils.isArray(contact.urls)) {\n        // if this is an update, re-initialize web page\n        if (update) {\n        }\n\n        var url = null,\n            urls = [];\n\n        for ( i = 0; i< contact.urls.length; i+= 1) {\n            url = contact.urls[i];\n\n            if (!url || !url.value) {\n                continue;\n            }\n\n            urls.push( new tizen.ContactWebSite(url.value, url.type));\n        }\n        tizenContact.urls = urls.length > 0 ? urls : [];\n    } else{\n        tizenContact.urls = [];\n    }\n\n    if (utils.isArray(contact.organizations && contact.organizations.length > 0) ) {\n        // if this is an update, re-initialize org attributes\n        var organization = contact.organizations[0];\n\n         tizenContact.organization = new tizen.ContacOrganization({\n             name:          organization.name,\n             department:    organization.department,\n             office:        \"\",\n             title:         organization.title,\n             role:          \"\",\n             logoURI:       \"\"\n         });\n    }\n\n    // categories\n    if (utils.isArray(contact.categories)) {\n        tizenContact.categories = [];\n\n        var category = null;\n\n        for (i = 0; i < contact.categories.length; i += 1) {\n            category = contact.categories[i];\n\n            if (typeof category === \"string\") {\n                tizenContact.categories.push(category);\n            }\n        }\n    }\n    else {\n        tizenContact.categories = [];\n    }\n\n    // save to device\n    // in tizen contact mean update or add\n    // later we might use addBatch and updateBatch\n    if (update){\n        tizen.contact.getDefaultAddressBook().update(tizenContact);\n    }\n    else {\n        tizen.contact.getDefaultAddressBook().add(tizenContact);\n    }\n\n    // Use the fully populated Tizen contact object to create a\n    // corresponding W3C contact object.\n    return ContactUtils.createContact(tizenContact, [ \"*\" ]);\n};\n\n\n/**\n * Creates a Tizen ContactAddress object from a W3C ContactAddress.\n *\n * @return {tizen.ContactAddress} a Tizen ContactAddress object\n */\nvar createTizenAddress = function(address) {\n\n    var type = null,\n        pref = null,\n        typesAr = [];\n\n    if (address === null) {\n        return null;\n    }\n\n\n    var tizenAddress = new tizen.ContactAddress();\n\n    if (tizenAddress === null) {\n        return null;\n    }\n\n    typesAr.push(address.type);\n\n    if (address.pref) {\n        typesAr.push(\"PREF\");\n    }\n\n    tizenAddress.country = address.country || \"\";\n    tizenAddress.region = address.region || \"\";\n    tizenAddress.city = address.locality || \"\";\n    tizenAddress.streetAddress = address.streetAddress || \"\";\n    tizenAddress.postalCode = address.postalCode || \"\";\n    tizenAddress.types = typesAr || \"\";\n\n    return tizenAddress;\n};\n\nmodule.exports = {\n    /**\n     * Persists contact to device storage.\n     */\n\n    save : function(successCB, failCB) {\n\n        try {\n            // save the contact and store it's unique id\n            var fullContact = saveToDevice(this);\n\n            this.id = fullContact.id;\n\n            // This contact object may only have a subset of properties\n            // if the save was an update of an existing contact. This is\n            // because the existing contact was likely retrieved using a\n            // subset of properties, so only those properties were set in the\n            // object. For this reason, invoke success with the contact object\n            // returned by saveToDevice since it is fully populated.\n\n            if (typeof successCB === 'function') {\n                successCB(fullContact);\n            }\n        }\n        catch (error) {\n            console.log('Error saving contact: ' +  error);\n\n            if (typeof failCB === 'function') {\n                failCB (new ContactError(ContactError.UNKNOWN_ERROR));\n            }\n        }\n    },\n\n    /**\n     * Removes contact from device storage.\n     *\n     * @param successCB\n     *            successCB callback\n     * @param failCB\n     *            error callback\n     */\n    remove : function (successCB, failCB) {\n\n        try {\n            // retrieve contact from device by id\n            var tizenContact = null;\n\n            if (this.id) {\n                tizenContact = findByUniqueId(this.id);\n            }\n\n\n            // if contact was found, remove it\n            if (tizenContact) {\n\n                tizen.contact.getDefaultAddressBook().remove(tizenContact.id);\n\n                if (typeof success === 'function') {\n                    successCB(this);\n                }\n            }\n            // attempting to remove a contact that hasn't been saved\n            else if (typeof failCB === 'function') {\n                failCB(new ContactError(ContactError.UNKNOWN_ERROR));\n            }\n        }\n        catch (error) {\n            console.log('Error removing contact ' + this.id + \": \" + error);\n            if (typeof failCB === 'function') {\n                failCB(new ContactError(ContactError.UNKNOWN_ERROR));\n            }\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Contact.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Contact.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/ContactUtils\", function(require, exports, module) {\n/*global tizen:false */\nvar ContactAddress = require('cordova/plugin/ContactAddress'),\n    ContactName = require('cordova/plugin/ContactName'),\n    ContactField = require('cordova/plugin/ContactField'),\n    ContactOrganization = require('cordova/plugin/ContactOrganization'),\n    utils = require('cordova/utils'),\n    Contact = require('cordova/plugin/Contact');\n\n/**\n * Mappings for each Contact field that may be used in a find operation. Maps\n * W3C Contact fields to one or more fields in a Tizen contact object.\n *\n * Example: user searches with a filter on the Contact 'name' field:\n *\n * <code>Contacts.find(['name'], onSuccess, onFail, {filter:'Bob'});</code>\n *\n * The 'name' field does not exist in a Tizen contact. Instead, a filter\n * expression will be built to search the Tizen contacts using the\n * Tizen 'title', 'firstName' and 'lastName' fields.\n */\nvar fieldMappings = {\n    \"id\" : [\"id\"],\n    \"displayName\" : [\"name.displayName\"],\n    \"nickname\": [\"name.nicknames\"],\n    \"name\" : [ \"name.prefix\", \"name.firstName\", \"name.lastName\" ],\n    \"phoneNumbers\" : [\"phoneNumbers.number\",\"phoneNumbers.types\"],\n    \"emails\" : [\"emails.types\", \"emails.email\"],\n    \"addresses\" : [\"addresses.country\",\"addresses.region\",\"addresses.city\",\"addresses.streetAddress\",\"addresses.postalCode\",\"addresses.country\",\"addresses.types\"],\n    \"organizations\" : [\"organization.name\",\"organization.department\",\"organization.office\", \"organization.title\"],\n    \"birthday\" : [\"birthday\"],\n    \"note\" : [\"notes\"],\n    \"photos\" : [\"photoURI\"],\n    \"categories\" : [\"categories\"],\n    \"urls\" : [\"urls.url\", \"urls.type\"]\n};\n\n/*\n * Build an array of all of the valid W3C Contact fields. This is used to\n * substitute all the fields when [\"*\"] is specified.\n */\nvar allFields = [];\n\n(function initializeAllFieldsMapping() {\n\n    for ( var key in fieldMappings) {\n        allFields.push(key);\n    }\n    // as we want it to be executed once\n    function initializeAllFieldsMapping() {\n    }\n\n})();\n\n/**\n * Create a W3C ContactAddress object from a Tizen Address object\n *\n * @param {String}\n *            type the type of address (e.g. work, home)\n * @param {tizen.ContactAddress}\n *            tizenAddress a Tizen Address object\n * @return {ContactAddress} a contact address object or null if the specified\n *         address is null\n */\nvar createContactAddress = function(type, tizenAddress) {\n    if (!tizenAddress) {\n        return null;\n    }\n\n    var streetAddress = tizenAddress.streetAddress;\n    var locality = tizenAddress.city || \"\";\n    var region = tizenAddress.region || \"\";\n    var postalCode = tizenAddress.postalCode || \"\";\n    var country = tizenAddress.country || \"\";\n    var formatted = streetAddress + \", \" + locality + \", \" + region + \", \" + postalCode + \", \" + country;\n\n    var contact = new ContactAddress(null, type, formatted, streetAddress, locality, region, postalCode, country);\n\n    return contact;\n};\n\nmodule.exports = {\n    /**\n     * Builds Tizen filter expressions for contact search using the\n     * contact fields and search filter provided.\n     *\n     * @param {String[]}\n     *            fields Array of Contact fields to search\n     * @param {String}\n     *            filter Filter, or search string\n     * @param {Boolean}\n     *                 multiple, one contacts or more wanted as result\n     * @return filter expression or null if fields is empty or filter is null or\n     *         empty\n     */\n\n    buildFilterExpression: function(fields, filter) {\n        // ensure filter exists\n        if (!filter || filter === \"\") {\n            return null;\n        }\n\n        if ((fields.length === 1) && (fields[0] === \"*\")) {\n            // Cordova enhancement to allow fields value of [\"*\"] to indicate\n            // all supported fields.\n            fields = allFields;\n        }\n\n        // build a filter expression using all Contact fields provided\n        var compositeFilter = null,\n            attributeFilter = null,\n            filterExpression = null,\n            matchFlag = \"CONTAINS\",\n            matchValue = filter,\n            attributesArray = [];\n\n        if (fields && utils.isArray(fields)) {\n\n            for ( var field in fields) {\n\n                if (!fields[field]) {\n                    continue;\n                }\n\n                // retrieve Tizen contact fields that map Cordova fields specified\n                // (tizenFields is a string or an array of strings)\n                var tizenFields = fieldMappings[fields[field]];\n\n                if (!tizenFields) {\n                    // does something maps\n                    continue;\n                }\n\n                // construct the filter expression using the Tizen fields\n                for ( var index in tizenFields) {\n                    attributeFilter = new tizen.AttributeFilter(tizenFields[index], matchFlag, matchValue);\n                    if (attributeFilter !== null) {\n                        attributesArray.push(attributeFilter);\n                    }\n                }\n            }\n        }\n\n        // fullfil tizen find attribute as a single or a composite attribute\n        if (attributesArray.length == 1 ) {\n            filterExpression = attributeFilter[0];\n        } else if (attributesArray.length > 1) {\n            // combine the filters as a Union\n            filterExpression = new tizen.CompositeFilter(\"UNION\", attributesArray);\n        } else {\n            filterExpression = null;\n        }\n\n        return filterExpression;\n    },\n\n\n\n    /**\n     * Creates a Contact object from a Tizen Contact object, copying only\n     * the fields specified.\n     *\n     * This is intended as a privately used function but it is made globally\n     * available so that a Contact.save can convert a BlackBerry contact object\n     * into its W3C equivalent.\n     *\n     * @param {tizen.Contact}\n     *            tizenContact Tizen Contact object\n     * @param {String[]}\n     *            fields array of contact fields that should be copied\n     * @return {Contact} a contact object containing the specified fields or\n     *         null if the specified contact is null\n     */\n    createContact: function(tizenContact, fields) {\n\n        if (!tizenContact) {\n            return null;\n        }\n\n        // construct a new contact object\n        // always copy the contact id and displayName fields\n        var contact = new Contact(tizenContact.id, tizenContact.name.displayName);\n\n\n        // nothing to do\n        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {\n            return contact;\n        } else if (fields.length === 1 && fields[0] === \"*\") {\n            // Cordova enhancement to allow fields value of [\"*\"] to indicate\n            // all supported fields.\n            fields = allFields;\n        }\n\n        // add the fields specified\n        for ( var key in fields) {\n\n            var field = fields[key],\n                index = 0;\n\n            if (!field) {\n                continue;\n            }\n\n            // name\n            if (field.indexOf('name') === 0) {\n\n                var formattedName = (tizenContact.name.prefix || \"\");\n\n                if (tizenContact.name.firstName) {\n                    formattedName += ' ';\n                    formattedName += (tizenContact.name.firstName || \"\");\n                }\n\n                if (tizenContact.name.middleName) {\n                    formattedName += ' ';\n                    formattedName += (tizenContact.name.middleName || \"\");\n                }\n\n                if (tizenContact.name.lastName) {\n                    formattedName += ' ';\n                    formattedName += (tizenContact.name.lastName || \"\");\n                }\n\n                contact.name = new ContactName(\n                        formattedName,\n                        tizenContact.name.lastName,\n                        tizenContact.name.firstName,\n                        tizenContact.name.middleName,\n                        tizenContact.name.prefix,\n                        null);\n            }\n\n            // phoneNumbers\n            else if (field.indexOf('phoneNumbers') === 0) {\n\n                var phoneNumbers = [];\n\n                for (index = 0 ; index < tizenContact.phoneNumbers.length ; ++index) {\n\n                    phoneNumbers.push(\n                            new ContactField(\n                                    'PHONE',\n                                    tizenContact.phoneNumbers[index].number,\n                                    ((tizenContact.phoneNumbers[index].types[1]) &&  (tizenContact.emails[index].types[1] === \"PREF\") ) ? true : false));\n                }\n\n\n                contact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : null;\n            }\n\n            // emails\n            else if (field.indexOf('emails') === 0) {\n\n                var emails = [];\n\n                for (index = 0 ; index < tizenContact.emails.length ; ++index) {\n\n                    emails.push(\n                        new ContactField(\n                            'EMAILS',\n                            tizenContact.emails[index].email,\n                            ((tizenContact.emails[index].types[1]) &&  (tizenContact.emails[index].types[1] === \"PREF\") ) ? true : false));\n                }\n                contact.emails = emails.length > 0 ? emails : null;\n            }\n\n            // addresses\n            else if (field.indexOf('addresses') === 0) {\n\n                var addresses = [];\n                for (index = 0 ; index < tizenContact.addresses.length ; ++index) {\n\n                    addresses.push(\n                            new ContactAddress(\n                                    ((tizenContact.addresses[index].types[1] &&  tizenContact.addresses[index].types[1] === \"PREF\") ? true : false),\n                                    tizenContact.addresses[index].types[0] ? tizenContact.addresses[index].types[0] : \"HOME\",\n                                    null,\n                                    tizenContact.addresses[index].streetAddress,\n                                    tizenContact.addresses[index].city,\n                                    tizenContact.addresses[index].region,\n                                    tizenContact.addresses[index].postalCode,\n                                    tizenContact.addresses[index].country ));\n                }\n\n                contact.addresses = addresses.length > 0 ? addresses : null;\n            }\n\n            // birthday\n            else if (field.indexOf('birthday') === 0) {\n                if (utils.isDate(tizenContact.birthday)) {\n                    contact.birthday = tizenContact.birthday;\n                }\n            }\n\n            // note only one in Tizen Contact\n            else if (field.indexOf('note') === 0) {\n                if (tizenContact.note) {\n                    contact.note = tizenContact.note[0];\n                }\n            }\n\n            // organizations\n            else if (field.indexOf('organizations') === 0) {\n\n                var organizations = [];\n\n                // there's only one organization in a Tizen Address\n\n                if (tizenContact.organization) {\n                    organizations.push(\n                            new ContactOrganization(\n                                    true,\n                                    'WORK',\n                                    tizenContact.organization.name,\n                                    tizenContact.organization.department,\n                                    tizenContact.organization.jobTitle));\n                }\n\n                contact.organizations = organizations.length > 0 ? organizations : null;\n            }\n\n            // categories\n            else if (field.indexOf('categories') === 0) {\n\n                var categories = [];\n\n                if (tizenContact.categories) {\n\n                    for (index = 0 ; index < tizenContact.categories.length ; ++index) {\n                        categories.push(\n                                new ContactField(\n                                        'MAIN',\n                                        tizenContact.categories,\n                                        (index === 0) ));\n                    }\n\n                    contact.categories = categories.length > 0 ? categories : null;\n                }\n            }\n\n            // urls\n            else if (field.indexOf('urls') === 0) {\n                var urls = [];\n\n                if (tizenContact.urls) {\n                    for (index = 0 ; index <tizenContact.urls.length ; ++index) {\n                        urls.push(\n                                new ContactField(\n                                        tizenContact.urls[index].type,\n                                        tizenContact.urls[index].url,\n                                        (index === 0)));\n                    }\n                }\n\n                contact.urls = urls.length > 0 ? urls : null;\n            }\n\n            // photos\n            else if (field.indexOf('photos') === 0) {\n                var photos = [];\n\n                if (tizenContact.photoURI) {\n                    photos.push(new ContactField('URI', tizenContact.photoURI, true));\n                }\n\n                contact.photos = photos.length > 0 ? photos : null;\n            }\n        }\n\n        return contact;\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/ContactUtils.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/ContactUtils.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Device\", function(require, exports, module) {\n/*global tizen:false */\nvar channel = require('cordova/channel');\n\n// Tell cordova channel to wait on the CordovaInfoReady event\nchannel.waitForInitialization('onCordovaInfoReady');\n\nfunction Device() {\n    this.version = null;\n    this.uuid = null;\n    this.name = null;\n    this.cordova =  \"2.0.0\";\n    this.platform = \"Tizen\";\n\n    var me = this;\n\n    function onSuccessCallback(sysInfoProp) {\n        me.name = sysInfoProp.model;\n        me.uuid = sysInfoProp.imei;\n        me.version = sysInfoProp.version;\n        channel.onCordovaInfoReady.fire();\n    }\n\n    function onErrorCallback(error) {\n        console.log(\"error initializing cordova: \" + error);\n    }\n\n    channel.onCordovaReady.subscribeOnce(function() {\n        me.getDeviceInfo(onSuccessCallback, onErrorCallback);\n    });\n}\n\nDevice.prototype.getDeviceInfo = function(success, fail, args) {\n    tizen.systeminfo.getPropertyValue(\"Device\", success, fail);\n};\n\nmodule.exports = new Device();\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Device.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Device.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/File\", function(require, exports, module) {\n/*global WebKitBlobBuilder:false */\nvar FileError = require('cordova/plugin/FileError'),\n    DirectoryEntry = require('cordova/plugin/DirectoryEntry'),\n    FileEntry = require('cordova/plugin/FileEntry'),\n    File = require('cordova/plugin/File'),\n    FileSystem = require('cordova/plugin/FileSystem');\n\nvar nativeRequestFileSystem = window.webkitRequestFileSystem,\n    nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL,\n    NativeFileReader = window.FileReader;\n\nfunction getFileSystemName(nativeFs) {\n    return (nativeFs.name.indexOf(\"Persistent\") != -1) ? \"persistent\" : \"temporary\";\n}\n\nfunction makeEntry(entry) {\n    if (entry.isDirectory) {\n        return new DirectoryEntry(entry.name, decodeURI(entry.toURL()));\n    }\n    else {\n        return new FileEntry(entry.name, decodeURI(entry.toURL()));\n    }\n}\n\nmodule.exports = {\n    /* requestFileSystem */\n    requestFileSystem: function(successCallback, errorCallback, args) {\n        var type = args[0],\n            size = args[1];\n\n        nativeRequestFileSystem(type, size, function(nativeFs) {\n            successCallback(new FileSystem(getFileSystemName(nativeFs), makeEntry(nativeFs.root)));\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* resolveLocalFileSystemURI */\n    resolveLocalFileSystemURI: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            successCallback(makeEntry(entry));\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* DirectoryReader */\n    readEntries: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(dirEntry) {\n            var reader = dirEntry.createReader();\n            reader.readEntries(function(entries) {\n                var retVal = [];\n                for (var i = 0; i < entries.length; i++) {\n                    retVal.push(makeEntry(entries[i]));\n                }\n                successCallback(retVal);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* Entry */\n    getMetadata: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.getMetadata(function(metaData) {\n                successCallback(metaData.modificationTime);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    moveTo: function(successCallback, errorCallback, args) {\n        var srcUri = args[0],\n            parentUri = args[1],\n            name = args[2];\n\n        nativeResolveLocalFileSystemURI(srcUri, function(source) {\n            nativeResolveLocalFileSystemURI(parentUri, function(parent) {\n                source.moveTo(parent, name, function(entry) {\n                    successCallback(makeEntry(entry));\n                }, function(error) {\n                    errorCallback(error.code);\n                });\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    copyTo: function(successCallback, errorCallback, args) {\n        var srcUri = args[0],\n            parentUri = args[1],\n            name = args[2];\n\n        nativeResolveLocalFileSystemURI(srcUri, function(source) {\n            nativeResolveLocalFileSystemURI(parentUri, function(parent) {\n                source.copyTo(parent, name, function(entry) {\n                    successCallback(makeEntry(entry));\n                }, function(error) {\n                    errorCallback(error.code);\n                });\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    remove: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            if (entry.fullPath === \"/\") {\n                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);\n            } else {\n                entry.remove(successCallback, function(error) {\n                    errorCallback(error.code);\n                });\n            }\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    getParent: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.getParent(function(entry) {\n                successCallback(makeEntry(entry));\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* FileEntry */\n    getFileMetadata: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.file(function(file) {\n                var retVal = new File(file.name, decodeURI(entry.toURL()), file.type, file.lastModifiedDate, file.size);\n                successCallback(retVal);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* DirectoryEntry */\n    getDirectory: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            path = args[1],\n            options = args[2];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.getDirectory(path, options, function(entry) {\n                successCallback(makeEntry(entry));\n            }, function(error) {\n                if (error.code === FileError.INVALID_MODIFICATION_ERR) {\n                    if (options.create) {\n                        errorCallback(FileError.PATH_EXISTS_ERR);\n                    } else {\n                        errorCallback(FileError.ENCODING_ERR);\n                    }\n                } else {\n                    errorCallback(error.code);\n                }\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    removeRecursively: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            if (entry.fullPath === \"/\") {\n                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);\n            } else {\n                entry.removeRecursively(successCallback, function(error) {\n                    errorCallback(error.code);\n                });\n            }\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    getFile: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            path = args[1],\n            options = args[2];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            entry.getFile(path, options, function(entry) {\n                successCallback(makeEntry(entry));\n            }, function(error) {\n                if (error.code === FileError.INVALID_MODIFICATION_ERR) {\n                    if (options.create) {\n                        errorCallback(FileError.PATH_EXISTS_ERR);\n                    } else {\n                        errorCallback(FileError.ENCODING_ERR);\n                    }\n                } else {\n                    errorCallback(error.code);\n                }\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* FileReader */\n    readAsText: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            encoding = args[1];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            var onLoadEnd = function(evt) {\n                    if (!evt.target.error) {\n                        successCallback(evt.target.result);\n                    }\n            },\n                onError = function(evt) {\n                    errorCallback(evt.target.error.code);\n            };\n\n            var reader = new NativeFileReader();\n\n            reader.onloadend = onLoadEnd;\n            reader.onerror = onError;\n            entry.file(function(file) {\n                reader.readAsText(file, encoding);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    readAsDataURL: function(successCallback, errorCallback, args) {\n        var uri = args[0];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            var onLoadEnd = function(evt) {\n                    if (!evt.target.error) {\n                        successCallback(evt.target.result);\n                    }\n            },\n                onError = function(evt) {\n                    errorCallback(evt.target.error.code);\n            };\n\n            var reader = new NativeFileReader();\n\n            reader.onloadend = onLoadEnd;\n            reader.onerror = onError;\n            entry.file(function(file) {\n                reader.readAsDataURL(file);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    /* FileWriter */\n    write: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            text = args[1],\n            position = args[2];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            var onWriteEnd = function(evt) {\n                    if(!evt.target.error) {\n                        successCallback(evt.target.position - position);\n                    } else {\n                        errorCallback(evt.target.error.code);\n                    }\n            },\n                onError = function(evt) {\n                    errorCallback(evt.target.error.code);\n            };\n\n            entry.createWriter(function(writer) {\n                var blob = new WebKitBlobBuilder();\n                blob.append(text);\n\n                writer.onwriteend = onWriteEnd;\n                writer.onerror = onError;\n\n                writer.seek(position);\n                writer.write(blob.getBlob('text/plain'));\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    },\n\n    truncate: function(successCallback, errorCallback, args) {\n        var uri = args[0],\n            size = args[1];\n\n        nativeResolveLocalFileSystemURI(uri, function(entry) {\n            var onWriteEnd = function(evt) {\n                    if(!evt.target.error) {\n                        successCallback(evt.target.length);\n                    } else {\n                        errorCallback(evt.target.error.code);\n                    }\n            },\n                onError = function(evt) {\n                    errorCallback(evt.target.error.code);\n            };\n\n            entry.createWriter(function(writer) {\n                writer.onwriteend = onWriteEnd;\n                writer.onerror = onError;\n\n                writer.truncate(size);\n            }, function(error) {\n                errorCallback(error.code);\n            });\n        }, function(error) {\n            errorCallback(error.code);\n        });\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/File.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/File.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/FileTransfer\", function(require, exports, module) {\n/*global WebKitBlobBuilder:false */\nvar FileEntry = require('cordova/plugin/FileEntry'),\n    FileTransferError = require('cordova/plugin/FileTransferError'),\n    FileUploadResult = require('cordova/plugin/FileUploadResult');\n\nvar nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL;\n\nfunction getParentPath(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(0, pos + 1);\n}\n\nfunction getFileName(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(pos + 1);\n}\n\nmodule.exports = {\n    upload: function(successCallback, errorCallback, args) {\n        var filePath = args[0],\n            server = args[1],\n            fileKey = args[2],\n            fileName = args[3],\n            mimeType = args[4],\n            params = args[5],\n            /*trustAllHosts = args[6],*/\n            chunkedMode = args[7];\n\n        nativeResolveLocalFileSystemURI(filePath, function(entry) {\n            entry.file(function(file) {\n                function uploadFile(blobFile) {\n                    var fd = new FormData();\n\n                    fd.append(fileKey, blobFile, fileName);\n                    for (var prop in params) {\n                        if(params.hasOwnProperty(prop)) {\n                            fd.append(prop, params[prop]);\n                        }\n                    }\n\n                    var xhr = new XMLHttpRequest();\n                    xhr.open(\"POST\", server);\n                    xhr.onload = function(evt) {\n                        if (xhr.status == 200) {\n                            var result = new FileUploadResult();\n                            result.bytesSent = file.size;\n                            result.responseCode = xhr.status;\n                            result.response = xhr.response;\n                            successCallback(result);\n                        } else if (xhr.status == 404) {\n                            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));\n                        } else {\n                            errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));\n                        }\n                    };\n                    xhr.ontimeout = function(evt) {\n                        errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));\n                    };\n\n                    xhr.send(fd);\n                }\n\n                var bytesPerChunk;\n                if (chunkedMode === true) {\n                    bytesPerChunk = 1024 * 1024; // 1MB chunk sizes.\n                } else {\n                    bytesPerChunk = file.size;\n                }\n                var start = 0;\n                var end = bytesPerChunk;\n                while (start < file.size) {\n                    var chunk = file.webkitSlice(start, end, mimeType);\n                    uploadFile(chunk);\n                    start = end;\n                    end = start + bytesPerChunk;\n                }\n            },\n            function(error) {\n                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n            }\n            );\n        },\n        function(error) {\n            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n        }\n        );\n    },\n\n    download: function(successCallback, errorCallback, args) {\n        var url = args[0],\n            filePath = args[1];\n\n        var xhr = new XMLHttpRequest();\n\n        function writeFile(fileEntry) {\n            fileEntry.createWriter(function(writer) {\n                writer.onwriteend = function(evt) {\n                    if (!evt.target.error) {\n                        successCallback(new FileEntry(fileEntry.name, fileEntry.toURL()));\n                    } else {\n                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n                    }\n                };\n\n                writer.onerror = function(evt) {\n                    errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n                };\n\n                var builder = new WebKitBlobBuilder();\n                builder.append(xhr.response);\n                var blob = builder.getBlob();\n                writer.write(blob);\n            },\n            function(error) {\n                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n            });\n        }\n\n        xhr.onreadystatechange = function () {\n            if (xhr.readyState == xhr.DONE) {\n                if (xhr.status == 200 && xhr.response) {\n                    nativeResolveLocalFileSystemURI(getParentPath(filePath), function(dir) {\n                        dir.getFile(getFileName(filePath), {create: true}, writeFile, function(error) {\n                            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n                        });\n                    }, function(error) {\n                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));\n                    });\n                } else if (xhr.status == 404) {\n                    errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));\n                } else {\n                    errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));\n                }\n            }\n        };\n\n        xhr.open(\"GET\", url, true);\n        xhr.responseType = \"arraybuffer\";\n        xhr.send();\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/FileTransfer.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/FileTransfer.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Media\", function(require, exports, module) {\n/*global Media:false, webkitURL:false */\nvar MediaError = require('cordova/plugin/MediaError'),\n    audioObjects = {};\n\nmodule.exports = {\n    create: function (successCallback, errorCallback, args) {\n        var id = args[0], src = args[1];\n        console.log(\"media::create() - id =\" + id + \", src =\" + src);\n        audioObjects[id] = new Audio(src);\n        audioObjects[id].onStalledCB = function () {\n            console.log(\"media::onStalled()\");\n             audioObjects[id].timer = window.setTimeout(function () {\n                    audioObjects[id].pause();\n                    if (audioObjects[id].currentTime !== 0)\n                        audioObjects[id].currentTime = 0;\n                    console.log(\"media::onStalled() - MEDIA_ERROR -> \" + MediaError.MEDIA_ERR_ABORTED);\n                    var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, \"Stalled\");\n                    Media.onStatus(id, Media.MEDIA_ERROR, err);\n                }, 2000);\n        };\n        audioObjects[id].onEndedCB = function () {\n            console.log(\"media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED\");\n            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);\n        };\n        audioObjects[id].onErrorCB = function () {\n            console.log(\"media::onErrorCB() - MEDIA_ERROR -> \" + event.srcElement.error);\n            Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error);\n        };\n        audioObjects[id].onPlayCB = function () {\n            console.log(\"media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING\");\n            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);\n        };\n        audioObjects[id].onPlayingCB = function () {\n            console.log(\"media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING\");\n            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);\n        };\n        audioObjects[id].onDurationChangeCB = function () {\n            console.log(\"media::onDurationChangeCB() - MEDIA_DURATION -> \" +  audioObjects[id].duration);\n            Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration);\n        };\n        audioObjects[id].onTimeUpdateCB = function () {\n            console.log(\"media::onTimeUpdateCB() - MEDIA_POSITION -> \" +  audioObjects[id].currentTime);\n            Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime);\n        };\n        audioObjects[id].onCanPlayCB = function () {\n            console.log(\"media::onCanPlayCB()\");\n            window.clearTimeout(audioObjects[id].timer);\n            audioObjects[id].play();\n        };\n      },\n    startPlayingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0], src = args[1], options = args[2];\n        console.log(\"media::startPlayingAudio() - id =\" + id + \", src =\" + src + \", options =\" + options);\n        audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB);\n        audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB);\n        audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);\n        audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB);\n        audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB);\n        audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB);\n        audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB);\n        audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB);\n        audioObjects[id].play();\n    },\n    stopPlayingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        window.clearTimeout(audioObjects[id].timer);\n        audioObjects[id].pause();\n        if (audioObjects[id].currentTime !== 0)\n            audioObjects[id].currentTime = 0;\n        console.log(\"media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED\");\n        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);\n        audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB);\n        audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB);\n        audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);\n        audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB);\n        audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB);\n        audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB);\n        audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB);\n        audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB);\n    },\n    seekToAudio: function (successCallback, errorCallback, args) {\n        var id = args[0], milliseconds = args[1];\n        console.log(\"media::seekToAudio()\");\n         audioObjects[id].currentTime = milliseconds;\n        successCallback( audioObjects[id].currentTime);\n    },\n    pausePlayingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        console.log(\"media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED\");\n        audioObjects[id].pause();\n        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);\n    },\n    getCurrentPositionAudio: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        console.log(\"media::getCurrentPositionAudio()\");\n        successCallback(audioObjects[id].currentTime);\n    },\n    release: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        window.clearTimeout(audioObjects[id].timer);\n        console.log(\"media::release()\");\n    },\n    setVolume: function (successCallback, errorCallback, args) {\n        var id = args[0], volume = args[1];\n        console.log(\"media::setVolume()\");\n        audioObjects[id].volume = volume;\n    },\n    startRecordingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0], src = args[1];\n        console.log(\"media::startRecordingAudio() - id =\" + id + \", src =\" + src);\n\n        function gotStreamCB(stream) {\n            audioObjects[id].src = webkitURL.createObjectURL(stream);\n            console.log(\"media::startRecordingAudio() - stream CB\");\n        }\n\n        function gotStreamFailedCB(error) {\n            console.log(\"media::startRecordingAudio() - error CB:\" + error.toString());\n        }\n\n        if (navigator.webkitGetUserMedia) {\n            audioObjects[id] = new Audio();\n            navigator.webkitGetUserMedia('audio', gotStreamCB, gotStreamFailedCB);\n        } else {\n            console.log(\"webkitGetUserMedia not supported\");\n        }\n        successCallback();\n    },\n    stopRecordingAudio: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        console.log(\"media::stopRecordingAudio() - id =\" + id);\n        audioObjects[id].pause();\n        successCallback();\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Media.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Media.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/MediaError\", function(require, exports, module) {\n\n// The MediaError object already exists on Tizen. This prevents the Cordova\n// version from being defined. This object is used to merge in differences\n// between Tizen and Cordova MediaError objects.\nmodule.exports = {\n        MEDIA_ERR_NONE_ACTIVE : 0,\n        MEDIA_ERR_NONE_SUPPORTED : 4\n};\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/MediaError.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/MediaError.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/NetworkStatus\", function(require, exports, module) {\n/*global tizen:false */\nvar Connection = require('cordova/plugin/Connection');\n\nmodule.exports = {\n    getConnectionInfo: function (successCallback, errorCallback) {\n        var cncType = Connection.NONE;\n        var infoCount = 0;\n\n        function infoCB() {\n            infoCount++;\n            if (infoCount > 1)\n               successCallback(cncType);\n        }\n\n        function errorCB(error) {\n           console.log(\"Error: \" + error.code + \",\" + error.name + \",\" + error.message);\n           infoCB();\n        }\n\n        function wifiSuccessCB(wifi) {\n            if ((wifi.status === \"ON\")  && (wifi.ipAddress.length !== 0))\n                cncType = Connection.WIFI;\n            infoCB();\n        }\n\n        function cellularSuccessCB(cell) {\n            if ((cncType === Connection.NONE) && (cell.status === \"ON\") && (cell.ipAddress.length !== 0))\n                cncType = Connection.CELL_2G;\n            infoCB();\n        }\n\n        if (tizen.systeminfo.isSupported('WifiNetwork')) {\n            tizen.systeminfo.getPropertyValue('WifiNetwork', wifiSuccessCB, errorCB);\n        }\n\n        if (tizen.systeminfo.isSupported('CellularNetwork')) {\n            tizen.systeminfo.getPropertyValue('CellularNetwork', cellularSuccessCB, errorCB);\n        }\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/NetworkStatus.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/NetworkStatus.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/Notification\", function(require, exports, module) {\nvar SoundBeat = require('cordova/plugin/tizen/SoundBeat');\n\n/* TODO: get resource path from app environment? */\nvar soundBeat = new SoundBeat([\"./sounds/beep.wav\"]);\n\nmodule.exports = {\n\n    alert: function(message, alertCallback, title, buttonName) {\n        return this.confirm(message, alertCallback, title, buttonName);\n    },\n\n    confirm: function(message, confirmCallback, title, buttonLabels) {\n        var index            =    null,\n            overlayElement    =    null,\n            popup            =    null,\n            element         =    null,\n            titleString        =     null,\n            messageString    =    null,\n            buttonString    =    null,\n            buttonsArray    =    null;\n\n\n        console.log (\"message\" , message);\n        console.log (\"confirmCallback\" , confirmCallback);\n        console.log (\"title\" , title);\n        console.log (\"buttonLabels\" , buttonLabels);\n\n        titleString = '<div class=\"popup-title\"><p>' + title + '</p></div>';\n        messageString = '<div class=\"popup-text\"><p>' + message + '</p></div>';\n        buttonString = '<div class=\"popup-button-bg\"><ul>';\n\n        switch(typeof(buttonLabels))\n        {\n        case \"string\":\n            buttonsArray = buttonLabels.split(\",\");\n\n            if (buttonsArray === null) {\n                buttonsArray = buttonLabels;\n            }\n\n            for (index in buttonsArray) {\n                buttonString += '<li><input id=\"popup-button-' + buttonsArray[index]+\n                                '\" type=\"button\" value=\"' + buttonsArray[index] + '\" /></li>';\n                console.log (\"index: \", index,\"\");\n                console.log (\"buttonsArray[index]: \", buttonsArray[index]);\n                console.log (\"buttonString: \", buttonString);\n            }\n            break;\n\n        case \"array\":\n            if (buttonsArray === null) {\n                buttonsArray = buttonLabels;\n            }\n\n            for (index in buttonsArray) {\n                buttonString += '<li><input id=\"popup-button-' + buttonsArray[index]+\n                                '\" type=\"button\" value=\"' + buttonsArray[index] + '\" /></li>';\n                console.log (\"index: \", index,\"\");\n                console.log (\"buttonsArray[index]: \", buttonsArray[index]);\n                console.log (\"buttonString: \", buttonString);\n            }\n            break;\n        default:\n            console.log (\"cordova/plugin/tizen/Notification, default, buttonLabels: \", buttonLabels);\n            break;\n        }\n\n        buttonString += '</ul></div>';\n\n        overlayElement = document.createElement(\"div\");\n        overlayElement.className = 'ui-popupwindow-screen';\n\n        overlayElement.style.zIndex = 1001;\n        overlayElement.style.width = \"100%\";\n        overlayElement.style.height = \"100%\";\n        overlayElement.style.top = 0;\n        overlayElement.style.left = 0;\n        overlayElement.style.margin = 0;\n        overlayElement.style.padding = 0;\n        overlayElement.style.position = \"absolute\";\n\n        popup = document.createElement(\"div\");\n        popup.className = \"ui-popupwindow\";\n        popup.style.position = \"fixed\";\n        popup.style.zIndex = 1002;\n        popup.innerHTML = titleString + messageString + buttonString;\n\n        document.body.appendChild(overlayElement);\n        document.body.appendChild(popup);\n\n        function createListener(button) {\n            return function() {\n                document.body.removeChild(overlayElement);\n                document.body.removeChild(popup);\n                confirmCallback(button.value);\n            };\n        }\n\n       for (index in buttonsArray) {\n           console.log (\"index: \", index);\n\n           element = document.getElementById(\"popup-button-\" + buttonsArray[index]);\n           element.addEventListener(\"click\", createListener(element), false);\n       }\n    },\n\n    vibrate: function(milliseconds) {\n        console.log (\"milliseconds\" , milliseconds);\n\n        if (navigator.vibrate) {\n            navigator.vibrate(milliseconds);\n        }\n        else {\n            console.log (\"cordova/plugin/tizen/Notification, vibrate API does not exists\");\n        }\n    },\n\n    beep: function(count) {\n        console.log (\"count\" , count);\n        soundBeat.play(count);\n    }\n};\n\n\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/Notification.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/Notification.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/SoundBeat\", function(require, exports, module) {\n/*global webkitAudioContext:false */\n/*\n *  SoundBeat\n * used by Notification Manager beep method\n *\n * This class provides sounds play\n *\n * uses W3C  Web Audio API\n * uses BufferLoader object\n *\n * NOTE: the W3C Web Audio doc tells we do not need to recreate the audio\n *       context to play a sound but only the audiosourcenode (createBufferSource)\n *       in the webkit implementation we have to.\n *\n */\n\nvar BufferLoader = require('cordova/plugin/tizen/BufferLoader');\n\nfunction SoundBeat(urlList) {\n    this.context = null;\n    this.urlList = urlList || null;\n    this.buffers = null;\n}\n\n/*\n * This method play a loaded sounds on the Device\n * @param {Number} times Number of times to play loaded sounds.\n *\n */\nSoundBeat.prototype.play = function(times) {\n\n    var i = 0, sources = [], that = this;\n\n    function finishedLoading (bufferList) {\n        that.buffers = bufferList;\n\n        for (i = 0; i < that.buffers.length ; i +=1) {\n            if (that.context) {\n                sources[i] = that.context.createBufferSource();\n\n                sources[i].buffer = that.buffers[i];\n                sources[i].connect (that.context.destination);\n\n                sources[i].loop = true;\n                sources[i].noteOn (0);\n                sources[i].noteOff(sources[i].buffer.duration * times);\n            }\n        }\n    }\n\n    if (webkitAudioContext !== null) {\n        this.context = new webkitAudioContext();\n    }\n    else {\n        console.log (\"SoundBeat.prototype.play, w3c web audio api not supported\");\n        this.context = null;\n    }\n\n    if (this.context === null) {\n        console.log (\"SoundBeat.prototype.play, cannot create audio context object\");\n        return;\n    }\n\n    this.bufferLoader = new BufferLoader (this.context, this.urlList, finishedLoading);\n    if (this.bufferLoader === null) {\n        console.log (\"SoundBeat.prototype.play, cannot create buffer loader object\");\n        return;\n    }\n\n    this.bufferLoader.load();\n};\n\nmodule.exports = SoundBeat;\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/SoundBeat.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/SoundBeat.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/contacts\", function(require, exports, module) {\n/*global tizen:false */\nvar ContactError = require('cordova/plugin/ContactError'),\n    utils = require('cordova/utils'),\n    ContactUtils = require('cordova/plugin/tizen/ContactUtils');\n\nmodule.exports = {\n    /**\n     * Returns an array of Contacts matching the search criteria.\n     *\n     * @return array of Contacts matching search criteria\n     */\n    find : function(fields, successCB, failCB, options) {\n\n        // Success callback is required. Throw exception if not specified.\n        if (typeof successCB !== 'function') {\n            throw new TypeError(\"You must specify a success callback for the find command.\");\n        }\n\n        // Search qualifier is required and cannot be empty.\n        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {\n            if (typeof failCB === 'function') {\n                failCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));\n            }\n            return;\n        }\n\n        // options are optional\n        var filter =\"\",\n            multiple = false,\n            contacts = [],\n            tizenFilter = null;\n\n        if (options) {\n            filter = options.filter || \"\";\n            multiple =  options.multiple || false;\n        }\n\n        if (filter){\n            tizenFilter = ContactUtils.buildFilterExpression(fields, filter);\n        }\n\n        tizen.contact.getDefaultAddressBook().find(\n            function(tizenContacts) {\n                if (multiple) {\n                    for (var index in tizenContacts) {\n                        contacts.push(ContactUtils.createContact(tizenContacts[index], fields));\n                    }\n                }\n                else {\n                    contacts.push(ContactUtils.createContact(tizenContacts[0], fields));\n                }\n\n                // return results\n                successCB(contacts);\n            },\n            function(error) {\n                if (typeof failCB === 'function') {\n                    failCB(ContactError.UNKNOWN_ERROR);\n                }\n            },\n            tizenFilter,\n            null);\n    }\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/contacts.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/contacts.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/plugin/tizen/manager\", function(require, exports, module) {\nvar cordova = require('cordova');\n\nmodule.exports = {\n    exec: function (successCallback, errorCallback, clazz, action, args) {\n        var plugin = require('cordova/plugin/tizen/' + clazz);\n\n        if (plugin && typeof plugin[action] === 'function') {\n            var result = plugin[action](successCallback, errorCallback, args);\n            return result || {status: cordova.callbackStatus.NO_RESULT};\n        }\n\n        return {\"status\" : cordova.callbackStatus.CLASS_NOT_FOUND_EXCEPTION, \"message\" : \"Function \" + clazz + \"::\" + action + \" cannot be found\"};\n    },\n    resume: function () {},\n    pause: function () {},\n    destroy: function () {}\n};\n\n});\n\n//@ sourceURL=lib/tizen/plugin/tizen/manager.js")} catch(e) {console.log("exception: in lib/tizen/plugin/tizen/manager.js: " + e);console.log(e.stack);}
+try {eval("define(\"cordova/utils\", function(require, exports, module) {\nvar utils = exports;\n\n/**\n * Returns an indication of whether the argument is an array or not\n */\nutils.isArray = function(a) {\n    return Object.prototype.toString.call(a) == '[object Array]';\n};\n\n/**\n * Returns an indication of whether the argument is a Date or not\n */\nutils.isDate = function(d) {\n    return Object.prototype.toString.call(d) == '[object Date]';\n};\n\n/**\n * Does a deep clone of the object.\n */\nutils.clone = function(obj) {\n    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {\n        return obj;\n    }\n\n    var retVal, i;\n\n    if(utils.isArray(obj)){\n        retVal = [];\n        for(i = 0; i < obj.length; ++i){\n            retVal.push(utils.clone(obj[i]));\n        }\n        return retVal;\n    }\n\n    retVal = {};\n    for(i in obj){\n        if(!(i in retVal) || retVal[i] != obj[i]) {\n            retVal[i] = utils.clone(obj[i]);\n        }\n    }\n    return retVal;\n};\n\n/**\n * Returns a wrappered version of the function\n */\nutils.close = function(context, func, params) {\n    if (typeof params == 'undefined') {\n        return function() {\n            return func.apply(context, arguments);\n        };\n    } else {\n        return function() {\n            return func.apply(context, params);\n        };\n    }\n};\n\n/**\n * Create a UUID\n */\nutils.createUUID = function() {\n    return UUIDcreatePart(4) + '-' +\n        UUIDcreatePart(2) + '-' +\n        UUIDcreatePart(2) + '-' +\n        UUIDcreatePart(2) + '-' +\n        UUIDcreatePart(6);\n};\n\n/**\n * Extends a child object from a parent object using classical inheritance\n * pattern.\n */\nutils.extend = (function() {\n    // proxy used to establish prototype chain\n    var F = function() {};\n    // extend Child from Parent\n    return function(Child, Parent) {\n        F.prototype = Parent.prototype;\n        Child.prototype = new F();\n        Child.__super__ = Parent.prototype;\n        Child.prototype.constructor = Child;\n    };\n}());\n\n/**\n * Alerts a message in any available way: alert or console.log.\n */\nutils.alert = function(msg) {\n    if (alert) {\n        alert(msg);\n    } else if (console && console.log) {\n        console.log(msg);\n    }\n};\n\n/**\n * Formats a string and arguments following it ala sprintf()\n *\n * see utils.vformat() for more information\n */\nutils.format = function(formatString /* ,... */) {\n    var args = [].slice.call(arguments, 1);\n    return utils.vformat(formatString, args);\n};\n\n/**\n * Formats a string and arguments following it ala vsprintf()\n *\n * format chars:\n *   %j - format arg as JSON\n *   %o - format arg as JSON\n *   %c - format arg as ''\n *   %% - replace with '%'\n * any other char following % will format it's\n * arg via toString().\n *\n * for rationale, see FireBug's Console API:\n *    http://getfirebug.com/wiki/index.php/Console_API\n */\nutils.vformat = function(formatString, args) {\n    if (formatString === null || formatString === undefined) return \"\";\n    if (arguments.length == 1) return formatString.toString();\n    if (typeof formatString != \"string\") return formatString.toString();\n\n    var pattern = /(.*?)%(.)(.*)/;\n    var rest    = formatString;\n    var result  = [];\n\n    while (args.length) {\n        var arg   = args.shift();\n        var match = pattern.exec(rest);\n\n        if (!match) break;\n\n        rest = match[3];\n\n        result.push(match[1]);\n\n        if (match[2] == '%') {\n            result.push('%');\n            args.unshift(arg);\n            continue;\n        }\n\n        result.push(formatted(arg, match[2]));\n    }\n\n    result.push(rest);\n\n    return result.join('');\n};\n\n//------------------------------------------------------------------------------\nfunction UUIDcreatePart(length) {\n    var uuidpart = \"\";\n    for (var i=0; i<length; i++) {\n        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);\n        if (uuidchar.length == 1) {\n            uuidchar = \"0\" + uuidchar;\n        }\n        uuidpart += uuidchar;\n    }\n    return uuidpart;\n}\n\n//------------------------------------------------------------------------------\nfunction formatted(object, formatChar) {\n\n    try {\n        switch(formatChar) {\n            case 'j':\n            case 'o': return JSON.stringify(object);\n            case 'c': return '';\n        }\n    }\n    catch (e) {\n        return \"error JSON.stringify()ing argument: \" + e;\n    }\n\n    if ((object === null) || (object === undefined)) {\n        return Object.prototype.toString.call(object);\n    }\n\n    return object.toString();\n}\n\n});\n\n//@ sourceURL=lib/common/utils.js")} catch(e) {console.log("exception: in lib/common/utils.js: " + e);console.log(e.stack);}
+
+window.cordova = require('cordova');
+
+try {eval("(function (context) {\n    var channel = require(\"cordova/channel\"),\n        _self = {\n            boot: function () {\n                /**\n                 * Create all cordova objects once page has fully loaded and native side is ready.\n                 */\n                channel.join(function() {\n                    var builder = require('cordova/builder'),\n                        base = require('cordova/common'),\n                        platform = require('cordova/platform');\n\n                    // Drop the common globals into the window object, but be nice and don't overwrite anything.\n                    builder.build(base.objects).intoButDontClobber(window);\n\n                    // Drop the platform-specific globals into the window object\n                    // and clobber any existing object.\n                    builder.build(platform.objects).intoAndClobber(window);\n\n                    // Merge the platform-specific overrides/enhancements into\n                    // the window object.\n                    if (typeof platform.merges !== 'undefined') {\n                        builder.build(platform.merges).intoAndMerge(window);\n                    }\n\n                    // Call the platform-specific initialization\n                    platform.initialize();\n\n                    // Fire event to notify that all objects are created\n                    channel.onCordovaReady.fire();\n\n                    // Fire onDeviceReady event once all constructors have run and\n                    // cordova info has been received from native side.\n                    channel.join(function() {\n                        require('cordova').fireDocumentEvent('deviceready');\n                    }, channel.deviceReadyChannelsArray);\n\n                }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);\n            }\n        };\n\n    // boot up once native side is ready\n    channel.onNativeReady.subscribeOnce(_self.boot);\n\n    // _nativeReady is global variable that the native side can set\n    // to signify that the native code is ready. It is a global since\n    // it may be called before any cordova JS is ready.\n    if (window._nativeReady) {\n        channel.onNativeReady.fire();\n    }\n\n}(window));\n\n//@ sourceURL=lib/scripts/bootstrap.js")} catch(e) {console.log("exception: in lib/scripts/bootstrap.js: " + e);console.log(e.stack);}
+try {eval("require('cordova/channel').onNativeReady.fire();\n\n//@ sourceURL=lib/scripts/bootstrap-tizen.js")} catch(e) {console.log("exception: in lib/scripts/bootstrap-tizen.js: " + e);console.log(e.stack);}
+
+})();
\ No newline at end of file
diff --git a/js/cordova.tizen.js b/js/cordova.tizen.js
new file mode 100644
index 0000000..98110c7
--- /dev/null
+++ b/js/cordova.tizen.js
@@ -0,0 +1,7066 @@
+// commit 7dd17b00544742d14ecdeff2148a66480680f12b
+
+// File generated at :: Thu Jul 26 2012 17:32:56 GMT+0200 (CEST)
+
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+;(function() {
+
+// file: lib/scripts/require.js
+var require,
+    define;
+
+(function () {
+    var modules = {};
+
+    function build(module) {
+        var factory = module.factory;
+        module.exports = {};
+        delete module.factory;
+        factory(require, module.exports, module);
+        return module.exports;
+    }
+
+    require = function (id) {
+        if (!modules[id]) {
+            throw "module " + id + " not found";
+        }
+        return modules[id].factory ? build(modules[id]) : modules[id].exports;
+    };
+
+    define = function (id, factory) {
+        if (modules[id]) {
+            throw "module " + id + " already defined";
+        }
+
+        modules[id] = {
+            id: id,
+            factory: factory
+        };
+    };
+
+    define.remove = function (id) {
+        delete modules[id];
+    };
+
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+    module.exports.require = require;
+    module.exports.define = define;
+}
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+var channel = require('cordova/channel');
+
+/**
+ * Listen for DOMContentLoaded and notify our channel subscribers.
+ */
+document.addEventListener('DOMContentLoaded', function() {
+    channel.onDOMContentLoaded.fire();
+}, false);
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+    channel.onDOMContentLoaded.fire();
+}
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+    windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof documentEventHandlers[e] != 'undefined') {
+        if (evt === 'deviceready') {
+            documentEventHandlers[e].subscribeOnce(handler);
+        } else {
+            documentEventHandlers[e].subscribe(handler);
+        }
+    } else {
+        m_document_addEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof windowEventHandlers[e] != 'undefined') {
+        windowEventHandlers[e].subscribe(handler);
+    } else {
+        m_window_addEventListener.call(window, evt, handler, capture);
+    }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof documentEventHandlers[e] != "undefined") {
+        documentEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_document_removeEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof windowEventHandlers[e] != "undefined") {
+        windowEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_window_removeEventListener.call(window, evt, handler, capture);
+    }
+};
+
+function createEvent(type, data) {
+    var event = document.createEvent('Events');
+    event.initEvent(type, false, false);
+    if (data) {
+        for (var i in data) {
+            if (data.hasOwnProperty(i)) {
+                event[i] = data[i];
+            }
+        }
+    }
+    return event;
+}
+
+if(typeof window.console === "undefined") {
+    window.console = {
+        log:function(){}
+    };
+}
+
+var cordova = {
+    define:define,
+    require:require,
+    /**
+     * Methods to add/remove your own addEventListener hijacking on document + window.
+     */
+    addWindowEventHandler:function(event, opts) {
+        return (windowEventHandlers[event] = channel.create(event, opts));
+    },
+    addDocumentEventHandler:function(event, opts) {
+        return (documentEventHandlers[event] = channel.create(event, opts));
+    },
+    removeWindowEventHandler:function(event) {
+        delete windowEventHandlers[event];
+    },
+    removeDocumentEventHandler:function(event) {
+        delete documentEventHandlers[event];
+    },
+    /**
+     * Retreive original event handlers that were replaced by Cordova
+     *
+     * @return object
+     */
+    getOriginalHandlers: function() {
+        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+    },
+    /**
+     * Method to fire event from native code
+     */
+    fireDocumentEvent: function(type, data) {
+        var evt = createEvent(type, data);
+        if (typeof documentEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                documentEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            document.dispatchEvent(evt);
+        }
+    },
+    fireWindowEvent: function(type, data) {
+        var evt = createEvent(type,data);
+        if (typeof windowEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                windowEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            window.dispatchEvent(evt);
+        }
+    },
+    // TODO: this is Android only; think about how to do this better
+    shuttingDown:false,
+    UsePolling:false,
+    // END TODO
+
+    // TODO: iOS only
+    // This queue holds the currently executing command and all pending
+    // commands executed with cordova.exec().
+    commandQueue:[],
+    // Indicates if we're currently in the middle of flushing the command
+    // queue on the native side.
+    commandQueueFlushing:false,
+    // END TODO
+    /**
+     * Plugin callback mechanism.
+     */
+    callbackId: 0,
+    callbacks:  {},
+    callbackStatus: {
+        NO_RESULT: 0,
+        OK: 1,
+        CLASS_NOT_FOUND_EXCEPTION: 2,
+        ILLEGAL_ACCESS_EXCEPTION: 3,
+        INSTANTIATION_EXCEPTION: 4,
+        MALFORMED_URL_EXCEPTION: 5,
+        IO_EXCEPTION: 6,
+        INVALID_ACTION: 7,
+        JSON_EXCEPTION: 8,
+        ERROR: 9
+    },
+
+    /**
+     * Called by native code when returning successful result from an action.
+     *
+     * @param callbackId
+     * @param args
+     */
+    callbackSuccess: function(callbackId, args) {
+        if (cordova.callbacks[callbackId]) {
+
+            // If result is to be sent to callback
+            if (args.status == cordova.callbackStatus.OK) {
+                try {
+                    if (cordova.callbacks[callbackId].success) {
+                        cordova.callbacks[callbackId].success(args.message);
+                    }
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+callbackId+" = "+e);
+                }
+            }
+
+            // Clear callback if not expecting any more results
+            if (!args.keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+
+    /**
+     * Called by native code when returning error result from an action.
+     *
+     * @param callbackId
+     * @param args
+     */
+    callbackError: function(callbackId, args) {
+        if (cordova.callbacks[callbackId]) {
+            try {
+                if (cordova.callbacks[callbackId].fail) {
+                    cordova.callbacks[callbackId].fail(args.message);
+                }
+            }
+            catch (e) {
+                console.log("Error in error callback: "+callbackId+" = "+e);
+            }
+
+            // Clear callback if not expecting any more results
+            if (!args.keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+    addConstructor: function(func) {
+        channel.onCordovaReady.subscribeOnce(function() {
+            try {
+                func();
+            } catch(e) {
+                console.log("Failed to run constructor: " + e);
+            }
+        });
+    }
+};
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addDocumentEventHandler('deviceready');
+
+module.exports = cordova;
+
+});
+
+// file: lib/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+    for (var prop in objects) {
+        if (objects.hasOwnProperty(prop)) {
+            func.apply(context, [objects[prop], prop]);
+        }
+    }
+}
+
+function include(parent, objects, clobber, merge) {
+    each(objects, function (obj, key) {
+        try {
+          var result = obj.path ? require(obj.path) : {};
+
+          if (clobber) {
+              // Clobber if it doesn't exist.
+              if (typeof parent[key] === 'undefined') {
+                  parent[key] = result;
+              } else if (typeof obj.path !== 'undefined') {
+                  // If merging, merge properties onto parent, otherwise, clobber.
+                  if (merge) {
+                      recursiveMerge(parent[key], result);
+                  } else {
+                      parent[key] = result;
+                  }
+              }
+              result = parent[key];
+          } else {
+            // Overwrite if not currently defined.
+            if (typeof parent[key] == 'undefined') {
+              parent[key] = result;
+            } else if (merge && typeof obj.path !== 'undefined') {
+              // If merging, merge parent onto result
+              recursiveMerge(result, parent[key]);
+              parent[key] = result;
+            } else {
+              // Set result to what already exists, so we can build children into it if they exist.
+              result = parent[key];
+            }
+          }
+
+          if (obj.children) {
+            include(result, obj.children, clobber, merge);
+          }
+        } catch(e) {
+          utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+        }
+    });
+}
+
+/**
+ * Merge properties from one object onto another recursively.  Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+    for (var prop in src) {
+        if (src.hasOwnProperty(prop)) {
+            if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) {
+                // If the target object is a constructor override off prototype.
+                target.prototype[prop] = src[prop];
+            } else {
+                target[prop] = typeof src[prop] === 'object' ? recursiveMerge(
+                        target[prop], src[prop]) : src[prop];
+            }
+        }
+    }
+    return target;
+}
+
+module.exports = {
+    build: function (objects) {
+        return {
+            intoButDontClobber: function (target) {
+                include(target, objects, false, false);
+            },
+            intoAndClobber: function(target) {
+                include(target, objects, true, false);
+            },
+            intoAndMerge: function(target) {
+                include(target, objects, true, true);
+            }
+        };
+    }
+};
+
+});
+
+// file: lib/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+var utils = require('cordova/utils');
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded         Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady              Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady             Internal event fired when all Cordova JavaScript objects have been created.
+ * onCordovaInfoReady         Internal event fired when device properties are available.
+ * onCordovaConnectionReady   Internal event fired when the connection property has been set.
+ * onDeviceReady              User event fired to indicate that Cordova is ready
+ * onResume                   User event fired to indicate a start/resume lifecycle event
+ * onPause                    User event fired to indicate a pause lifecycle event
+ * onDestroy                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The only Cordova events that user code should register for are:
+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ *      pause                 App has moved to background
+ *      resume                App has returned to foreground
+ *
+ * Listeners can be registered as:
+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);
+ *      document.addEventListener("resume", myResumeListener, false);
+ *      document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ *      window.onload
+ *      window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type  String the channel name
+ * @param opts  Object options to pass into the channel, currently
+ *                     supports:
+ *                     onSubscribe: callback that fires when
+ *                       something subscribes to the Channel. Sets
+ *                       context to the Channel.
+ *                     onUnsubscribe: callback that fires when
+ *                       something unsubscribes to the Channel. Sets
+ *                       context to the Channel.
+ */
+var Channel = function(type, opts) {
+    this.type = type;
+    this.handlers = {};
+    this.numHandlers = 0;
+    this.guid = 1;
+    this.fired = false;
+    this.enabled = true;
+    this.events = {
+        onSubscribe:null,
+        onUnsubscribe:null
+    };
+    if (opts) {
+        if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe;
+        if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe;
+    }
+},
+    channel = {
+        /**
+         * Calls the provided function only after all of the channels specified
+         * have been fired.
+         */
+        join: function (h, c) {
+            var i = c.length;
+            var len = i;
+            var f = function() {
+                if (!(--i)) h();
+            };
+            for (var j=0; j<len; j++) {
+                !c[j].fired?c[j].subscribeOnce(f):i--;
+            }
+            if (!i) h();
+        },
+        create: function (type, opts) {
+            channel[type] = new Channel(type, opts);
+            return channel[type];
+        },
+
+        /**
+         * cordova Channels that must fire before "deviceready" is fired.
+         */
+        deviceReadyChannelsArray: [],
+        deviceReadyChannelsMap: {},
+
+        /**
+         * Indicate that a feature needs to be initialized before it is ready to be used.
+         * This holds up Cordova's "deviceready" event until the feature has been initialized
+         * and Cordova.initComplete(feature) is called.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        waitForInitialization: function(feature) {
+            if (feature) {
+                var c = null;
+                if (this[feature]) {
+                    c = this[feature];
+                }
+                else {
+                    c = this.create(feature);
+                }
+                this.deviceReadyChannelsMap[feature] = c;
+                this.deviceReadyChannelsArray.push(c);
+            }
+        },
+
+        /**
+         * Indicate that initialization code has completed and the feature is ready to be used.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        initializationComplete: function(feature) {
+            var c = this.deviceReadyChannelsMap[feature];
+            if (c) {
+                c.fire();
+            }
+        }
+    };
+
+function forceFunction(f) {
+    if (f === null || f === undefined || typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c, g) {
+    // need a function to call
+    forceFunction(f);
+
+    var func = f;
+    if (typeof c == "object") { func = utils.close(c, f); }
+
+    g = g || func.observer_guid || f.observer_guid;
+    if (!g) {
+        // first time we've seen this subscriber
+        g = this.guid++;
+    }
+    else {
+        // subscriber already handled; dont set it twice
+        return g;
+    }
+    func.observer_guid = g;
+    f.observer_guid = g;
+    this.handlers[g] = func;
+    this.numHandlers++;
+    if (this.events.onSubscribe) this.events.onSubscribe.call(this);
+    if (this.fired) func.call(this);
+    return g;
+};
+
+/**
+ * Like subscribe but the function is only called once and then it
+ * auto-unsubscribes itself.
+ */
+Channel.prototype.subscribeOnce = function(f, c) {
+    // need a function to call
+    forceFunction(f);
+
+    var g = null;
+    var _this = this;
+    var m = function() {
+        f.apply(c || null, arguments);
+        _this.unsubscribe(g);
+    };
+    if (this.fired) {
+        if (typeof c == "object") { f = utils.close(c, f); }
+        f.apply(this, this.fireArgs);
+    } else {
+        g = this.subscribe(m);
+    }
+    return g;
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(g) {
+    // need a function to unsubscribe
+    if (g === null || g === undefined) { throw "You must pass _something_ into Channel.unsubscribe"; }
+
+    if (typeof g == 'function') { g = g.observer_guid; }
+    var handler = this.handlers[g];
+    if (handler) {
+        if (handler.observer_guid) handler.observer_guid=null;
+        this.handlers[g] = null;
+        delete this.handlers[g];
+        this.numHandlers--;
+        if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);
+    }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+    if (this.enabled) {
+        var fail = false;
+        this.fired = true;
+        for (var item in this.handlers) {
+            var handler = this.handlers[item];
+            if (typeof handler == 'function') {
+                var rv = (handler.apply(this, arguments)===false);
+                fail = fail || rv;
+            }
+        }
+        this.fireArgs = arguments;
+        return !fail;
+    }
+    return true;
+};
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.create('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.create('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.create('onCordovaReady');
+
+// Event to indicate that device properties are available
+channel.create('onCordovaInfoReady');
+
+// Event to indicate that the connection property has been set.
+channel.create('onCordovaConnectionReady');
+
+// Event to indicate that Cordova is ready
+channel.create('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.create('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onCordovaConnectionReady');
+
+module.exports = channel;
+
+});
+
+// file: lib/common/common.js
+define("cordova/common", function(require, exports, module) {
+module.exports = {
+    objects: {
+        cordova: {
+            path: 'cordova',
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                },
+                logger: {
+                    path: 'cordova/plugin/logger'
+                }
+            }
+        },
+        Cordova: {
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                }
+            }
+        },
+        PhoneGap:{
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                }
+            }
+        },
+        navigator: {
+            children: {
+                notification: {
+                    path: 'cordova/plugin/notification'
+                },
+                accelerometer: {
+                    path: 'cordova/plugin/accelerometer'
+                },
+                battery: {
+                    path: 'cordova/plugin/battery'
+                },
+                camera:{
+                    path: 'cordova/plugin/Camera'
+                },
+                compass:{
+                    path: 'cordova/plugin/compass'
+                },
+                contacts: {
+                    path: 'cordova/plugin/contacts'
+                },
+                device:{
+                    children:{
+                        capture: {
+                            path: 'cordova/plugin/capture'
+                        }
+                    }
+                },
+                geolocation: {
+                    path: 'cordova/plugin/geolocation'
+                },
+                network: {
+                    children: {
+                        connection: {
+                            path: 'cordova/plugin/network'
+                        }
+                    }
+                },
+                splashscreen: {
+                    path: 'cordova/plugin/splashscreen'
+                }
+            }
+        },
+        Acceleration: {
+            path: 'cordova/plugin/Acceleration'
+        },
+        Camera:{
+            path: 'cordova/plugin/CameraConstants'
+        },
+        CameraPopoverOptions: {
+            path: 'cordova/plugin/CameraPopoverOptions'
+        },
+        CaptureError: {
+            path: 'cordova/plugin/CaptureError'
+        },
+        CaptureAudioOptions:{
+            path: 'cordova/plugin/CaptureAudioOptions'
+        },
+        CaptureImageOptions: {
+            path: 'cordova/plugin/CaptureImageOptions'
+        },
+        CaptureVideoOptions: {
+            path: 'cordova/plugin/CaptureVideoOptions'
+        },
+        CompassHeading:{
+            path: 'cordova/plugin/CompassHeading'
+        },
+        CompassError:{
+            path: 'cordova/plugin/CompassError'
+        },
+        ConfigurationData: {
+            path: 'cordova/plugin/ConfigurationData'
+        },
+        Connection: {
+            path: 'cordova/plugin/Connection'
+        },
+        Contact: {
+            path: 'cordova/plugin/Contact'
+        },
+        ContactAddress: {
+            path: 'cordova/plugin/ContactAddress'
+        },
+        ContactError: {
+            path: 'cordova/plugin/ContactError'
+        },
+        ContactField: {
+            path: 'cordova/plugin/ContactField'
+        },
+        ContactFindOptions: {
+            path: 'cordova/plugin/ContactFindOptions'
+        },
+        ContactName: {
+            path: 'cordova/plugin/ContactName'
+        },
+        ContactOrganization: {
+            path: 'cordova/plugin/ContactOrganization'
+        },
+        Coordinates: {
+            path: 'cordova/plugin/Coordinates'
+        },
+        device: {
+            path: 'cordova/plugin/device'
+        },
+        DirectoryEntry: {
+            path: 'cordova/plugin/DirectoryEntry'
+        },
+        DirectoryReader: {
+            path: 'cordova/plugin/DirectoryReader'
+        },
+        Entry: {
+            path: 'cordova/plugin/Entry'
+        },
+        File: {
+            path: 'cordova/plugin/File'
+        },
+        FileEntry: {
+            path: 'cordova/plugin/FileEntry'
+        },
+        FileError: {
+            path: 'cordova/plugin/FileError'
+        },
+        FileReader: {
+            path: 'cordova/plugin/FileReader'
+        },
+        FileSystem: {
+            path: 'cordova/plugin/FileSystem'
+        },
+        FileTransfer: {
+            path: 'cordova/plugin/FileTransfer'
+        },
+        FileTransferError: {
+            path: 'cordova/plugin/FileTransferError'
+        },
+        FileUploadOptions: {
+            path: 'cordova/plugin/FileUploadOptions'
+        },
+        FileUploadResult: {
+            path: 'cordova/plugin/FileUploadResult'
+        },
+        FileWriter: {
+            path: 'cordova/plugin/FileWriter'
+        },
+        Flags: {
+            path: 'cordova/plugin/Flags'
+        },
+        LocalFileSystem: {
+            path: 'cordova/plugin/LocalFileSystem'
+        },
+        Media: {
+            path: 'cordova/plugin/Media'
+        },
+        MediaError: {
+            path: 'cordova/plugin/MediaError'
+        },
+        MediaFile: {
+            path: 'cordova/plugin/MediaFile'
+        },
+        MediaFileData:{
+            path: 'cordova/plugin/MediaFileData'
+        },
+        Metadata:{
+            path: 'cordova/plugin/Metadata'
+        },
+        Position: {
+            path: 'cordova/plugin/Position'
+        },
+        PositionError: {
+            path: 'cordova/plugin/PositionError'
+        },
+        ProgressEvent: {
+            path: 'cordova/plugin/ProgressEvent'
+        },
+        requestFileSystem:{
+            path: 'cordova/plugin/requestFileSystem'
+        },
+        resolveLocalFileSystemURI:{
+            path: 'cordova/plugin/resolveLocalFileSystemURI'
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/exec.js
+define("cordova/exec", function(require, exports, module) {
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchrounous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} successCB  The success callback
+ * @param {Function} failCB     The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ */
+
+var tizen = require('cordova/plugin/tizen/manager'),
+    cordova = require('cordova'),
+    utils = require('cordova/utils');
+
+module.exports = function(successCB, failCB, service, action, args) {
+
+    try {
+        var v = tizen.exec(successCB, failCB, service, action, args);
+
+        // If status is OK, then return value back to caller
+        if (v.status == cordova.callbackStatus.OK) {
+
+            // If there is a success callback, then call it now with returned value
+            if (successCB) {
+                try {
+                    successCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+ service + "." + action + " = " + e);
+                }
+
+            }
+            return v.message;
+        } else if (v.status == cordova.callbackStatus.NO_RESULT) {
+            // Nothing to do here
+        } else {
+            // If error, then display error
+            console.log("Error: " + service + "." + action + " Status=" + v.status + " Message=" + v.message);
+
+            // If there is a fail callback, then call it now with returned value
+            if (failCB) {
+                try {
+                    failCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in error callback: " + service + "." + action + " = "+e);
+                }
+            }
+            return null;
+        }
+    } catch (e) {
+        utils.alert("Error: " + e);
+    }
+};
+
+});
+
+// file: lib/tizen/platform.js
+define("cordova/platform", function(require, exports, module) {
+module.exports = {
+    id: "tizen",
+    initialize: function() {},
+    objects: {
+        device: {
+            path: "cordova/plugin/tizen/Device"
+        },
+        File: { // exists natively, override
+            path: "cordova/plugin/File"
+        },
+        FileReader: { // exists natively, override
+            path: "cordova/plugin/FileReader"
+        },
+        FileError: { //exists natively, override
+            path: "cordova/plugin/FileError"
+        }
+    },
+    merges: {
+        MediaError: { // exists natively
+            path: "cordova/plugin/tizen/MediaError"
+        },
+        navigator: {
+            children: {
+                device: {
+                    path: "cordova/plugin/tizen/Device"
+                },
+                contacts: {
+                    path: "cordova/plugin/tizen/contacts"
+                },
+               notification: {
+                   path: "cordova/plugin/tizen/Notification"
+               }
+            }
+        },
+        Contact: {
+            path: "cordova/plugin/tizen/Contact"
+        }
+    }
+};
+
+});
+
+// file: lib/common/plugin/Acceleration.js
+define("cordova/plugin/Acceleration", function(require, exports, module) {
+var Acceleration = function(x, y, z, timestamp) {
+    this.x = x;
+    this.y = y;
+    this.z = z;
+    this.timestamp = timestamp || (new Date()).getTime();
+};
+
+module.exports = Acceleration;
+
+});
+
+// file: lib/common/plugin/Camera.js
+define("cordova/plugin/Camera", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    Camera = require('cordova/plugin/CameraConstants');
+
+var cameraExport = {};
+
+// Tack on the Camera Constants to the base camera plugin.
+for (var key in Camera) {
+    cameraExport[key] = Camera[key];
+}
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+cameraExport.getPicture = function(successCallback, errorCallback, options) {
+    // successCallback required
+    if (typeof successCallback != "function") {
+        console.log("Camera Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback != "function")) {
+        console.log("Camera Error: errorCallback is not a function");
+        return;
+    }
+
+    var quality = 50;
+    if (options && typeof options.quality == "number") {
+        quality = options.quality;
+    } else if (options && typeof options.quality == "string") {
+        var qlity = parseInt(options.quality, 10);
+        if (isNaN(qlity) === false) {
+            quality = qlity.valueOf();
+        }
+    }
+
+    var destinationType = Camera.DestinationType.FILE_URI;
+    if (typeof options.destinationType == "number") {
+        destinationType = options.destinationType;
+    }
+
+    var sourceType = Camera.PictureSourceType.CAMERA;
+    if (typeof options.sourceType == "number") {
+        sourceType = options.sourceType;
+    }
+
+    var targetWidth = -1;
+    if (typeof options.targetWidth == "number") {
+        targetWidth = options.targetWidth;
+    } else if (typeof options.targetWidth == "string") {
+        var width = parseInt(options.targetWidth, 10);
+        if (isNaN(width) === false) {
+            targetWidth = width.valueOf();
+        }
+    }
+
+    var targetHeight = -1;
+    if (typeof options.targetHeight == "number") {
+        targetHeight = options.targetHeight;
+    } else if (typeof options.targetHeight == "string") {
+        var height = parseInt(options.targetHeight, 10);
+        if (isNaN(height) === false) {
+            targetHeight = height.valueOf();
+        }
+    }
+
+    var encodingType = Camera.EncodingType.JPEG;
+    if (typeof options.encodingType == "number") {
+        encodingType = options.encodingType;
+    }
+
+    var mediaType = Camera.MediaType.PICTURE;
+    if (typeof options.mediaType == "number") {
+        mediaType = options.mediaType;
+    }
+    var allowEdit = false;
+    if (typeof options.allowEdit == "boolean") {
+        allowEdit = options.allowEdit;
+    } else if (typeof options.allowEdit == "number") {
+        allowEdit = options.allowEdit <= 0 ? false : true;
+    }
+    var correctOrientation = false;
+    if (typeof options.correctOrientation == "boolean") {
+        correctOrientation = options.correctOrientation;
+    } else if (typeof options.correctOrientation == "number") {
+        correctOrientation = options.correctOrientation <=0 ? false : true;
+    }
+    var saveToPhotoAlbum = false;
+    if (typeof options.saveToPhotoAlbum == "boolean") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum;
+    } else if (typeof options.saveToPhotoAlbum == "number") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum <=0 ? false : true;
+    }
+    var popoverOptions = null;
+    if (typeof options.popoverOptions == "object") {
+        popoverOptions = options.popoverOptions;
+    }
+
+    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
+                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+
+    exec(successCallback, errorCallback, "Camera", "takePicture", args);
+};
+
+cameraExport.cleanup = function(successCallback, errorCallback) {
+    exec(successCallback, errorCallback, "Camera", "cleanup", []);
+};
+
+module.exports = cameraExport;
+});
+
+// file: lib/common/plugin/CameraConstants.js
+define("cordova/plugin/CameraConstants", function(require, exports, module) {
+module.exports = {
+  DestinationType:{
+    DATA_URL: 0,         // Return base64 encoded string
+    FILE_URI: 1          // Return file uri (content://media/external/images/media/2 for Android)
+  },
+  EncodingType:{
+    JPEG: 0,             // Return JPEG encoded image
+    PNG: 1               // Return PNG encoded image
+  },
+  MediaType:{
+    PICTURE: 0,          // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
+    VIDEO: 1,            // allow selection of video only, ONLY RETURNS URL
+    ALLMEDIA : 2         // allow selection from all media types
+  },
+  PictureSourceType:{
+    PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
+    CAMERA : 1,          // Take picture from camera
+    SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)
+  },
+  PopoverArrowDirection:{
+      ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
+      ARROW_DOWN : 2,
+      ARROW_LEFT : 4,
+      ARROW_RIGHT : 8,
+      ARROW_ANY : 15
+  }
+};
+});
+
+// file: lib/common/plugin/CameraPopoverOptions.js
+define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
+var Camera = require('cordova/plugin/CameraConstants');
+
+/**
+ * Encapsulates options for iOS Popover image picker
+ */
+var CameraPopoverOptions = function(x,y,width,height,arrowDir){
+    // information of rectangle that popover should be anchored to
+    this.x = x || 0;
+    this.y = y || 32;
+    this.width = width || 320;
+    this.height = height || 480;
+    // The direction of the popover arrow
+    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
+};
+
+module.exports = CameraPopoverOptions;
+});
+
+// file: lib/common/plugin/CaptureAudioOptions.js
+define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
+/**
+ * Encapsulates all audio capture operation configuration options.
+ */
+var CaptureAudioOptions = function(){
+    // Upper limit of sound clips user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single sound clip in seconds.
+    this.duration = 0;
+    // The selected audio mode. Must match with one of the elements in supportedAudioModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureAudioOptions;
+});
+
+// file: lib/common/plugin/CaptureError.js
+define("cordova/plugin/CaptureError", function(require, exports, module) {
+/**
+ * The CaptureError interface encapsulates all errors in the Capture API.
+ */
+var CaptureError = function(c) {
+   this.code = c || null;
+};
+
+// Camera or microphone failed to capture image or sound.
+CaptureError.CAPTURE_INTERNAL_ERR = 0;
+// Camera application or audio capture application is currently serving other capture request.
+CaptureError.CAPTURE_APPLICATION_BUSY = 1;
+// Invalid use of the API (e.g. limit parameter has value less than one).
+CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
+// User exited camera application or audio capture application before capturing anything.
+CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
+// The requested capture operation is not supported.
+CaptureError.CAPTURE_NOT_SUPPORTED = 20;
+
+module.exports = CaptureError;
+});
+
+// file: lib/common/plugin/CaptureImageOptions.js
+define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
+/**
+ * Encapsulates all image capture operation configuration options.
+ */
+var CaptureImageOptions = function(){
+    // Upper limit of images user can take. Value must be equal or greater than 1.
+    this.limit = 1;
+    // The selected image mode. Must match with one of the elements in supportedImageModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureImageOptions;
+});
+
+// file: lib/common/plugin/CaptureVideoOptions.js
+define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
+/**
+ * Encapsulates all video capture operation configuration options.
+ */
+var CaptureVideoOptions = function(){
+    // Upper limit of videos user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single video clip in seconds.
+    this.duration = 0;
+    // The selected video mode. Must match with one of the elements in supportedVideoModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureVideoOptions;
+});
+
+// file: lib/common/plugin/CompassError.js
+define("cordova/plugin/CompassError", function(require, exports, module) {
+/**
+ *  CompassError.
+ *  An error code assigned by an implementation when an error has occured
+ * @constructor
+ */
+var CompassError = function(err) {
+    this.code = (err !== undefined ? err : null);
+};
+
+CompassError.COMPASS_INTERNAL_ERR = 0;
+CompassError.COMPASS_NOT_SUPPORTED = 20;
+
+module.exports = CompassError;
+});
+
+// file: lib/common/plugin/CompassHeading.js
+define("cordova/plugin/CompassHeading", function(require, exports, module) {
+var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
+  this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null);
+  this.trueHeading = (trueHeading !== undefined ? trueHeading : null);
+  this.headingAccuracy = (headingAccuracy !== undefined ? headingAccuracy : null);
+  this.timestamp = (timestamp !== undefined ? timestamp : new Date().getTime());
+};
+
+module.exports = CompassHeading;
+});
+
+// file: lib/common/plugin/ConfigurationData.js
+define("cordova/plugin/ConfigurationData", function(require, exports, module) {
+/**
+ * Encapsulates a set of parameters that the capture device supports.
+ */
+function ConfigurationData() {
+    // The ASCII-encoded string in lower case representing the media type.
+    this.type = null;
+    // The height attribute represents height of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0.
+    this.height = 0;
+    // The width attribute represents width of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0
+    this.width = 0;
+}
+
+module.exports = ConfigurationData;
+});
+
+// file: lib/common/plugin/Connection.js
+define("cordova/plugin/Connection", function(require, exports, module) {
+/**
+ * Network status
+ */
+module.exports = {
+        UNKNOWN: "unknown",
+        ETHERNET: "ethernet",
+        WIFI: "wifi",
+        CELL_2G: "2g",
+        CELL_3G: "3g",
+        CELL_4G: "4g",
+        NONE: "none"
+};
+});
+
+// file: lib/common/plugin/Contact.js
+define("cordova/plugin/Contact", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils');
+
+/**
+* Converts primitives into Complex Object
+* Currently only used for Date fields
+*/
+function convertIn(contact) {
+    var value = contact.birthday;
+    try {
+      contact.birthday = new Date(parseFloat(value));
+    } catch (exception){
+      console.log("Cordova Contact convertIn error: exception creating date.");
+    }
+    return contact;
+}
+
+/**
+* Converts Complex objects into primitives
+* Only conversion at present is for Dates.
+**/
+
+function convertOut(contact) {
+    var value = contact.birthday;
+    if (value !== null) {
+        // try to make it a Date object if it is not already
+        if (!utils.isDate(value)){
+            try {
+                value = new Date(value);
+            } catch(exception){
+                value = null;
+            }
+        }
+        if (utils.isDate(value)){
+            value = value.valueOf(); // convert to milliseconds
+        }
+        contact.birthday = value;
+    }
+    return contact;
+}
+
+/**
+* Contains information about a single contact.
+* @constructor
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {Array.<ContactField>} phoneNumbers array of phone numbers
+* @param {Array.<ContactField>} emails array of email addresses
+* @param {Array.<ContactAddress>} addresses array of addresses
+* @param {Array.<ContactField>} ims instant messaging user ids
+* @param {Array.<ContactOrganization>} organizations
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} note user notes about contact
+* @param {Array.<ContactField>} photos
+* @param {Array.<ContactField>} categories
+* @param {Array.<ContactField>} urls contact's web sites
+*/
+var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
+    ims, organizations, birthday, note, photos, categories, urls) {
+    this.id = id || null;
+    this.rawId = null;
+    this.displayName = displayName || null;
+    this.name = name || null; // ContactName
+    this.nickname = nickname || null;
+    this.phoneNumbers = phoneNumbers || null; // ContactField[]
+    this.emails = emails || null; // ContactField[]
+    this.addresses = addresses || null; // ContactAddress[]
+    this.ims = ims || null; // ContactField[]
+    this.organizations = organizations || null; // ContactOrganization[]
+    this.birthday = birthday || null;
+    this.note = note || null;
+    this.photos = photos || null; // ContactField[]
+    this.categories = categories || null; // ContactField[]
+    this.urls = urls || null; // ContactField[]
+};
+
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+    var fail = function(code) {
+        errorCB(new ContactError(code));
+    };
+    if (this.id === null) {
+        fail(ContactError.UNKNOWN_ERROR);
+    }
+    else {
+        exec(successCB, fail, "Contacts", "remove", [this.id]);
+    }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+    var clonedContact = utils.clone(this);
+    var i;
+    clonedContact.id = null;
+    clonedContact.rawId = null;
+    // Loop through and clear out any id's in phones, emails, etc.
+    if (clonedContact.phoneNumbers) {
+        for (i = 0; i < clonedContact.phoneNumbers.length; i++) {
+            clonedContact.phoneNumbers[i].id = null;
+        }
+    }
+    if (clonedContact.emails) {
+        for (i = 0; i < clonedContact.emails.length; i++) {
+            clonedContact.emails[i].id = null;
+        }
+    }
+    if (clonedContact.addresses) {
+        for (i = 0; i < clonedContact.addresses.length; i++) {
+            clonedContact.addresses[i].id = null;
+        }
+    }
+    if (clonedContact.ims) {
+        for (i = 0; i < clonedContact.ims.length; i++) {
+            clonedContact.ims[i].id = null;
+        }
+    }
+    if (clonedContact.organizations) {
+        for (i = 0; i < clonedContact.organizations.length; i++) {
+            clonedContact.organizations[i].id = null;
+        }
+    }
+    if (clonedContact.categories) {
+        for (i = 0; i < clonedContact.categories.length; i++) {
+            clonedContact.categories[i].id = null;
+        }
+    }
+    if (clonedContact.photos) {
+        for (i = 0; i < clonedContact.photos.length; i++) {
+            clonedContact.photos[i].id = null;
+        }
+    }
+    if (clonedContact.urls) {
+        for (i = 0; i < clonedContact.urls.length; i++) {
+            clonedContact.urls[i].id = null;
+        }
+    }
+    return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+  var fail = function(code) {
+      errorCB(new ContactError(code));
+  };
+    var success = function(result) {
+      if (result) {
+          if (typeof successCB === 'function') {
+              var fullContact = require('cordova/plugin/contacts').create(result);
+              successCB(convertIn(fullContact));
+          }
+      }
+      else {
+          // no Entry object returned
+          fail(ContactError.UNKNOWN_ERROR);
+      }
+  };
+    var dupContact = convertOut(utils.clone(this));
+    exec(success, fail, "Contacts", "save", [dupContact]);
+};
+
+
+module.exports = Contact;
+
+});
+
+// file: lib/common/plugin/ContactAddress.js
+define("cordova/plugin/ContactAddress", function(require, exports, module) {
+/**
+* Contact address.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code
+* @param formatted // NOTE: not a W3C standard
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+
+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.formatted = formatted || null;
+    this.streetAddress = streetAddress || null;
+    this.locality = locality || null;
+    this.region = region || null;
+    this.postalCode = postalCode || null;
+    this.country = country || null;
+};
+
+module.exports = ContactAddress;
+});
+
+// file: lib/common/plugin/ContactError.js
+define("cordova/plugin/ContactError", function(require, exports, module) {
+/**
+ *  ContactError.
+ *  An error code assigned by an implementation when an error has occured
+ * @constructor
+ */
+var ContactError = function(err) {
+    this.code = (typeof err != 'undefined' ? err : null);
+};
+
+/**
+ * Error codes
+ */
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.TIMEOUT_ERROR = 2;
+ContactError.PENDING_OPERATION_ERROR = 3;
+ContactError.IO_ERROR = 4;
+ContactError.NOT_SUPPORTED_ERROR = 5;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+module.exports = ContactError;
+});
+
+// file: lib/common/plugin/ContactField.js
+define("cordova/plugin/ContactField", function(require, exports, module) {
+/**
+* Generic contact field.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param type
+* @param value
+* @param pref
+*/
+var ContactField = function(type, value, pref) {
+    this.id = null;
+    this.type = (type && type.toString()) || null;
+    this.value = (value && value.toString()) || null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+};
+
+module.exports = ContactField;
+});
+
+// file: lib/common/plugin/ContactFindOptions.js
+define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
+/**
+ * ContactFindOptions.
+ * @constructor
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ */
+
+var ContactFindOptions = function(filter, multiple) {
+    this.filter = filter || '';
+    this.multiple = (typeof multiple != 'undefined' ? multiple : false);
+};
+
+module.exports = ContactFindOptions;
+});
+
+// file: lib/common/plugin/ContactName.js
+define("cordova/plugin/ContactName", function(require, exports, module) {
+/**
+* Contact name.
+* @constructor
+* @param formatted // NOTE: not part of W3C standard
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
+    this.formatted = formatted || null;
+    this.familyName = familyName || null;
+    this.givenName = givenName || null;
+    this.middleName = middle || null;
+    this.honorificPrefix = prefix || null;
+    this.honorificSuffix = suffix || null;
+};
+
+module.exports = ContactName;
+});
+
+// file: lib/common/plugin/ContactOrganization.js
+define("cordova/plugin/ContactOrganization", function(require, exports, module) {
+/**
+* Contact organization.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param name
+* @param dept
+* @param title
+* @param startDate
+* @param endDate
+* @param location
+* @param desc
+*/
+
+var ContactOrganization = function(pref, type, name, dept, title) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.name = name || null;
+    this.department = dept || null;
+    this.title = title || null;
+};
+
+module.exports = ContactOrganization;
+});
+
+// file: lib/common/plugin/Coordinates.js
+define("cordova/plugin/Coordinates", function(require, exports, module) {
+/**
+ * This class contains position information.
+ * @param {Object} lat
+ * @param {Object} lng
+ * @param {Object} alt
+ * @param {Object} acc
+ * @param {Object} head
+ * @param {Object} vel
+ * @param {Object} altacc
+ * @constructor
+ */
+var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
+    /**
+     * The latitude of the position.
+     */
+    this.latitude = lat;
+    /**
+     * The longitude of the position,
+     */
+    this.longitude = lng;
+    /**
+     * The accuracy of the position.
+     */
+    this.accuracy = acc;
+    /**
+     * The altitude of the position.
+     */
+    this.altitude = (alt !== undefined ? alt : null);
+    /**
+     * The direction the device is moving at the position.
+     */
+    this.heading = (head !== undefined ? head : null);
+    /**
+     * The velocity with which the device is moving at the position.
+     */
+    this.speed = (vel !== undefined ? vel : null);
+
+    if (this.speed === 0 || this.speed === null) {
+        this.heading = NaN;
+    }
+
+    /**
+     * The altitude accuracy of the position.
+     */
+    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
+};
+
+module.exports = Coordinates;
+
+});
+
+// file: lib/common/plugin/DirectoryEntry.js
+define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileError = require('cordova/plugin/FileError'),
+    DirectoryReader = require('cordova/plugin/DirectoryReader');
+
+/**
+ * An interface representing a directory on the file system.
+ *
+ * {boolean} isFile always false (readonly)
+ * {boolean} isDirectory always true (readonly)
+ * {DOMString} name of the directory, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the directory (readonly)
+ * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
+ */
+var DirectoryEntry = function(name, fullPath) {
+     DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]);
+};
+
+utils.extend(DirectoryEntry, Entry);
+
+/**
+ * Creates a new DirectoryReader to read entries from this directory
+ */
+DirectoryEntry.prototype.createReader = function() {
+    return new DirectoryReader(this.fullPath);
+};
+
+/**
+ * Creates or looks up a directory
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
+ * @param {Flags} options to create or excluively create the directory
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
+};
+
+/**
+ * Deletes a directory and all of it's contents
+ *
+ * @param {Function} successCallback is called with no parameters
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
+};
+
+/**
+ * Creates or looks up a file
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
+ * @param {Flags} options to create or excluively create the file
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var FileEntry = require('cordova/plugin/FileEntry');
+        var entry = new FileEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
+};
+
+module.exports = DirectoryEntry;
+
+});
+
+// file: lib/common/plugin/DirectoryReader.js
+define("cordova/plugin/DirectoryReader", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError') ;
+
+/**
+ * An interface that lists the files and directories in a directory.
+ */
+function DirectoryReader(path) {
+    this.path = path || null;
+}
+
+/**
+ * Returns a list of entries from a directory.
+ *
+ * @param {Function} successCallback is called with a list of entries
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var retVal = [];
+        for (var i=0; i<result.length; i++) {
+            var entry = null;
+            if (result[i].isDirectory) {
+                entry = new (require('cordova/plugin/DirectoryEntry'))();
+            }
+            else if (result[i].isFile) {
+                entry = new (require('cordova/plugin/FileEntry'))();
+            }
+            entry.isDirectory = result[i].isDirectory;
+            entry.isFile = result[i].isFile;
+            entry.name = result[i].name;
+            entry.fullPath = result[i].fullPath;
+            retVal.push(entry);
+        }
+        successCallback(retVal);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "readEntries", [this.path]);
+};
+
+module.exports = DirectoryReader;
+
+});
+
+// file: lib/common/plugin/Entry.js
+define("cordova/plugin/Entry", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    Metadata = require('cordova/plugin/Metadata');
+
+/**
+ * Represents a file or directory on the local file system.
+ *
+ * @param isFile
+ *            {boolean} true if Entry is a file (readonly)
+ * @param isDirectory
+ *            {boolean} true if Entry is a directory (readonly)
+ * @param name
+ *            {DOMString} name of the file or directory, excluding the path
+ *            leading to it (readonly)
+ * @param fullPath
+ *            {DOMString} the absolute full path to the file or directory
+ *            (readonly)
+ */
+function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
+    this.isFile = (typeof isFile != 'undefined'?isFile:false);
+    this.isDirectory = (typeof isDirectory != 'undefined'?isDirectory:false);
+    this.name = name || '';
+    this.fullPath = fullPath || '';
+    this.filesystem = fileSystem || null;
+}
+
+/**
+ * Look up the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ */
+Entry.prototype.getMetadata = function(successCallback, errorCallback) {
+  var success = typeof successCallback !== 'function' ? null : function(lastModified) {
+      var metadata = new Metadata(lastModified);
+      successCallback(metadata);
+  };
+  var fail = typeof errorCallback !== 'function' ? null : function(code) {
+      errorCallback(new FileError(code));
+  };
+
+  exec(success, fail, "File", "getMetadata", [this.fullPath]);
+};
+
+/**
+ * Set the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ * @param metadataObject
+ *            {Object} keys and values to set
+ */
+Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
+
+  exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
+};
+
+/**
+ * Move a file or directory to a new location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to move this entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new DirectoryEntry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+    // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Copy a directory to a different location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to copy the entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new Entry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+
+        // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        // success callback
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Return a URL that can be used to identify this entry.
+ */
+Entry.prototype.toURL = function() {
+    // fullPath attribute contains the full URL
+    return this.fullPath;
+};
+
+/**
+ * Returns a URI that can be used to identify this entry.
+ *
+ * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
+ * @return uri
+ */
+Entry.prototype.toURI = function(mimeType) {
+    console.log("DEPRECATED: Update your code to use 'toURL'");
+    // fullPath attribute contains the full URI
+    return this.toURL();
+};
+
+/**
+ * Remove a file or directory. It is an error to attempt to delete a
+ * directory that is not empty. It is an error to attempt to delete a
+ * root directory of a file system.
+ *
+ * @param successCallback {Function} called with no parameters
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.remove = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "remove", [this.fullPath]);
+};
+
+/**
+ * Look up the parent DirectoryEntry of this entry.
+ *
+ * @param successCallback {Function} called with the parent DirectoryEntry object
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.getParent = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getParent", [this.fullPath]);
+};
+
+module.exports = Entry;
+});
+
+// file: lib/common/plugin/File.js
+define("cordova/plugin/File", function(require, exports, module) {
+/**
+ * Constructor.
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+
+var File = function(name, fullPath, type, lastModifiedDate, size){
+    this.name = name || '';
+    this.fullPath = fullPath || null;
+    this.type = type || null;
+    this.lastModifiedDate = lastModifiedDate || null;
+    this.size = size || 0;
+};
+
+module.exports = File;
+});
+
+// file: lib/common/plugin/FileEntry.js
+define("cordova/plugin/FileEntry", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileWriter = require('cordova/plugin/FileWriter'),
+    File = require('cordova/plugin/File'),
+    FileError = require('cordova/plugin/FileError');
+
+/**
+ * An interface representing a file on the file system.
+ *
+ * {boolean} isFile always true (readonly)
+ * {boolean} isDirectory always false (readonly)
+ * {DOMString} name of the file, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the file (readonly)
+ * {FileSystem} filesystem on which the file resides (readonly)
+ */
+var FileEntry = function(name, fullPath) {
+     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
+};
+
+utils.extend(FileEntry, Entry);
+
+/**
+ * Creates a new FileWriter associated with the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new FileWriter
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
+    this.file(function(filePointer) {
+        var writer = new FileWriter(filePointer);
+
+        if (writer.fileName === null || writer.fileName === "") {
+            if (typeof errorCallback === "function") {
+                errorCallback(new FileError(FileError.INVALID_STATE_ERR));
+            }
+        } else {
+            if (typeof successCallback === "function") {
+                successCallback(writer);
+            }
+        }
+    }, errorCallback);
+};
+
+/**
+ * Returns a File that represents the current state of the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new File object
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.file = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(f) {
+        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
+        successCallback(file);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
+};
+
+
+module.exports = FileEntry;
+});
+
+// file: lib/common/plugin/FileError.js
+define("cordova/plugin/FileError", function(require, exports, module) {
+/**
+ * FileError
+ */
+function FileError(error) {
+  this.code = error || null;
+}
+
+// File error codes
+// Found in DOMException
+FileError.NOT_FOUND_ERR = 1;
+FileError.SECURITY_ERR = 2;
+FileError.ABORT_ERR = 3;
+
+// Added by File API specification
+FileError.NOT_READABLE_ERR = 4;
+FileError.ENCODING_ERR = 5;
+FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
+FileError.INVALID_STATE_ERR = 7;
+FileError.SYNTAX_ERR = 8;
+FileError.INVALID_MODIFICATION_ERR = 9;
+FileError.QUOTA_EXCEEDED_ERR = 10;
+FileError.TYPE_MISMATCH_ERR = 11;
+FileError.PATH_EXISTS_ERR = 12;
+
+module.exports = FileError;
+});
+
+// file: lib/common/plugin/FileReader.js
+define("cordova/plugin/FileReader", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class reads the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To read from the SD card, the file name is "sdcard/my_file.txt"
+ * @constructor
+ */
+var FileReader = function() {
+    this.fileName = "";
+
+    this.readyState = 0; // FileReader.EMPTY
+
+    // File data
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onloadstart = null;    // When the read starts.
+    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total)
+    this.onload = null;         // When the read has successfully completed.
+    this.onerror = null;        // When the read has failed (see errors).
+    this.onloadend = null;      // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.
+};
+
+// States
+FileReader.EMPTY = 0;
+FileReader.LOADING = 1;
+FileReader.DONE = 2;
+
+/**
+ * Abort reading file.
+ */
+FileReader.prototype.abort = function() {
+    this.result = null;
+
+    if (this.readyState == FileReader.DONE || this.readyState == FileReader.EMPTY) {
+      return;
+    }
+
+    this.readyState = FileReader.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === 'function') {
+        this.onabort(new ProgressEvent('abort', {target:this}));
+    }
+    // If load end callback
+    if (typeof this.onloadend === 'function') {
+        this.onloadend(new ProgressEvent('loadend', {target:this}));
+    }
+};
+
+/**
+ * Read text file.
+ *
+ * @param file          {File} File object containing file properties
+ * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)
+ */
+FileReader.prototype.readAsText = function(file, encoding) {
+    // Figure out pathing
+    this.fileName = '';
+    if (typeof file.fullPath === 'undefined') {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    // Default encoding is UTF-8
+    var enc = encoding ? encoding : "UTF-8";
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // null result
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsText", [this.fileName, enc]);
+};
+
+
+/**
+ * Read file and return data as a base64 encoded data url.
+ * A data url is of the form:
+ *      data:[<mediatype>][;base64],<data>
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsDataURL = function(file) {
+    this.fileName = "";
+    if (typeof file.fullPath === "undefined") {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsDataURL", [this.fileName]);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsBinaryString = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('method "readAsBinaryString" is not supported at this time.');
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsArrayBuffer = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('This method is not supported at this time.');
+};
+
+module.exports = FileReader;
+});
+
+// file: lib/common/plugin/FileSystem.js
+define("cordova/plugin/FileSystem", function(require, exports, module) {
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+
+/**
+ * An interface representing a file system
+ *
+ * @constructor
+ * {DOMString} name the unique name of the file system (readonly)
+ * {DirectoryEntry} root directory of the file system (readonly)
+ */
+var FileSystem = function(name, root) {
+    this.name = name || null;
+    if (root) {
+        this.root = new DirectoryEntry(root.name, root.fullPath);
+    }
+};
+
+module.exports = FileSystem;
+
+});
+
+// file: lib/common/plugin/FileTransfer.js
+define("cordova/plugin/FileTransfer", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileTransferError = require('cordova/plugin/FileTransferError');
+
+/**
+ * FileTransfer uploads a file to a remote server.
+ * @constructor
+ */
+var FileTransfer = function() {};
+
+/**
+* Given an absolute file path, uploads a file on the device to a remote server
+* using a multipart HTTP request.
+* @param filePath {String}           Full path of the file on the device
+* @param server {String}             URL of the server to receive the file
+* @param successCallback (Function}  Callback to be invoked when upload has completed
+* @param errorCallback {Function}    Callback to be invoked upon error
+* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
+* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+*/
+FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
+    // sanity parameter checking
+    if (!filePath || !server) throw new Error("FileTransfer.upload requires filePath and server URL parameters at the minimum.");
+    // check for options
+    var fileKey = null;
+    var fileName = null;
+    var mimeType = null;
+    var params = null;
+    var chunkedMode = true;
+    if (options) {
+        fileKey = options.fileKey;
+        fileName = options.fileName;
+        mimeType = options.mimeType;
+        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
+            chunkedMode = options.chunkedMode;
+        }
+        if (options.params) {
+            params = options.params;
+        }
+        else {
+            params = {};
+        }
+    }
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]);
+};
+
+/**
+ * Downloads a file form a given URL and saves it to the specified directory.
+ * @param source {String}          URL of the server to receive the file
+ * @param target {String}         Full path of the file on the device
+ * @param successCallback (Function}  Callback to be invoked when upload has completed
+ * @param errorCallback {Function}    Callback to be invoked upon error
+ */
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) {
+    // sanity parameter checking
+    if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum.");
+    var win = function(result) {
+        var entry = null;
+        if (result.isDirectory) {
+            entry = new (require('cordova/plugin/DirectoryEntry'))();
+        }
+        else if (result.isFile) {
+            entry = new (require('cordova/plugin/FileEntry'))();
+        }
+        entry.isDirectory = result.isDirectory;
+        entry.isFile = result.isFile;
+        entry.name = result.name;
+        entry.fullPath = result.fullPath;
+        successCallback(entry);
+    };
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    exec(win, errorCallback, 'FileTransfer', 'download', [source, target]);
+};
+
+module.exports = FileTransfer;
+
+});
+
+// file: lib/common/plugin/FileTransferError.js
+define("cordova/plugin/FileTransferError", function(require, exports, module) {
+/**
+ * FileTransferError
+ * @constructor
+ */
+var FileTransferError = function(code, source, target, status) {
+    this.code = code || null;
+    this.source = source || null;
+    this.target = target || null;
+    this.http_status = status || null;
+};
+
+FileTransferError.FILE_NOT_FOUND_ERR = 1;
+FileTransferError.INVALID_URL_ERR = 2;
+FileTransferError.CONNECTION_ERR = 3;
+
+module.exports = FileTransferError;
+
+});
+
+// file: lib/common/plugin/FileUploadOptions.js
+define("cordova/plugin/FileUploadOptions", function(require, exports, module) {
+/**
+ * Options to customize the HTTP request used to upload files.
+ * @constructor
+ * @param fileKey {String}   Name of file request parameter.
+ * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.
+ * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.
+ * @param params {Object}    Object with key: value params to send to the server.
+ */
+var FileUploadOptions = function(fileKey, fileName, mimeType, params) {
+    this.fileKey = fileKey || null;
+    this.fileName = fileName || null;
+    this.mimeType = mimeType || null;
+    this.params = params || null;
+};
+
+module.exports = FileUploadOptions;
+});
+
+// file: lib/common/plugin/FileUploadResult.js
+define("cordova/plugin/FileUploadResult", function(require, exports, module) {
+/**
+ * FileUploadResult
+ * @constructor
+ */
+var FileUploadResult = function() {
+    this.bytesSent = 0;
+    this.responseCode = null;
+    this.response = null;
+};
+
+module.exports = FileUploadResult;
+});
+
+// file: lib/common/plugin/FileWriter.js
+define("cordova/plugin/FileWriter", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class writes to the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To write to the SD card, the file name is "sdcard/my_file.txt"
+ *
+ * @constructor
+ * @param file {File} File object containing file properties
+ * @param append if true write to the end of the file, otherwise overwrite the file
+ */
+var FileWriter = function(file) {
+    this.fileName = "";
+    this.length = 0;
+    if (file) {
+        this.fileName = file.fullPath || file;
+        this.length = file.size || 0;
+    }
+    // default is to write at the beginning of the file
+    this.position = 0;
+
+    this.readyState = 0; // EMPTY
+
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onwritestart = null;   // When writing starts
+    this.onprogress = null;     // While writing the file, and reporting partial file data
+    this.onwrite = null;        // When the write has successfully completed.
+    this.onwriteend = null;     // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.
+    this.onerror = null;        // When the write has failed (see errors).
+};
+
+// States
+FileWriter.INIT = 0;
+FileWriter.WRITING = 1;
+FileWriter.DONE = 2;
+
+/**
+ * Abort writing file.
+ */
+FileWriter.prototype.abort = function() {
+    // check for invalid state
+    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // set error
+    this.error = new FileError(FileError.ABORT_ERR);
+
+    this.readyState = FileWriter.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === "function") {
+        this.onabort(new ProgressEvent("abort", {"target":this}));
+    }
+
+    // If write end callback
+    if (typeof this.onwriteend === "function") {
+        this.onwriteend(new ProgressEvent("writeend", {"target":this}));
+    }
+};
+
+/**
+ * Writes data to the file
+ *
+ * @param text to be written
+ */
+FileWriter.prototype.write = function(text) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":me}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // position always increases by bytes written because file would be extended
+            me.position += r;
+            // The length of the file is now where we are done writing.
+
+            me.length = me.position;
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "write", [this.fileName, text, this.position]);
+};
+
+/**
+ * Moves the file pointer to the location specified.
+ *
+ * If the offset is a negative number the position of the file
+ * pointer is rewound.  If the offset is greater than the file
+ * size the position is set to the end of the file.
+ *
+ * @param offset is the location to move the file pointer to.
+ */
+FileWriter.prototype.seek = function(offset) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    if (!offset && offset !== 0) {
+        return;
+    }
+
+    // See back from end of file.
+    if (offset < 0) {
+        this.position = Math.max(offset + this.length, 0);
+    }
+    // Offset is bigger then file size so set position
+    // to the end of the file.
+    else if (offset > this.length) {
+        this.position = this.length;
+    }
+    // Offset is between 0 and file size so set the position
+    // to start writing.
+    else {
+        this.position = offset;
+    }
+};
+
+/**
+ * Truncates the file to the size specified.
+ *
+ * @param size to chop the file at.
+ */
+FileWriter.prototype.truncate = function(size) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":this}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Update the length of the file
+            me.length = r;
+            me.position = Math.min(me.position, r);
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "truncate", [this.fileName, size]);
+};
+
+module.exports = FileWriter;
+
+});
+
+// file: lib/common/plugin/Flags.js
+define("cordova/plugin/Flags", function(require, exports, module) {
+/**
+ * Supplies arguments to methods that lookup or create files and directories.
+ *
+ * @param create
+ *            {boolean} file or directory if it doesn't exist
+ * @param exclusive
+ *            {boolean} used with create; if true the command will fail if
+ *            target path exists
+ */
+function Flags(create, exclusive) {
+    this.create = create || false;
+    this.exclusive = exclusive || false;
+}
+
+module.exports = Flags;
+});
+
+// file: lib/common/plugin/LocalFileSystem.js
+define("cordova/plugin/LocalFileSystem", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+/**
+ * Represents a local file system.
+ */
+var LocalFileSystem = function() {
+
+};
+
+LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence
+LocalFileSystem.PERSISTENT = 1; //persistent
+
+module.exports = LocalFileSystem;
+});
+
+// file: lib/common/plugin/Media.js
+define("cordova/plugin/Media", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+var mediaObjects = {};
+
+/**
+ * This class provides access to the device media, interfaces to both sound and video
+ *
+ * @constructor
+ * @param src                   The file name or url to play
+ * @param successCallback       The callback to be called when the file is done playing or recording.
+ *                                  successCallback()
+ * @param errorCallback         The callback to be called if there is an error.
+ *                                  errorCallback(int errorCode) - OPTIONAL
+ * @param statusCallback        The callback to be called when media status has changed.
+ *                                  statusCallback(int statusCode) - OPTIONAL
+ */
+var Media = function(src, successCallback, errorCallback, statusCallback) {
+
+    // successCallback optional
+    if (successCallback && (typeof successCallback !== "function")) {
+        console.log("Media Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Media Error: errorCallback is not a function");
+        return;
+    }
+
+    // statusCallback optional
+    if (statusCallback && (typeof statusCallback !== "function")) {
+        console.log("Media Error: statusCallback is not a function");
+        return;
+    }
+
+    this.id = utils.createUUID();
+    mediaObjects[this.id] = this;
+    this.src = src;
+    this.successCallback = successCallback;
+    this.errorCallback = errorCallback;
+    this.statusCallback = statusCallback;
+    this._duration = -1;
+    this._position = -1;
+    exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
+};
+
+// Media messages
+Media.MEDIA_STATE = 1;
+Media.MEDIA_DURATION = 2;
+Media.MEDIA_POSITION = 3;
+Media.MEDIA_ERROR = 9;
+
+// Media states
+Media.MEDIA_NONE = 0;
+Media.MEDIA_STARTING = 1;
+Media.MEDIA_RUNNING = 2;
+Media.MEDIA_PAUSED = 3;
+Media.MEDIA_STOPPED = 4;
+Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
+
+// "static" function to return existing objs.
+Media.get = function(id) {
+    return mediaObjects[id];
+};
+
+/**
+ * Start or resume playing audio file.
+ */
+Media.prototype.play = function(options) {
+    exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
+};
+
+/**
+ * Stop playing audio file.
+ */
+Media.prototype.stop = function() {
+    var me = this;
+    exec(function() {
+        me._position = 0;
+        me.successCallback();
+    }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
+};
+
+/**
+ * Seek or jump to a new time in the track..
+ */
+Media.prototype.seekTo = function(milliseconds) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+    }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
+};
+
+/**
+ * Pause playing audio file.
+ */
+Media.prototype.pause = function() {
+    exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
+};
+
+/**
+ * Get duration of an audio file.
+ * The duration is only set for audio that is playing, paused or stopped.
+ *
+ * @return      duration or -1 if not known.
+ */
+Media.prototype.getDuration = function() {
+    return this._duration;
+};
+
+/**
+ * Get position of audio.
+ */
+Media.prototype.getCurrentPosition = function(success, fail) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+        success(p);
+    }, fail, "Media", "getCurrentPositionAudio", [this.id]);
+};
+
+/**
+ * Start recording audio file.
+ */
+Media.prototype.startRecord = function() {
+    exec(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
+};
+
+/**
+ * Stop recording audio file.
+ */
+Media.prototype.stopRecord = function() {
+    exec(this.successCallback, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
+};
+
+/**
+ * Release the resources.
+ */
+Media.prototype.release = function() {
+    exec(null, this.errorCallback, "Media", "release", [this.id]);
+};
+
+/**
+ * Adjust the volume.
+ */
+Media.prototype.setVolume = function(volume) {
+    exec(null, null, "Media", "setVolume", [this.id, volume]);
+};
+
+/**
+ * Audio has status update.
+ * PRIVATE
+ *
+ * @param id            The media object id (string)
+ * @param status        The status code (int)
+ * @param msg           The status message (string)
+ */
+Media.onStatus = function(id, msg, value) {
+    var media = mediaObjects[id];
+    // If state update
+    if (msg === Media.MEDIA_STATE) {
+        if (value === Media.MEDIA_STOPPED) {
+            if (media.successCallback) {
+                media.successCallback();
+            }
+        }
+        if (media.statusCallback) {
+            media.statusCallback(value);
+        }
+    }
+    else if (msg === Media.MEDIA_DURATION) {
+        media._duration = value;
+    }
+    else if (msg === Media.MEDIA_ERROR) {
+        if (media.errorCallback) {
+            // value should be a MediaError object when msg == MEDIA_ERROR
+            media.errorCallback(value);
+        }
+    }
+    else if (msg === Media.MEDIA_POSITION) {
+        media._position = value;
+    }
+};
+
+module.exports = Media;
+});
+
+// file: lib/common/plugin/MediaError.js
+define("cordova/plugin/MediaError", function(require, exports, module) {
+/**
+ * This class contains information about any Media errors.
+ * @constructor
+ */
+var MediaError = function(code, msg) {
+    this.code = (code !== undefined ? code : null);
+    this.message = msg || "";
+};
+
+MediaError.MEDIA_ERR_NONE_ACTIVE    = 0;
+MediaError.MEDIA_ERR_ABORTED        = 1;
+MediaError.MEDIA_ERR_NETWORK        = 2;
+MediaError.MEDIA_ERR_DECODE         = 3;
+MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
+
+module.exports = MediaError;
+});
+
+// file: lib/common/plugin/MediaFile.js
+define("cordova/plugin/MediaFile", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    File = require('cordova/plugin/File'),
+    CaptureError = require('cordova/plugin/CaptureError');
+/**
+ * Represents a single file.
+ *
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+var MediaFile = function(name, fullPath, type, lastModifiedDate, size){
+    MediaFile.__super__.constructor.apply(this, arguments);
+};
+
+utils.extend(MediaFile, File);
+
+/**
+ * Request capture format data for a specific file and type
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ */
+MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
+    if (typeof this.fullPath === "undefined" || this.fullPath === null) {
+        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));
+    } else {
+        exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);
+    }
+};
+
+// TODO: can we axe this?
+/**
+ * Casts a PluginResult message property  (array of objects) to an array of MediaFile objects
+ * (used in Objective-C and Android)
+ *
+ * @param {PluginResult} pluginResult
+ */
+MediaFile.cast = function(pluginResult) {
+    var mediaFiles = [];
+    for (var i=0; i<pluginResult.message.length; i++) {
+        var mediaFile = new MediaFile();
+        mediaFile.name = pluginResult.message[i].name;
+        mediaFile.fullPath = pluginResult.message[i].fullPath;
+        mediaFile.type = pluginResult.message[i].type;
+        mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate;
+        mediaFile.size = pluginResult.message[i].size;
+        mediaFiles.push(mediaFile);
+    }
+    pluginResult.message = mediaFiles;
+    return pluginResult;
+};
+
+module.exports = MediaFile;
+
+});
+
+// file: lib/common/plugin/MediaFileData.js
+define("cordova/plugin/MediaFileData", function(require, exports, module) {
+/**
+ * MediaFileData encapsulates format information of a media file.
+ *
+ * @param {DOMString} codecs
+ * @param {long} bitrate
+ * @param {long} height
+ * @param {long} width
+ * @param {float} duration
+ */
+var MediaFileData = function(codecs, bitrate, height, width, duration){
+    this.codecs = codecs || null;
+    this.bitrate = bitrate || 0;
+    this.height = height || 0;
+    this.width = width || 0;
+    this.duration = duration || 0;
+};
+
+module.exports = MediaFileData;
+});
+
+// file: lib/common/plugin/Metadata.js
+define("cordova/plugin/Metadata", function(require, exports, module) {
+/**
+ * Information about the state of the file or directory
+ *
+ * {Date} modificationTime (readonly)
+ */
+var Metadata = function(time) {
+    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);
+};
+
+module.exports = Metadata;
+});
+
+// file: lib/common/plugin/Position.js
+define("cordova/plugin/Position", function(require, exports, module) {
+var Coordinates = require('cordova/plugin/Coordinates');
+
+var Position = function(coords, timestamp) {
+    if (coords) {
+        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);
+    } else {
+        this.coords = new Coordinates();
+    }
+    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();
+};
+
+module.exports = Position;
+
+});
+
+// file: lib/common/plugin/PositionError.js
+define("cordova/plugin/PositionError", function(require, exports, module) {
+/**
+ * Position error object
+ *
+ * @constructor
+ * @param code
+ * @param message
+ */
+var PositionError = function(code, message) {
+    this.code = code || null;
+    this.message = message || '';
+};
+
+PositionError.PERMISSION_DENIED = 1;
+PositionError.POSITION_UNAVAILABLE = 2;
+PositionError.TIMEOUT = 3;
+
+module.exports = PositionError;
+});
+
+// file: lib/common/plugin/ProgressEvent.js
+define("cordova/plugin/ProgressEvent", function(require, exports, module) {
+// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill
+// Feature test: See if we can instantiate a native ProgressEvent;
+// if so, use that approach,
+// otherwise fill-in with our own implementation.
+//
+// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.
+var ProgressEvent = (function() {
+    /*
+    var createEvent = function(data) {
+        var event = document.createEvent('Events');
+        event.initEvent('ProgressEvent', false, false);
+        if (data) {
+            for (var i in data) {
+                if (data.hasOwnProperty(i)) {
+                    event[i] = data[i];
+                }
+            }
+            if (data.target) {
+                // TODO: cannot call <some_custom_object>.dispatchEvent
+                // need to first figure out how to implement EventTarget
+            }
+        }
+        return event;
+    };
+    try {
+        var ev = createEvent({type:"abort",target:document});
+        return function ProgressEvent(type, data) {
+            data.type = type;
+            return createEvent(data);
+        };
+    } catch(e){
+    */
+        return function ProgressEvent(type, dict) {
+            this.type = type;
+            this.bubbles = false;
+            this.cancelBubble = false;
+            this.cancelable = false;
+            this.lengthComputable = false;
+            this.loaded = dict && dict.loaded ? dict.loaded : 0;
+            this.total = dict && dict.total ? dict.total : 0;
+            this.target = dict && dict.target ? dict.target : null;
+        };
+    //}
+})();
+
+module.exports = ProgressEvent;
+});
+
+// file: lib/common/plugin/accelerometer.js
+define("cordova/plugin/accelerometer", function(require, exports, module) {
+/**
+ * This class provides access to device accelerometer data.
+ * @constructor
+ */
+var utils = require("cordova/utils"),
+    exec = require("cordova/exec"),
+    Acceleration = require('cordova/plugin/Acceleration');
+
+// Is the accel sensor running?
+var running = false;
+
+// Keeps reference to watchAcceleration calls.
+var timers = {};
+
+// Array of listeners; used to keep track of when we should call start and stop.
+var listeners = [];
+
+// Last returned acceleration object from native
+var accel = null;
+
+// Tells native to start.
+function start() {
+    exec(function(a) {
+        var tempListeners = listeners.slice(0);
+        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].win(accel);
+        }
+    }, function(e) {
+        var tempListeners = listeners.slice(0);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].fail(e);
+        }
+    }, "Accelerometer", "start", []);
+    running = true;
+}
+
+// Tells native to stop.
+function stop() {
+    exec(null, null, "Accelerometer", "stop", []);
+    running = false;
+}
+
+// Adds a callback pair to the listeners array
+function createCallbackPair(win, fail) {
+    return {win:win, fail:fail};
+}
+
+// Removes a win/fail listener pair from the listeners array
+function removeListeners(l) {
+    var idx = listeners.indexOf(l);
+    if (idx > -1) {
+        listeners.splice(idx, 1);
+        if (listeners.length === 0) {
+            stop();
+        }
+    }
+}
+
+var accelerometer = {
+    /**
+     * Asynchronously aquires the current acceleration.
+     *
+     * @param {Function} successCallback    The function to call when the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     */
+    getCurrentAcceleration: function(successCallback, errorCallback, options) {
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "getCurrentAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        var p;
+        var win = function(a) {
+            removeListeners(p);
+            successCallback(a);
+        };
+        var fail = function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        };
+
+        p = createCallbackPair(win, fail);
+        listeners.push(p);
+
+        if (!running) {
+            start();
+        }
+    },
+
+    /**
+     * Asynchronously aquires the acceleration repeatedly at a given interval.
+     *
+     * @param {Function} successCallback    The function to call each time the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchAcceleration: function(successCallback, errorCallback, options) {
+        // Default interval (10 sec)
+        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;
+
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "watchAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        // Keep reference to watch id, and report accel readings as often as defined in frequency
+        var id = utils.createUUID();
+
+        var p = createCallbackPair(function(){}, function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        });
+        listeners.push(p);
+
+        timers[id] = {
+            timer:window.setInterval(function() {
+                if (accel) {
+                    successCallback(accel);
+                }
+            }, frequency),
+            listeners:p
+        };
+
+        if (running) {
+            // If we're already running then immediately invoke the success callback
+            // but only if we have retreived a value, sample code does not check for null ...
+            if(accel) {
+                successCallback(accel);
+            }
+        } else {
+            start();
+        }
+
+        return id;
+    },
+
+    /**
+     * Clears the specified accelerometer watch.
+     *
+     * @param {String} id       The id of the watch returned from #watchAcceleration.
+     */
+    clearWatch: function(id) {
+        // Stop javascript timer & remove from timer list
+        if (id && timers[id]) {
+            window.clearInterval(timers[id].timer);
+            removeListeners(timers[id].listeners);
+            delete timers[id];
+        }
+    }
+};
+
+module.exports = accelerometer;
+
+});
+
+// file: lib/common/plugin/battery.js
+define("cordova/plugin/battery", function(require, exports, module) {
+/**
+ * This class contains information about the current battery status.
+ * @constructor
+ */
+var cordova = require('cordova'),
+    exec = require('cordova/exec');
+
+function handlers() {
+  return battery.channels.batterystatus.numHandlers +
+         battery.channels.batterylow.numHandlers +
+         battery.channels.batterycritical.numHandlers;
+}
+
+var Battery = function() {
+    this._level = null;
+    this._isPlugged = null;
+    // Create new event handlers on the window (returns a channel instance)
+    var subscriptionEvents = {
+      onSubscribe:this.onSubscribe,
+      onUnsubscribe:this.onUnsubscribe
+    };
+    this.channels = {
+      batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents),
+      batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents),
+      batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents)
+    };
+};
+/**
+ * Event handlers for when callbacks get registered for the battery.
+ * Keep track of how many handlers we have so we can start and stop the native battery listener
+ * appropriately (and hopefully save on battery life!).
+ */
+Battery.prototype.onSubscribe = function() {
+  var me = battery;
+  // If we just registered the first handler, make sure native listener is started.
+  if (handlers() === 1) {
+    exec(me._status, me._error, "Battery", "start", []);
+  }
+};
+
+Battery.prototype.onUnsubscribe = function() {
+  var me = battery;
+
+  // If we just unregistered the last handler, make sure native listener is stopped.
+  if (handlers() === 0) {
+      exec(null, null, "Battery", "stop", []);
+  }
+};
+
+/**
+ * Callback for battery status
+ *
+ * @param {Object} info            keys: level, isPlugged
+ */
+Battery.prototype._status = function(info) {
+    if (info) {
+        var me = battery;
+    var level = info.level;
+        if (me._level !== level || me._isPlugged !== info.isPlugged) {
+            // Fire batterystatus event
+            cordova.fireWindowEvent("batterystatus", info);
+
+            // Fire low battery event
+            if (level === 20 || level === 5) {
+                if (level === 20) {
+                    cordova.fireWindowEvent("batterylow", info);
+                }
+                else {
+                    cordova.fireWindowEvent("batterycritical", info);
+                }
+            }
+        }
+        me._level = level;
+        me._isPlugged = info.isPlugged;
+    }
+};
+
+/**
+ * Error callback for battery start
+ */
+Battery.prototype._error = function(e) {
+    console.log("Error initializing Battery: " + e);
+};
+
+var battery = new Battery();
+
+module.exports = battery;
+});
+
+// file: lib/common/plugin/capture.js
+define("cordova/plugin/capture", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    MediaFile = require('cordova/plugin/MediaFile');
+
+/**
+ * Launches a capture of different types.
+ *
+ * @param (DOMString} type
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+function _capture(type, successCallback, errorCallback, options) {
+    var win = function(pluginResult) {
+        var mediaFiles = [];
+        var i;
+        for (i = 0; i < pluginResult.length; i++) {
+            var mediaFile = new MediaFile();
+            mediaFile.name = pluginResult[i].name;
+            mediaFile.fullPath = pluginResult[i].fullPath;
+            mediaFile.type = pluginResult[i].type;
+            mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;
+            mediaFile.size = pluginResult[i].size;
+            mediaFiles.push(mediaFile);
+        }
+        successCallback(mediaFiles);
+    };
+    exec(win, errorCallback, "Capture", type, [options]);
+}
+/**
+ * The Capture interface exposes an interface to the camera and microphone of the hosting device.
+ */
+function Capture() {
+    this.supportedAudioModes = [];
+    this.supportedImageModes = [];
+    this.supportedVideoModes = [];
+}
+
+/**
+ * Launch audio recorder application for recording audio clip(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureAudioOptions} options
+ */
+Capture.prototype.captureAudio = function(successCallback, errorCallback, options){
+    _capture("captureAudio", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch camera application for taking image(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureImageOptions} options
+ */
+Capture.prototype.captureImage = function(successCallback, errorCallback, options){
+    _capture("captureImage", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch device camera application for recording video(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+Capture.prototype.captureVideo = function(successCallback, errorCallback, options){
+    _capture("captureVideo", successCallback, errorCallback, options);
+};
+
+
+module.exports = new Capture();
+
+});
+
+// file: lib/common/plugin/compass.js
+define("cordova/plugin/compass", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    utils = require('cordova/utils'),
+    CompassHeading = require('cordova/plugin/CompassHeading'),
+    CompassError = require('cordova/plugin/CompassError'),
+    timers = {},
+    compass = {
+        /**
+         * Asynchronously acquires the current heading.
+         * @param {Function} successCallback The function to call when the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {CompassOptions} options The options for getting the heading data (not used).
+         */
+        getCurrentHeading:function(successCallback, errorCallback, options) {
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var win = function(result) {
+                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);
+                successCallback(ch);
+            };
+            var fail = function(code) {
+                var ce = new CompassError(code);
+                errorCallback(ce);
+            };
+
+            // Get heading
+            exec(win, fail, "Compass", "getHeading", [options]);
+        },
+
+        /**
+         * Asynchronously acquires the heading repeatedly at a given interval.
+         * @param {Function} successCallback The function to call each time the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {HeadingOptions} options The options for getting the heading data
+         * such as timeout and the frequency of the watch. For iOS, filter parameter
+         * specifies to watch via a distance filter rather than time.
+         */
+        watchHeading:function(successCallback, errorCallback, options) {
+            // Default interval (100 msec)
+            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;
+            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;
+
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var id = utils.createUUID();
+            if (filter > 0) {
+                // is an iOS request for watch by filter, no timer needed
+                timers[id] = "iOS";
+                compass.getCurrentHeading(successCallback, errorCallback, options);
+            } else {
+                // Start watch timer to get headings
+                timers[id] = window.setInterval(function() {
+                    compass.getCurrentHeading(successCallback, errorCallback);
+                }, frequency);
+            }
+
+            return id;
+        },
+
+        /**
+         * Clears the specified heading watch.
+         * @param {String} watchId The ID of the watch returned from #watchHeading.
+         */
+        clearWatch:function(id) {
+            // Stop javascript timer & remove from timer list
+            if (id && timers[id]) {
+                if (timers[id] != "iOS") {
+                      clearInterval(timers[id]);
+                  } else {
+                    // is iOS watch by filter so call into device to stop
+                    exec(null, null, "Compass", "stopHeading", []);
+                }
+                delete timers[id];
+            }
+        }
+    };
+
+module.exports = compass;
+});
+
+// file: lib/common/plugin/console-via-logger.js
+define("cordova/plugin/console-via-logger", function(require, exports, module) {
+//------------------------------------------------------------------------------
+
+var logger = require("cordova/plugin/logger");
+var utils  = require("cordova/utils");
+
+//------------------------------------------------------------------------------
+// object that we're exporting
+//------------------------------------------------------------------------------
+var console = module.exports;
+
+//------------------------------------------------------------------------------
+// copy of the original console object
+//------------------------------------------------------------------------------
+var WinConsole = window.console;
+
+//------------------------------------------------------------------------------
+// whether to use the logger
+//------------------------------------------------------------------------------
+var UseLogger = false;
+
+//------------------------------------------------------------------------------
+// Timers
+//------------------------------------------------------------------------------
+var Timers = {};
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+function noop() {}
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+console.useLogger = function (value) {
+    if (arguments.length) UseLogger = !!value;
+
+    if (UseLogger) {
+        if (logger.useConsole()) {
+            throw new Error("console and logger are too intertwingly");
+        }
+    }
+
+    return UseLogger;
+};
+
+//------------------------------------------------------------------------------
+console.log = function() {
+    if (logger.useConsole()) return;
+    logger.log.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.error = function() {
+    if (logger.useConsole()) return;
+    logger.error.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.warn = function() {
+    if (logger.useConsole()) return;
+    logger.warn.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.info = function() {
+    if (logger.useConsole()) return;
+    logger.info.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.debug = function() {
+    if (logger.useConsole()) return;
+    logger.debug.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.assert = function(expression) {
+    if (expression) return;
+
+    var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));
+    console.log("ASSERT: " + message);
+};
+
+//------------------------------------------------------------------------------
+console.clear = function() {};
+
+//------------------------------------------------------------------------------
+console.dir = function(object) {
+    console.log("%o", object);
+};
+
+//------------------------------------------------------------------------------
+console.dirxml = function(node) {
+    console.log(node.innerHTML);
+};
+
+//------------------------------------------------------------------------------
+console.trace = noop;
+
+//------------------------------------------------------------------------------
+console.group = console.log;
+
+//------------------------------------------------------------------------------
+console.groupCollapsed = console.log;
+
+//------------------------------------------------------------------------------
+console.groupEnd = noop;
+
+//------------------------------------------------------------------------------
+console.time = function(name) {
+    Timers[name] = new Date().valueOf();
+};
+
+//------------------------------------------------------------------------------
+console.timeEnd = function(name) {
+    var timeStart = Timers[name];
+    if (!timeStart) {
+        console.warn("unknown timer: " + name);
+        return;
+    }
+
+    var timeElapsed = new Date().valueOf() - timeStart;
+    console.log(name + ": " + timeElapsed + "ms");
+};
+
+//------------------------------------------------------------------------------
+console.timeStamp = noop;
+
+//------------------------------------------------------------------------------
+console.profile = noop;
+
+//------------------------------------------------------------------------------
+console.profileEnd = noop;
+
+//------------------------------------------------------------------------------
+console.count = noop;
+
+//------------------------------------------------------------------------------
+console.exception = console.log;
+
+//------------------------------------------------------------------------------
+console.table = function(data, columns) {
+    console.log("%o", data);
+};
+
+//------------------------------------------------------------------------------
+// return a new function that calls both functions passed as args
+//------------------------------------------------------------------------------
+function wrapperedOrigCall(orgFunc, newFunc) {
+    return function() {
+        var args = [].slice.call(arguments);
+        try { orgFunc.apply(WinConsole, args); } catch (e) {}
+        try { newFunc.apply(console,    args); } catch (e) {}
+    };
+}
+
+//------------------------------------------------------------------------------
+// For every function that exists in the original console object, that
+// also exists in the new console object, wrap the new console method
+// with one that calls both
+//------------------------------------------------------------------------------
+for (var key in console) {
+    if (typeof WinConsole[key] == "function") {
+        console[key] = wrapperedOrigCall(WinConsole[key], console[key]);
+    }
+}
+
+});
+
+// file: lib/common/plugin/contacts.js
+define("cordova/plugin/contacts", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+* Represents a group of Contacts.
+* @constructor
+*/
+var contacts = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     * @param fields that should be searched
+     * @param successCB success callback
+     * @param errorCB error callback
+     * @param {ContactFindOptions} options that can be applied to contact searching
+     * @return array of Contacts matching search criteria
+     */
+    find:function(fields, successCB, errorCB, options) {
+        if (!successCB) {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+        if (!fields || (utils.isArray(fields) && fields.length === 0)) {
+            if (typeof errorCB === "function") {
+                errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+        } else {
+            var win = function(result) {
+                var cs = [];
+                for (var i = 0, l = result.length; i < l; i++) {
+                    cs.push(contacts.create(result[i]));
+                }
+                successCB(cs);
+            };
+            exec(win, errorCB, "Contacts", "search", [fields, options]);
+        }
+    },
+
+    /**
+     * This function creates a new contact, but it does not persist the contact
+     * to device storage. To persist the contact to device storage, invoke
+     * contact.save().
+     * @param properties an object who's properties will be examined to create a new Contact
+     * @returns new Contact object
+     */
+    create:function(properties) {
+        var i;
+        var contact = new Contact();
+        for (i in properties) {
+            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {
+                contact[i] = properties[i];
+            }
+        }
+        return contact;
+    }
+};
+
+module.exports = contacts;
+
+});
+
+// file: lib/common/plugin/device.js
+define("cordova/plugin/device", function(require, exports, module) {
+var channel = require('cordova/channel'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+/**
+ * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+function Device() {
+    this.available = false;
+    this.platform = null;
+    this.version = null;
+    this.name = null;
+    this.uuid = null;
+    this.cordova = null;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getInfo(function(info) {
+            me.available = true;
+            me.platform = info.platform;
+            me.version = info.version;
+            me.name = info.name;
+            me.uuid = info.uuid;
+            me.cordova = info.cordova;
+            channel.onCordovaInfoReady.fire();
+        },function(e) {
+            me.available = false;
+            utils.alert("[ERROR] Error initializing Cordova: " + e);
+        });
+    });
+}
+
+/**
+ * Get device info
+ *
+ * @param {Function} successCallback The function to call when the heading data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
+ */
+Device.prototype.getInfo = function(successCallback, errorCallback) {
+
+    // successCallback required
+    if (typeof successCallback !== "function") {
+        console.log("Device Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Device Error: errorCallback is not a function");
+        return;
+    }
+
+    // Get info
+    exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
+};
+
+module.exports = new Device();
+
+});
+
+// file: lib/common/plugin/geolocation.js
+define("cordova/plugin/geolocation", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    PositionError = require('cordova/plugin/PositionError'),
+    Position = require('cordova/plugin/Position');
+
+var timers = {};   // list of timers in use
+
+// Returns default params, overrides if provided with values
+function parseParameters(options) {
+    var opt = {
+        maximumAge: 0,
+        enableHighAccuracy: false,
+        timeout: Infinity
+    };
+
+    if (options) {
+        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {
+            opt.maximumAge = options.maximumAge;
+        }
+        if (options.enableHighAccuracy !== undefined) {
+            opt.enableHighAccuracy = options.enableHighAccuracy;
+        }
+        if (options.timeout !== undefined && !isNaN(options.timeout)) {
+            if (options.timeout < 0) {
+                opt.timeout = 0;
+            } else {
+                opt.timeout = options.timeout;
+            }
+        }
+    }
+
+    return opt;
+}
+
+// Returns a timeout failure, closed over a specified timeout value and error callback.
+function createTimeout(errorCallback, timeout) {
+    var t = setTimeout(function() {
+        clearTimeout(t);
+        t = null;
+        errorCallback({
+            code:PositionError.TIMEOUT,
+            message:"Position retrieval timed out."
+        });
+    }, timeout);
+    return t;
+}
+
+var geolocation = {
+    lastPosition:null, // reference to last known (cached) position returned
+    /**
+   * Asynchronously aquires the current position.
+   *
+   * @param {Function} successCallback    The function to call when the position data is available
+   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)
+   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)
+   */
+    getCurrentPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("getCurrentPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        // Timer var that will fire an error callback if no position is retrieved from native
+        // before the "timeout" param provided expires
+        var timeoutTimer = null;
+
+        var win = function(p) {
+            clearTimeout(timeoutTimer);
+            if (!timeoutTimer) {
+                // Timeout already happened, or native fired error callback for
+                // this geo request.
+                // Don't continue with success callback.
+                return;
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+        var fail = function(e) {
+            clearTimeout(timeoutTimer);
+            timeoutTimer = null;
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just
+        // fire the success callback with the cached position.
+        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {
+            successCallback(geolocation.lastPosition);
+        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.
+        } else if (options.timeout === 0) {
+            fail({
+                code:PositionError.TIMEOUT,
+                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter."
+            });
+        // Otherwise we have to call into native to retrieve a position.
+        } else {
+            if (options.timeout !== Infinity) {
+                // If the timeout value was not set to Infinity (default), then
+                // set up a timeout function that will fire the error callback
+                // if no successful position was retrieved before timeout expired.
+                timeoutTimer = createTimeout(fail, options.timeout);
+            } else {
+                // This is here so the check in the win function doesn't mess stuff up
+                // may seem weird but this guarantees timeoutTimer is
+                // always truthy before we call into native
+                timeoutTimer = true;
+            }
+            exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);
+        }
+        return timeoutTimer;
+    },
+    /**
+     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,
+     * the successCallback is called with the new location.
+     *
+     * @param {Function} successCallback    The function to call each time the location data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)
+     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("watchPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        var id = utils.createUUID();
+
+        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition
+        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);
+
+        var fail = function(e) {
+            clearTimeout(timers[id]);
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        var win = function(p) {
+            clearTimeout(timers[id]);
+            if (options.timeout !== Infinity) {
+                timers[id] = createTimeout(fail, options.timeout);
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+
+        exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);
+
+        return id;
+    },
+    /**
+     * Clears the specified heading watch.
+     *
+     * @param {String} id       The ID of the watch returned from #watchPosition
+     */
+    clearWatch:function(id) {
+        if (id && timers[id] !== undefined) {
+            clearTimeout(timers[id]);
+            delete timers[id];
+            exec(null, null, "Geolocation", "clearWatch", [id]);
+        }
+    }
+};
+
+module.exports = geolocation;
+
+});
+
+// file: lib/common/plugin/logger.js
+define("cordova/plugin/logger", function(require, exports, module) {
+//------------------------------------------------------------------------------
+// The logger module exports the following properties/functions:
+//
+// LOG                          - constant for the level LOG
+// ERROR                        - constant for the level ERROR
+// WARN                         - constant for the level WARN
+// INFO                         - constant for the level INFO
+// DEBUG                        - constant for the level DEBUG
+// logLevel()                   - returns current log level
+// logLevel(value)              - sets and returns a new log level
+// useConsole()                 - returns whether logger is using console
+// useConsole(value)            - sets and returns whether logger is using console
+// log(message,...)             - logs a message at level LOG
+// error(message,...)           - logs a message at level ERROR
+// warn(message,...)            - logs a message at level WARN
+// info(message,...)            - logs a message at level INFO
+// debug(message,...)           - logs a message at level DEBUG
+// logLevel(level,message,...)  - logs a message specified level
+//
+//------------------------------------------------------------------------------
+
+var logger = exports;
+
+var exec    = require('cordova/exec');
+var utils   = require('cordova/utils');
+
+var UseConsole   = true;
+var Queued       = [];
+var DeviceReady  = false;
+var CurrentLevel;
+
+/**
+ * Logging levels
+ */
+
+var Levels = [
+    "LOG",
+    "ERROR",
+    "WARN",
+    "INFO",
+    "DEBUG"
+];
+
+/*
+ * add the logging levels to the logger object and
+ * to a separate levelsMap object for testing
+ */
+
+var LevelsMap = {};
+for (var i=0; i<Levels.length; i++) {
+    var level = Levels[i];
+    LevelsMap[level] = i;
+    logger[level]    = level;
+}
+
+CurrentLevel = LevelsMap.WARN;
+
+/**
+ * Getter/Setter for the logging level
+ *
+ * Returns the current logging level.
+ *
+ * When a value is passed, sets the logging level to that value.
+ * The values should be one of the following constants:
+ *    logger.LOG
+ *    logger.ERROR
+ *    logger.WARN
+ *    logger.INFO
+ *    logger.DEBUG
+ *
+ * The value used determines which messages get printed.  The logging
+ * values above are in order, and only messages logged at the logging
+ * level or above will actually be displayed to the user.  Eg, the
+ * default level is WARN, so only messages logged with LOG, ERROR, or
+ * WARN will be displayed; INFO and DEBUG messages will be ignored.
+ */
+logger.level = function (value) {
+    if (arguments.length) {
+        if (LevelsMap[value] === null) {
+            throw new Error("invalid logging level: " + value);
+        }
+        CurrentLevel = LevelsMap[value];
+    }
+
+    return Levels[CurrentLevel];
+};
+
+/**
+ * Getter/Setter for the useConsole functionality
+ *
+ * When useConsole is true, the logger will log via the
+ * browser 'console' object.  Otherwise, it will use the
+ * native Logger plugin.
+ */
+logger.useConsole = function (value) {
+    if (arguments.length) UseConsole = !!value;
+
+    if (UseConsole) {
+        if (typeof console == "undefined") {
+            throw new Error("global console object is not defined");
+        }
+
+        if (typeof console.log != "function") {
+            throw new Error("global console object does not have a log function");
+        }
+
+        if (typeof console.useLogger == "function") {
+            if (console.useLogger()) {
+                throw new Error("console and logger are too intertwingly");
+            }
+        }
+    }
+
+    return UseConsole;
+};
+
+/**
+ * Logs a message at the LOG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.log   = function(message) { logWithArgs("LOG",   arguments); };
+
+/**
+ * Logs a message at the ERROR level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.error = function(message) { logWithArgs("ERROR", arguments); };
+
+/**
+ * Logs a message at the WARN level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.warn  = function(message) { logWithArgs("WARN",  arguments); };
+
+/**
+ * Logs a message at the INFO level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.info  = function(message) { logWithArgs("INFO",  arguments); };
+
+/**
+ * Logs a message at the DEBUG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.debug = function(message) { logWithArgs("DEBUG", arguments); };
+
+// log at the specified level with args
+function logWithArgs(level, args) {
+    args = [level].concat([].slice.call(args));
+    logger.logLevel.apply(logger, args);
+}
+
+/**
+ * Logs a message at the specified level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.logLevel = function(level, message /* , ... */) {
+    // format the message with the parameters
+    var formatArgs = [].slice.call(arguments, 2);
+    message    = utils.vformat(message, formatArgs);
+
+    if (LevelsMap[level] === null) {
+        throw new Error("invalid logging level: " + level);
+    }
+
+    if (LevelsMap[level] > CurrentLevel) return;
+
+    // queue the message if not yet at deviceready
+    if (!DeviceReady && !UseConsole) {
+        Queued.push([level, message]);
+        return;
+    }
+
+    // if not using the console, use the native logger
+    if (!UseConsole) {
+        exec(null, null, "Logger", "logLevel", [level, message]);
+        return;
+    }
+
+    // make sure console is not using logger
+    if (console.__usingCordovaLogger) {
+        throw new Error("console and logger are too intertwingly");
+    }
+
+    // log to the console
+    switch (level) {
+        case logger.LOG:   console.log(message); break;
+        case logger.ERROR: console.log("ERROR: " + message); break;
+        case logger.WARN:  console.log("WARN: "  + message); break;
+        case logger.INFO:  console.log("INFO: "  + message); break;
+        case logger.DEBUG: console.log("DEBUG: " + message); break;
+    }
+};
+
+// when deviceready fires, log queued messages
+logger.__onDeviceReady = function() {
+    if (DeviceReady) return;
+
+    DeviceReady = true;
+
+    for (var i=0; i<Queued.length; i++) {
+        var messageArgs = Queued[i];
+        logger.logLevel(messageArgs[0], messageArgs[1]);
+    }
+
+    Queued = null;
+};
+
+// add a deviceready event to log queued messages
+document.addEventListener("deviceready", logger.__onDeviceReady, false);
+
+});
+
+// file: lib/common/plugin/network.js
+define("cordova/plugin/network", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    cordova = require('cordova'),
+    channel = require('cordova/channel');
+
+var NetworkConnection = function () {
+    this.type = null;
+    this._firstRun = true;
+    this._timer = null;
+    this.timeout = 500;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getInfo(function (info) {
+            me.type = info;
+            if (info === "none") {
+                // set a timer if still offline at the end of timer send the offline event
+                me._timer = setTimeout(function(){
+                    cordova.fireDocumentEvent("offline");
+                    me._timer = null;
+                    }, me.timeout);
+            } else {
+                // If there is a current offline event pending clear it
+                if (me._timer !== null) {
+                    clearTimeout(me._timer);
+                    me._timer = null;
+                }
+                cordova.fireDocumentEvent("online");
+            }
+
+            // should only fire this once
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+        },
+        function (e) {
+            // If we can't get the network info we should still tell Cordova
+            // to fire the deviceready event.
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+            console.log("Error initializing Network Connection: " + e);
+        });
+    });
+};
+
+/**
+ * Get connection info
+ *
+ * @param {Function} successCallback The function to call when the Connection data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)
+ */
+NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) {
+    // Get info
+    exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []);
+};
+
+module.exports = new NetworkConnection();
+});
+
+// file: lib/common/plugin/notification.js
+define("cordova/plugin/notification", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+/**
+ * Provides access to notifications on the device.
+ */
+
+module.exports = {
+
+    /**
+     * Open a native alert dialog, with a customizable title and button text.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} completeCallback   The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Alert)
+     * @param {String} buttonLabel          Label of the close button (default: OK)
+     */
+    alert: function(message, completeCallback, title, buttonLabel) {
+        var _title = (title || "Alert");
+        var _buttonLabel = (buttonLabel || "OK");
+        exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]);
+    },
+
+    /**
+     * Open a native confirm dialog, with a customizable title and button text.
+     * The result that the user selects is returned to the result callback.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Confirm)
+     * @param {String} buttonLabels         Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+     */
+    confirm: function(message, resultCallback, title, buttonLabels) {
+        var _title = (title || "Confirm");
+        var _buttonLabels = (buttonLabels || "OK,Cancel");
+        exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
+    },
+
+    /**
+     * Causes the device to vibrate.
+     *
+     * @param {Integer} mills       The number of milliseconds to vibrate for.
+     */
+    vibrate: function(mills) {
+        exec(null, null, "Notification", "vibrate", [mills]);
+    },
+
+    /**
+     * Causes the device to beep.
+     * On Android, the default notification ringtone is played "count" times.
+     *
+     * @param {Integer} count       The number of beeps.
+     */
+    beep: function(count) {
+        exec(null, null, "Notification", "beep", [count]);
+    }
+};
+});
+
+// file: lib/common/plugin/requestFileSystem.js
+define("cordova/plugin/requestFileSystem", function(require, exports, module) {
+var FileError = require('cordova/plugin/FileError'),
+    FileSystem = require('cordova/plugin/FileSystem'),
+    exec = require('cordova/exec');
+
+/**
+ * Request a file system in which to store application data.
+ * @param type  local file system type
+ * @param size  indicates how much storage space, in bytes, the application expects to need
+ * @param successCallback  invoked with a FileSystem object
+ * @param errorCallback  invoked if error occurs retrieving file system
+ */
+var requestFileSystem = function(type, size, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    if (type < 0 || type > 3) {
+        fail(FileError.SYNTAX_ERR);
+    } else {
+        // if successful, return a FileSystem object
+        var success = function(file_system) {
+            if (file_system) {
+                if (typeof successCallback === 'function') {
+                    // grab the name and root from the file system object
+                    var result = new FileSystem(file_system.name, file_system.root);
+                    successCallback(result);
+                }
+            }
+            else {
+                // no FileSystem object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+        exec(success, fail, "File", "requestFileSystem", [type, size]);
+    }
+};
+
+module.exports = requestFileSystem;
+});
+
+// file: lib/common/plugin/resolveLocalFileSystemURI.js
+define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) {
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    FileError = require('cordova/plugin/FileError'),
+    exec = require('cordova/exec');
+
+/**
+ * Look up file system Entry referred to by local URI.
+ * @param {DOMString} uri  URI referring to a local file or directory
+ * @param successCallback  invoked with Entry object corresponding to URI
+ * @param errorCallback    invoked if error occurs retrieving file system entry
+ */
+module.exports = function(uri, successCallback, errorCallback) {
+    // error callback
+    var fail = function(error) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(error));
+        }
+    };
+    // sanity check for 'not:valid:filename'
+    if(!uri || uri.split(":").length > 2) {
+        setTimeout( function() {
+            fail(FileError.ENCODING_ERR);
+        },0);
+        return;
+    }
+    // if successful, return either a file or directory entry
+    var success = function(entry) {
+        var result;
+        if (entry) {
+            if (typeof successCallback === 'function') {
+                // create appropriate Entry object
+                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);
+                try {
+                    successCallback(result);
+                }
+                catch (e) {
+                    console.log('Error invoking callback: ' + e);
+                }
+            }
+        }
+        else {
+            // no Entry object returned
+            fail(FileError.NOT_FOUND_ERR);
+        }
+    };
+
+    exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
+};
+
+});
+
+// file: lib/common/plugin/splashscreen.js
+define("cordova/plugin/splashscreen", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+var splashscreen = {
+    show:function() {
+        exec(null, null, "SplashScreen", "show", []);
+    },
+    hide:function() {
+        exec(null, null, "SplashScreen", "hide", []);
+    }
+};
+
+module.exports = splashscreen;
+});
+
+// file: lib/tizen/plugin/tizen/Accelerometer.js
+define("cordova/plugin/tizen/Accelerometer", function(require, exports, module) {
+var callback = null;
+
+module.exports = {
+    start: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+        callback = function (motion) {
+            successCallback({
+                x: motion.accelerationIncludingGravity.x,
+                y: motion.accelerationIncludingGravity.y,
+                z: motion.accelerationIncludingGravity.z,
+                timestamp: motion.timeStamp
+            });
+        };
+        window.addEventListener("devicemotion", callback);
+    },
+    stop: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+    }
+};
+});
+
+// file: lib/tizen/plugin/tizen/Battery.js
+define("cordova/plugin/tizen/Battery", function(require, exports, module) {
+/*global tizen:false */
+var id = null;
+
+module.exports = {
+    start: function(successCallback, errorCallback) {
+        var tizenSuccessCallback = function(power) {
+            if (successCallback) {
+                successCallback({level: Math.round(power.level * 100), isPlugged: power.isCharging});
+            }
+        };
+
+        if (id === null) {
+            id = tizen.systeminfo.addPropertyValueChangeListener("Power", tizenSuccessCallback);
+        }
+        tizen.systeminfo.getPropertyValue("Power", tizenSuccessCallback, errorCallback);
+    },
+
+    stop: function(successCallback, errorCallback) {
+        tizen.systeminfo.removePropertyValueChangeListener(id);
+        id = null;
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/BufferLoader.js
+define("cordova/plugin/tizen/BufferLoader", function(require, exports, module) {
+/*
+ * Buffer Loader Object
+ * This class provides a sound buffer for one or more sounds
+ * holded in a local file located by an url
+ *
+ * uses W3C  Web Audio API
+ *
+ * @constructor
+ *
+ * @param {AudioContext} audio context object
+ * @param {Array} urlList, array of url for sound to load
+ * @param {function} callback , called after buffer was loaded
+ *
+ */
+
+function BufferLoader(context, urlList, callback) {
+    this.context = context;
+    this.urlList = urlList;
+    this.onload = callback;
+    this.bufferList = [];
+    this.loadCount = 0;
+}
+
+/*
+ * This method loads a sound into a buffer
+ * @param {Array} urlList, array of url for sound to load
+ * @param {Number} index, buffer index in the array where to load the url sound
+ *
+ */
+
+BufferLoader.prototype.loadBuffer = function(url, index) {
+    // Load buffer asynchronously
+    var request = null,
+        loader = null;
+
+    request = new XMLHttpRequest();
+
+    if (request === null) {
+        console.log ("BufferLoader.prototype.loadBuffer, cannot allocate XML http request");
+        return;
+    }
+
+    request.open("GET", url, true);
+    request.responseType = "arraybuffer";
+
+    loader = this;
+
+    request.onload = function() {
+    // Asynchronously decode the audio file data in request.response
+    loader.context.decodeAudioData(
+        request.response,
+        function(buffer) {
+                if (!buffer) {
+                    console.log ("BufferLoader.prototype.loadBuffer,error decoding file data: " + url);
+                    return;
+                }
+
+                loader.bufferList[index] = buffer;
+
+                if (++loader.loadCount == loader.urlList.length) {
+                    loader.onload(loader.bufferList);
+                }
+            }
+        );
+    };
+
+    request.onerror = function() {
+        console.log ("BufferLoader.prototype.loadBuffer, XHR error");
+    };
+
+    request.send();
+};
+
+/*
+ * This method loads all sounds identified by their url
+ * and that where given to the object constructor
+ *
+ */
+
+BufferLoader.prototype.load = function() {
+    for (var i = 0; i < this.urlList.length; ++i) {
+        this.loadBuffer(this.urlList[i], i);
+    }
+};
+
+module.exports = BufferLoader;
+
+});
+
+// file: lib/tizen/plugin/tizen/Camera.js
+define("cordova/plugin/tizen/Camera", function(require, exports, module) {
+/*global tizen:false */
+var Camera = require('cordova/plugin/CameraConstants');
+
+function makeReplyCallback(successCallback, errorCallback) {
+    return {
+        onsuccess: function(reply) {
+            if (reply.length > 0) {
+                successCallback(reply[0].value);
+            } else {
+                errorCallback('Picture selection aborted');
+            }
+        },
+        onfail: function() {
+           console.log('The service launch failed');
+        }
+    };
+}
+
+module.exports = {
+    takePicture: function(successCallback, errorCallback, args) {
+        var destinationType = args[1],
+            sourceType = args[2],
+            encodingType = args[5],
+            mediaType = args[6];
+            // Not supported
+            /*
+            quality = args[0]
+            targetWidth = args[3]
+            targetHeight = args[4]
+            allowEdit = args[7]
+            correctOrientation = args[8]
+            saveToPhotoAlbum = args[9]
+            */
+
+        if (destinationType !== Camera.DestinationType.FILE_URI) {
+            errorCallback('DestinationType not supported');
+            return;
+        }
+        if (mediaType !== Camera.MediaType.PICTURE) {
+            errorCallback('MediaType not supported');
+            return;
+        }
+
+        var mimeType;
+        if (encodingType === Camera.EncodingType.JPEG) {
+            mimeType = 'image/jpeg';
+        } else if (encodingType === Camera.EncodingType.PNG) {
+            mimeType = 'image/png';
+        } else {
+            mimeType = 'image/*';
+        }
+
+        var serviceId;
+        if (sourceType === Camera.PictureSourceType.CAMERA) {
+            serviceId = 'http://tizen.org/appsvc/operation/create_content';
+        } else {
+            serviceId = 'http://tizen.org/appsvc/operation/pick';
+        }
+
+        var service = new tizen.ApplicationService(serviceId, null, mimeType, null);
+        tizen.application.launchService(service, null, null,
+                function(error) { errorCallback(error.message); },
+                makeReplyCallback(successCallback, errorCallback));
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Compass.js
+define("cordova/plugin/tizen/Compass", function(require, exports, module) {
+var CompassError = require('cordova/plugin/CompassError'),
+    callback = null, ready = false;
+
+module.exports = {
+    getHeading: function(successCallback, errorCallback) {
+        if (window.DeviceOrientationEvent !== undefined) {
+            callback = function (orientation) {
+                var heading = 360 - orientation.alpha;
+                if (ready) {
+                    successCallback({
+                        magneticHeading: heading,
+                        trueHeading: heading,
+                        headingAccuracy: 0,
+                        timestamp: orientation.timeStamp
+                    });
+                    window.removeEventListener("deviceorientation", callback);
+                }
+                ready = true;
+            };
+            ready = false; // workaround invalid first event value returned by WRT
+            window.addEventListener("deviceorientation", callback);
+        }
+        else {
+            errorCallback(CompassError.COMPASS_NOT_SUPPORTED);
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Contact.js
+define("cordova/plugin/tizen/Contact", function(require, exports, module) {
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// ------------------
+// Utility functions
+// ------------------
+
+
+/**
+ * Retrieves a Tizen Contact object from the device by its unique id.
+ *
+ * @param uid
+ *            Unique id of the contact on the device
+ * @return {tizen.Contact} Tizen Contact object or null if contact with
+ *         specified id is not found
+ */
+var findByUniqueId = function(id) {
+
+    if (!id) {
+        return null;
+    }
+
+    var tizenContact = null;
+
+    tizen.contact.getDefaultAddressBook().find(
+        function _successCallback(contacts){
+            tizenContact = contacts[0];
+        },
+        function _errorCallback(error){
+            console.log("tizen find error " + error);
+        },
+        new tizen.AttributeFilter('id', 'CONTAINS', id),
+        new tizen.SortMode('id', 'ASC'));
+
+    return tizenContact || null;
+};
+
+
+var traceTizenContact = function (tizenContact) {
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.id " + tizenContact.id);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.lastUpdated " + tizenContact.lastUpdated);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.name " + tizenContact.name);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.account " + tizenContact.account);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.addresses " + tizenContact.addresses);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.photoURI " + tizenContact.photoURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.phoneNumbers " + tizenContact.phoneNumbers);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.emails " + tizenContact.emails);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.birthday " + tizenContact.birthday);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.organization " + tizenContact.organization);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.notes " + tizenContact.notes);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.urls " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.isFavorite " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.ringtonesURI " + tizenContact.ringtonesURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.categories " + tizenContact.categories);
+};
+
+
+/**
+ * Creates a Tizen contact object from the W3C Contact object and persists
+ * it to device storage.
+ *
+ * @param {Contact}
+ *            contact The contact to save
+ * @return a new contact object with all properties set
+ */
+var saveToDevice = function(contact) {
+
+    if (!contact) {
+        return;
+    }
+
+    var tizenContact = null;
+    var update = false;
+    var i = 0;
+
+    // if the underlying Tizen Contact object already exists, retrieve it for
+    // update
+    if (contact.id) {
+        // we must attempt to retrieve the BlackBerry contact from the device
+        // because this may be an update operation
+        tizenContact = findByUniqueId(contact.id);
+    }
+
+    // contact not found on device, create a new one
+    if (!tizenContact) {
+        tizenContact = new tizen.Contact();
+    }
+    // update the existing contact
+    else {
+        update = true;
+    }
+
+    // NOTE: The user may be working with a partial Contact object, because only
+    // user-specified Contact fields are returned from a find operation (blame
+    // the W3C spec). If this is an update to an existing Contact, we don't
+    // want to clear an attribute from the contact database simply because the
+    // Contact object that the user passed in contains a null value for that
+    // attribute. So we only copy the non-null Contact attributes to the
+    // Tizen Contact object before saving.
+    //
+    // This means that a user must explicitly set a Contact attribute to a
+    // non-null value in order to update it in the contact database.
+    //
+    traceTizenContact (tizenContact);
+
+    // display name
+    if (contact.displayName !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            tizenContact.name.displayName = contact.displayName;
+        }
+    }
+
+    // name
+    if (contact.name !== null) {
+        if (contact.name.givenName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.firstName = contact.name.givenName;
+            }
+        }
+
+        if  (contact.name.middleName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.middleName = contact.name.middleName;
+            }
+        }
+
+        if (contact.name.familyName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.lastName = contact.name.familyName;
+            }
+        }
+
+        if (contact.name.honorificPrefix) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.prefix = contact.name.honorificPrefix;
+            }
+        }
+    }
+
+    // nickname
+    if (contact.nickname !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            if (!utils.isArray(tizenContact.name.nicknames))
+            {
+                tizenContact.name.nicknames = [];
+            }
+            tizenContact.name.nicknames[0] = contact.nickname;
+        }
+    }
+    else {
+        tizenContact.name.nicknames = [];
+    }
+
+    // note
+    if (contact.note !== null) {
+        if (tizenContact.note === null) {
+            tizenContact.note = [];
+        }
+        if (tizenContact.note !== null) {
+            tizenContact.note[0] = contact.note;
+        }
+    }
+
+    // photos
+    if (contact.photos && utils.isArray(contact.emails) && contact.emails.length > 0) {
+        tizenContact.photoURI = contact.photos[0];
+    }
+
+    if (utils.isDate(contact.birthday)) {
+        if (!utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday = new Date();
+        }
+        if (utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday.setDate(contact.birthday.getDate());
+        }
+    }
+
+    // Tizen supports many addresses
+    if (utils.isArray(contact.emails)) {
+
+        // if this is an update, re initialize email addresses
+        if (update) {
+            // doit on effacer sur un update??????
+        }
+
+        // copy the first three email addresses found
+        var emails = [];
+        for (i = 0; i < contact.emails.length; i += 1) {
+            var emailTypes = [];
+
+            emailTypes.push (contact.emails[i].type);
+
+            if (contact.emails[i].pref) {
+                emailTypes.push ("PREF");
+            }
+
+            emails.push(
+                new tizen.ContactEmailAddress(
+                    contact.emails[i].value,
+                    emailTypes)
+            );
+        }
+        tizenContact.emails = emails.length > 0 ? emails : [];
+    }
+    else {
+        tizenContact.emails = [];
+    }
+
+    // Tizen supports many phone numbers
+    // copy into appropriate fields based on type
+    if (utils.isArray(contact.phoneNumbers)) {
+        // if this is an update, re-initialize phone numbers
+        if (update) {
+        }
+
+        var phoneNumbers = [];
+
+        for (i = 0; i < contact.phoneNumbers.length; i += 1) {
+
+            if (!contact.phoneNumbers[i] || !contact.phoneNumbers[i].value) {
+                continue;
+            }
+
+             var phoneTypes = [];
+             phoneTypes.push (contact.phoneNumbers[i].type);
+
+             if (contact.phoneNumbers[i].pref) {
+                 phoneTypes.push ("PREF");
+             }
+
+            phoneNumbers.push(
+                new tizen.ContactPhoneNumber(
+                    contact.phoneNumbers[i].value,
+                    phoneTypes)
+            );
+        }
+
+        tizenContact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : [];
+    } else {
+        tizenContact.phoneNumbers = [];
+    }
+
+    if (utils.isArray(contact.addresses)) {
+        // if this is an update, re-initialize addresses
+        if (update) {
+        }
+
+        var addresses = [],
+            address = null;
+
+        for ( i = 0; i < contact.addresses.length; i += 1) {
+            address = contact.addresses[i];
+
+            if (!address || address.id === undefined || address.pref === undefined || address.type === undefined || address.formatted === undefined) {
+                continue;
+            }
+
+            var addressTypes = [];
+            addressTypes.push (address.type);
+
+            if (address.pref) {
+                addressTypes.push ("PREF");
+            }
+
+            addresses.push(
+                new tizen.ContactAddress({
+                         country:                   address.country,
+                         region :                   address.region,
+                         city:                      address.locality,
+                         streetAddress:             address.streetAddress,
+                         additionalInformation:     "",
+                         postalCode:                address.postalCode,
+                         types :                    addressTypes
+                }));
+
+        }
+        tizenContact.addresses = addresses.length > 0 ? addresses : [];
+
+    } else{
+        tizenContact.addresses = [];
+    }
+
+    // copy first url found to BlackBerry 'webpage' field
+    if (utils.isArray(contact.urls)) {
+        // if this is an update, re-initialize web page
+        if (update) {
+        }
+
+        var url = null,
+            urls = [];
+
+        for ( i = 0; i< contact.urls.length; i+= 1) {
+            url = contact.urls[i];
+
+            if (!url || !url.value) {
+                continue;
+            }
+
+            urls.push( new tizen.ContactWebSite(url.value, url.type));
+        }
+        tizenContact.urls = urls.length > 0 ? urls : [];
+    } else{
+        tizenContact.urls = [];
+    }
+
+    if (utils.isArray(contact.organizations && contact.organizations.length > 0) ) {
+        // if this is an update, re-initialize org attributes
+        var organization = contact.organizations[0];
+
+         tizenContact.organization = new tizen.ContacOrganization({
+             name:          organization.name,
+             department:    organization.department,
+             office:        "",
+             title:         organization.title,
+             role:          "",
+             logoURI:       ""
+         });
+    }
+
+    // categories
+    if (utils.isArray(contact.categories)) {
+        tizenContact.categories = [];
+
+        var category = null;
+
+        for (i = 0; i < contact.categories.length; i += 1) {
+            category = contact.categories[i];
+
+            if (typeof category === "string") {
+                tizenContact.categories.push(category);
+            }
+        }
+    }
+    else {
+        tizenContact.categories = [];
+    }
+
+    // save to device
+    // in tizen contact mean update or add
+    // later we might use addBatch and updateBatch
+    if (update){
+        tizen.contact.getDefaultAddressBook().update(tizenContact);
+    }
+    else {
+        tizen.contact.getDefaultAddressBook().add(tizenContact);
+    }
+
+    // Use the fully populated Tizen contact object to create a
+    // corresponding W3C contact object.
+    return ContactUtils.createContact(tizenContact, [ "*" ]);
+};
+
+
+/**
+ * Creates a Tizen ContactAddress object from a W3C ContactAddress.
+ *
+ * @return {tizen.ContactAddress} a Tizen ContactAddress object
+ */
+var createTizenAddress = function(address) {
+
+    var type = null,
+        pref = null,
+        typesAr = [];
+
+    if (address === null) {
+        return null;
+    }
+
+
+    var tizenAddress = new tizen.ContactAddress();
+
+    if (tizenAddress === null) {
+        return null;
+    }
+
+    typesAr.push(address.type);
+
+    if (address.pref) {
+        typesAr.push("PREF");
+    }
+
+    tizenAddress.country = address.country || "";
+    tizenAddress.region = address.region || "";
+    tizenAddress.city = address.locality || "";
+    tizenAddress.streetAddress = address.streetAddress || "";
+    tizenAddress.postalCode = address.postalCode || "";
+    tizenAddress.types = typesAr || "";
+
+    return tizenAddress;
+};
+
+module.exports = {
+    /**
+     * Persists contact to device storage.
+     */
+
+    save : function(successCB, failCB) {
+
+        try {
+            // save the contact and store it's unique id
+            var fullContact = saveToDevice(this);
+
+            this.id = fullContact.id;
+
+            // This contact object may only have a subset of properties
+            // if the save was an update of an existing contact. This is
+            // because the existing contact was likely retrieved using a
+            // subset of properties, so only those properties were set in the
+            // object. For this reason, invoke success with the contact object
+            // returned by saveToDevice since it is fully populated.
+
+            if (typeof successCB === 'function') {
+                successCB(fullContact);
+            }
+        }
+        catch (error) {
+            console.log('Error saving contact: ' +  error);
+
+            if (typeof failCB === 'function') {
+                failCB (new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    },
+
+    /**
+     * Removes contact from device storage.
+     *
+     * @param successCB
+     *            successCB callback
+     * @param failCB
+     *            error callback
+     */
+    remove : function (successCB, failCB) {
+
+        try {
+            // retrieve contact from device by id
+            var tizenContact = null;
+
+            if (this.id) {
+                tizenContact = findByUniqueId(this.id);
+            }
+
+
+            // if contact was found, remove it
+            if (tizenContact) {
+
+                tizen.contact.getDefaultAddressBook().remove(tizenContact.id);
+
+                if (typeof success === 'function') {
+                    successCB(this);
+                }
+            }
+            // attempting to remove a contact that hasn't been saved
+            else if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+        catch (error) {
+            console.log('Error removing contact ' + this.id + ": " + error);
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/ContactUtils.js
+define("cordova/plugin/tizen/ContactUtils", function(require, exports, module) {
+/*global tizen:false */
+var ContactAddress = require('cordova/plugin/ContactAddress'),
+    ContactName = require('cordova/plugin/ContactName'),
+    ContactField = require('cordova/plugin/ContactField'),
+    ContactOrganization = require('cordova/plugin/ContactOrganization'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+ * Mappings for each Contact field that may be used in a find operation. Maps
+ * W3C Contact fields to one or more fields in a Tizen contact object.
+ *
+ * Example: user searches with a filter on the Contact 'name' field:
+ *
+ * <code>Contacts.find(['name'], onSuccess, onFail, {filter:'Bob'});</code>
+ *
+ * The 'name' field does not exist in a Tizen contact. Instead, a filter
+ * expression will be built to search the Tizen contacts using the
+ * Tizen 'title', 'firstName' and 'lastName' fields.
+ */
+var fieldMappings = {
+    "id" : ["id"],
+    "displayName" : ["name.displayName"],
+    "nickname": ["name.nicknames"],
+    "name" : [ "name.prefix", "name.firstName", "name.lastName" ],
+    "phoneNumbers" : ["phoneNumbers.number","phoneNumbers.types"],
+    "emails" : ["emails.types", "emails.email"],
+    "addresses" : ["addresses.country","addresses.region","addresses.city","addresses.streetAddress","addresses.postalCode","addresses.country","addresses.types"],
+    "organizations" : ["organization.name","organization.department","organization.office", "organization.title"],
+    "birthday" : ["birthday"],
+    "note" : ["notes"],
+    "photos" : ["photoURI"],
+    "categories" : ["categories"],
+    "urls" : ["urls.url", "urls.type"]
+};
+
+/*
+ * Build an array of all of the valid W3C Contact fields. This is used to
+ * substitute all the fields when ["*"] is specified.
+ */
+var allFields = [];
+
+(function initializeAllFieldsMapping() {
+
+    for ( var key in fieldMappings) {
+        allFields.push(key);
+    }
+    // as we want it to be executed once
+    function initializeAllFieldsMapping() {
+    }
+
+})();
+
+/**
+ * Create a W3C ContactAddress object from a Tizen Address object
+ *
+ * @param {String}
+ *            type the type of address (e.g. work, home)
+ * @param {tizen.ContactAddress}
+ *            tizenAddress a Tizen Address object
+ * @return {ContactAddress} a contact address object or null if the specified
+ *         address is null
+ */
+var createContactAddress = function(type, tizenAddress) {
+    if (!tizenAddress) {
+        return null;
+    }
+
+    var streetAddress = tizenAddress.streetAddress;
+    var locality = tizenAddress.city || "";
+    var region = tizenAddress.region || "";
+    var postalCode = tizenAddress.postalCode || "";
+    var country = tizenAddress.country || "";
+    var formatted = streetAddress + ", " + locality + ", " + region + ", " + postalCode + ", " + country;
+
+    var contact = new ContactAddress(null, type, formatted, streetAddress, locality, region, postalCode, country);
+
+    return contact;
+};
+
+module.exports = {
+    /**
+     * Builds Tizen filter expressions for contact search using the
+     * contact fields and search filter provided.
+     *
+     * @param {String[]}
+     *            fields Array of Contact fields to search
+     * @param {String}
+     *            filter Filter, or search string
+     * @param {Boolean}
+     *                 multiple, one contacts or more wanted as result
+     * @return filter expression or null if fields is empty or filter is null or
+     *         empty
+     */
+
+    buildFilterExpression: function(fields, filter) {
+        // ensure filter exists
+        if (!filter || filter === "") {
+            return null;
+        }
+
+        if ((fields.length === 1) && (fields[0] === "*")) {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // build a filter expression using all Contact fields provided
+        var compositeFilter = null,
+            attributeFilter = null,
+            filterExpression = null,
+            matchFlag = "CONTAINS",
+            matchValue = filter,
+            attributesArray = [];
+
+        if (fields && utils.isArray(fields)) {
+
+            for ( var field in fields) {
+
+                if (!fields[field]) {
+                    continue;
+                }
+
+                // retrieve Tizen contact fields that map Cordova fields specified
+                // (tizenFields is a string or an array of strings)
+                var tizenFields = fieldMappings[fields[field]];
+
+                if (!tizenFields) {
+                    // does something maps
+                    continue;
+                }
+
+                // construct the filter expression using the Tizen fields
+                for ( var index in tizenFields) {
+                    attributeFilter = new tizen.AttributeFilter(tizenFields[index], matchFlag, matchValue);
+                    if (attributeFilter !== null) {
+                        attributesArray.push(attributeFilter);
+                    }
+                }
+            }
+        }
+
+        // fullfil tizen find attribute as a single or a composite attribute
+        if (attributesArray.length == 1 ) {
+            filterExpression = attributeFilter[0];
+        } else if (attributesArray.length > 1) {
+            // combine the filters as a Union
+            filterExpression = new tizen.CompositeFilter("UNION", attributesArray);
+        } else {
+            filterExpression = null;
+        }
+
+        return filterExpression;
+    },
+
+
+
+    /**
+     * Creates a Contact object from a Tizen Contact object, copying only
+     * the fields specified.
+     *
+     * This is intended as a privately used function but it is made globally
+     * available so that a Contact.save can convert a BlackBerry contact object
+     * into its W3C equivalent.
+     *
+     * @param {tizen.Contact}
+     *            tizenContact Tizen Contact object
+     * @param {String[]}
+     *            fields array of contact fields that should be copied
+     * @return {Contact} a contact object containing the specified fields or
+     *         null if the specified contact is null
+     */
+    createContact: function(tizenContact, fields) {
+
+        if (!tizenContact) {
+            return null;
+        }
+
+        // construct a new contact object
+        // always copy the contact id and displayName fields
+        var contact = new Contact(tizenContact.id, tizenContact.name.displayName);
+
+
+        // nothing to do
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            return contact;
+        } else if (fields.length === 1 && fields[0] === "*") {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // add the fields specified
+        for ( var key in fields) {
+
+            var field = fields[key],
+                index = 0;
+
+            if (!field) {
+                continue;
+            }
+
+            // name
+            if (field.indexOf('name') === 0) {
+
+                var formattedName = (tizenContact.name.prefix || "");
+
+                if (tizenContact.name.firstName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.firstName || "");
+                }
+
+                if (tizenContact.name.middleName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.middleName || "");
+                }
+
+                if (tizenContact.name.lastName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.lastName || "");
+                }
+
+                contact.name = new ContactName(
+                        formattedName,
+                        tizenContact.name.lastName,
+                        tizenContact.name.firstName,
+                        tizenContact.name.middleName,
+                        tizenContact.name.prefix,
+                        null);
+            }
+
+            // phoneNumbers
+            else if (field.indexOf('phoneNumbers') === 0) {
+
+                var phoneNumbers = [];
+
+                for (index = 0 ; index < tizenContact.phoneNumbers.length ; ++index) {
+
+                    phoneNumbers.push(
+                            new ContactField(
+                                    'PHONE',
+                                    tizenContact.phoneNumbers[index].number,
+                                    ((tizenContact.phoneNumbers[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+
+
+                contact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : null;
+            }
+
+            // emails
+            else if (field.indexOf('emails') === 0) {
+
+                var emails = [];
+
+                for (index = 0 ; index < tizenContact.emails.length ; ++index) {
+
+                    emails.push(
+                        new ContactField(
+                            'EMAILS',
+                            tizenContact.emails[index].email,
+                            ((tizenContact.emails[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+                contact.emails = emails.length > 0 ? emails : null;
+            }
+
+            // addresses
+            else if (field.indexOf('addresses') === 0) {
+
+                var addresses = [];
+                for (index = 0 ; index < tizenContact.addresses.length ; ++index) {
+
+                    addresses.push(
+                            new ContactAddress(
+                                    ((tizenContact.addresses[index].types[1] &&  tizenContact.addresses[index].types[1] === "PREF") ? true : false),
+                                    tizenContact.addresses[index].types[0] ? tizenContact.addresses[index].types[0] : "HOME",
+                                    null,
+                                    tizenContact.addresses[index].streetAddress,
+                                    tizenContact.addresses[index].city,
+                                    tizenContact.addresses[index].region,
+                                    tizenContact.addresses[index].postalCode,
+                                    tizenContact.addresses[index].country ));
+                }
+
+                contact.addresses = addresses.length > 0 ? addresses : null;
+            }
+
+            // birthday
+            else if (field.indexOf('birthday') === 0) {
+                if (utils.isDate(tizenContact.birthday)) {
+                    contact.birthday = tizenContact.birthday;
+                }
+            }
+
+            // note only one in Tizen Contact
+            else if (field.indexOf('note') === 0) {
+                if (tizenContact.note) {
+                    contact.note = tizenContact.note[0];
+                }
+            }
+
+            // organizations
+            else if (field.indexOf('organizations') === 0) {
+
+                var organizations = [];
+
+                // there's only one organization in a Tizen Address
+
+                if (tizenContact.organization) {
+                    organizations.push(
+                            new ContactOrganization(
+                                    true,
+                                    'WORK',
+                                    tizenContact.organization.name,
+                                    tizenContact.organization.department,
+                                    tizenContact.organization.jobTitle));
+                }
+
+                contact.organizations = organizations.length > 0 ? organizations : null;
+            }
+
+            // categories
+            else if (field.indexOf('categories') === 0) {
+
+                var categories = [];
+
+                if (tizenContact.categories) {
+
+                    for (index = 0 ; index < tizenContact.categories.length ; ++index) {
+                        categories.push(
+                                new ContactField(
+                                        'MAIN',
+                                        tizenContact.categories,
+                                        (index === 0) ));
+                    }
+
+                    contact.categories = categories.length > 0 ? categories : null;
+                }
+            }
+
+            // urls
+            else if (field.indexOf('urls') === 0) {
+                var urls = [];
+
+                if (tizenContact.urls) {
+                    for (index = 0 ; index <tizenContact.urls.length ; ++index) {
+                        urls.push(
+                                new ContactField(
+                                        tizenContact.urls[index].type,
+                                        tizenContact.urls[index].url,
+                                        (index === 0)));
+                    }
+                }
+
+                contact.urls = urls.length > 0 ? urls : null;
+            }
+
+            // photos
+            else if (field.indexOf('photos') === 0) {
+                var photos = [];
+
+                if (tizenContact.photoURI) {
+                    photos.push(new ContactField('URI', tizenContact.photoURI, true));
+                }
+
+                contact.photos = photos.length > 0 ? photos : null;
+            }
+        }
+
+        return contact;
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Device.js
+define("cordova/plugin/tizen/Device", function(require, exports, module) {
+/*global tizen:false */
+var channel = require('cordova/channel');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+function Device() {
+    this.version = null;
+    this.uuid = null;
+    this.name = null;
+    this.cordova =  "2.0.0";
+    this.platform = "Tizen";
+
+    var me = this;
+
+    function onSuccessCallback(sysInfoProp) {
+        me.name = sysInfoProp.model;
+        me.uuid = sysInfoProp.imei;
+        me.version = sysInfoProp.version;
+        channel.onCordovaInfoReady.fire();
+    }
+
+    function onErrorCallback(error) {
+        console.log("error initializing cordova: " + error);
+    }
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getDeviceInfo(onSuccessCallback, onErrorCallback);
+    });
+}
+
+Device.prototype.getDeviceInfo = function(success, fail, args) {
+    tizen.systeminfo.getPropertyValue("Device", success, fail);
+};
+
+module.exports = new Device();
+
+});
+
+// file: lib/tizen/plugin/tizen/File.js
+define("cordova/plugin/tizen/File", function(require, exports, module) {
+/*global WebKitBlobBuilder:false */
+var FileError = require('cordova/plugin/FileError'),
+    DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    File = require('cordova/plugin/File'),
+    FileSystem = require('cordova/plugin/FileSystem');
+
+var nativeRequestFileSystem = window.webkitRequestFileSystem,
+    nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL,
+    NativeFileReader = window.FileReader;
+
+function getFileSystemName(nativeFs) {
+    return (nativeFs.name.indexOf("Persistent") != -1) ? "persistent" : "temporary";
+}
+
+function makeEntry(entry) {
+    if (entry.isDirectory) {
+        return new DirectoryEntry(entry.name, decodeURI(entry.toURL()));
+    }
+    else {
+        return new FileEntry(entry.name, decodeURI(entry.toURL()));
+    }
+}
+
+module.exports = {
+    /* requestFileSystem */
+    requestFileSystem: function(successCallback, errorCallback, args) {
+        var type = args[0],
+            size = args[1];
+
+        nativeRequestFileSystem(type, size, function(nativeFs) {
+            successCallback(new FileSystem(getFileSystemName(nativeFs), makeEntry(nativeFs.root)));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* resolveLocalFileSystemURI */
+    resolveLocalFileSystemURI: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            successCallback(makeEntry(entry));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryReader */
+    readEntries: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(dirEntry) {
+            var reader = dirEntry.createReader();
+            reader.readEntries(function(entries) {
+                var retVal = [];
+                for (var i = 0; i < entries.length; i++) {
+                    retVal.push(makeEntry(entries[i]));
+                }
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* Entry */
+    getMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getMetadata(function(metaData) {
+                successCallback(metaData.modificationTime);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    moveTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.moveTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    copyTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.copyTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    remove: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.remove(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getParent: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getParent(function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileEntry */
+    getFileMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.file(function(file) {
+                var retVal = new File(file.name, decodeURI(entry.toURL()), file.type, file.lastModifiedDate, file.size);
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryEntry */
+    getDirectory: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getDirectory(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    removeRecursively: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.removeRecursively(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getFile: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getFile(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileReader */
+    readAsText: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            encoding = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsText(file, encoding);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    readAsDataURL: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsDataURL(file);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileWriter */
+    write: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            text = args[1],
+            position = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.position - position);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                var blob = new WebKitBlobBuilder();
+                blob.append(text);
+
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.seek(position);
+                writer.write(blob.getBlob('text/plain'));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    truncate: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            size = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.length);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.truncate(size);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/FileTransfer.js
+define("cordova/plugin/tizen/FileTransfer", function(require, exports, module) {
+/*global WebKitBlobBuilder:false */
+var FileEntry = require('cordova/plugin/FileEntry'),
+    FileTransferError = require('cordova/plugin/FileTransferError'),
+    FileUploadResult = require('cordova/plugin/FileUploadResult');
+
+var nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL;
+
+function getParentPath(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(0, pos + 1);
+}
+
+function getFileName(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(pos + 1);
+}
+
+module.exports = {
+    upload: function(successCallback, errorCallback, args) {
+        var filePath = args[0],
+            server = args[1],
+            fileKey = args[2],
+            fileName = args[3],
+            mimeType = args[4],
+            params = args[5],
+            /*trustAllHosts = args[6],*/
+            chunkedMode = args[7];
+
+        nativeResolveLocalFileSystemURI(filePath, function(entry) {
+            entry.file(function(file) {
+                function uploadFile(blobFile) {
+                    var fd = new FormData();
+
+                    fd.append(fileKey, blobFile, fileName);
+                    for (var prop in params) {
+                        if(params.hasOwnProperty(prop)) {
+                            fd.append(prop, params[prop]);
+                        }
+                    }
+
+                    var xhr = new XMLHttpRequest();
+                    xhr.open("POST", server);
+                    xhr.onload = function(evt) {
+                        if (xhr.status == 200) {
+                            var result = new FileUploadResult();
+                            result.bytesSent = file.size;
+                            result.responseCode = xhr.status;
+                            result.response = xhr.response;
+                            successCallback(result);
+                        } else if (xhr.status == 404) {
+                            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                        } else {
+                            errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                        }
+                    };
+                    xhr.ontimeout = function(evt) {
+                        errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                    };
+
+                    xhr.send(fd);
+                }
+
+                var bytesPerChunk;
+                if (chunkedMode === true) {
+                    bytesPerChunk = 1024 * 1024; // 1MB chunk sizes.
+                } else {
+                    bytesPerChunk = file.size;
+                }
+                var start = 0;
+                var end = bytesPerChunk;
+                while (start < file.size) {
+                    var chunk = file.webkitSlice(start, end, mimeType);
+                    uploadFile(chunk);
+                    start = end;
+                    end = start + bytesPerChunk;
+                }
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            }
+            );
+        },
+        function(error) {
+            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+        }
+        );
+    },
+
+    download: function(successCallback, errorCallback, args) {
+        var url = args[0],
+            filePath = args[1];
+
+        var xhr = new XMLHttpRequest();
+
+        function writeFile(fileEntry) {
+            fileEntry.createWriter(function(writer) {
+                writer.onwriteend = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(new FileEntry(fileEntry.name, fileEntry.toURL()));
+                    } else {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    }
+                };
+
+                writer.onerror = function(evt) {
+                    errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                };
+
+                var builder = new WebKitBlobBuilder();
+                builder.append(xhr.response);
+                var blob = builder.getBlob();
+                writer.write(blob);
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            });
+        }
+
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == xhr.DONE) {
+                if (xhr.status == 200 && xhr.response) {
+                    nativeResolveLocalFileSystemURI(getParentPath(filePath), function(dir) {
+                        dir.getFile(getFileName(filePath), {create: true}, writeFile, function(error) {
+                            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                        });
+                    }, function(error) {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    });
+                } else if (xhr.status == 404) {
+                    errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                } else {
+                    errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                }
+            }
+        };
+
+        xhr.open("GET", url, true);
+        xhr.responseType = "arraybuffer";
+        xhr.send();
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Media.js
+define("cordova/plugin/tizen/Media", function(require, exports, module) {
+/*global Media:false, webkitURL:false */
+var MediaError = require('cordova/plugin/MediaError'),
+    audioObjects = {};
+
+module.exports = {
+    create: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::create() - id =" + id + ", src =" + src);
+        audioObjects[id] = new Audio(src);
+        audioObjects[id].onStalledCB = function () {
+            console.log("media::onStalled()");
+             audioObjects[id].timer = window.setTimeout(function () {
+                    audioObjects[id].pause();
+                    if (audioObjects[id].currentTime !== 0)
+                        audioObjects[id].currentTime = 0;
+                    console.log("media::onStalled() - MEDIA_ERROR -> " + MediaError.MEDIA_ERR_ABORTED);
+                    var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, "Stalled");
+                    Media.onStatus(id, Media.MEDIA_ERROR, err);
+                }, 2000);
+        };
+        audioObjects[id].onEndedCB = function () {
+            console.log("media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        };
+        audioObjects[id].onErrorCB = function () {
+            console.log("media::onErrorCB() - MEDIA_ERROR -> " + event.srcElement.error);
+            Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error);
+        };
+        audioObjects[id].onPlayCB = function () {
+            console.log("media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
+        };
+        audioObjects[id].onPlayingCB = function () {
+            console.log("media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);
+        };
+        audioObjects[id].onDurationChangeCB = function () {
+            console.log("media::onDurationChangeCB() - MEDIA_DURATION -> " +  audioObjects[id].duration);
+            Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration);
+        };
+        audioObjects[id].onTimeUpdateCB = function () {
+            console.log("media::onTimeUpdateCB() - MEDIA_POSITION -> " +  audioObjects[id].currentTime);
+            Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime);
+        };
+        audioObjects[id].onCanPlayCB = function () {
+            console.log("media::onCanPlayCB()");
+            window.clearTimeout(audioObjects[id].timer);
+            audioObjects[id].play();
+        };
+      },
+    startPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1], options = args[2];
+        console.log("media::startPlayingAudio() - id =" + id + ", src =" + src + ", options =" + options);
+        audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB);
+        audioObjects[id].play();
+    },
+    stopPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        audioObjects[id].pause();
+        if (audioObjects[id].currentTime !== 0)
+            audioObjects[id].currentTime = 0;
+        console.log("media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED");
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB);
+    },
+    seekToAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], milliseconds = args[1];
+        console.log("media::seekToAudio()");
+         audioObjects[id].currentTime = milliseconds;
+        successCallback( audioObjects[id].currentTime);
+    },
+    pausePlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED");
+        audioObjects[id].pause();
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
+    },
+    getCurrentPositionAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::getCurrentPositionAudio()");
+        successCallback(audioObjects[id].currentTime);
+    },
+    release: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        console.log("media::release()");
+    },
+    setVolume: function (successCallback, errorCallback, args) {
+        var id = args[0], volume = args[1];
+        console.log("media::setVolume()");
+        audioObjects[id].volume = volume;
+    },
+    startRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::startRecordingAudio() - id =" + id + ", src =" + src);
+
+        function gotStreamCB(stream) {
+            audioObjects[id].src = webkitURL.createObjectURL(stream);
+            console.log("media::startRecordingAudio() - stream CB");
+        }
+
+        function gotStreamFailedCB(error) {
+            console.log("media::startRecordingAudio() - error CB:" + error.toString());
+        }
+
+        if (navigator.webkitGetUserMedia) {
+            audioObjects[id] = new Audio();
+            navigator.webkitGetUserMedia('audio', gotStreamCB, gotStreamFailedCB);
+        } else {
+            console.log("webkitGetUserMedia not supported");
+        }
+        successCallback();
+    },
+    stopRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::stopRecordingAudio() - id =" + id);
+        audioObjects[id].pause();
+        successCallback();
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/MediaError.js
+define("cordova/plugin/tizen/MediaError", function(require, exports, module) {
+
+// The MediaError object already exists on Tizen. This prevents the Cordova
+// version from being defined. This object is used to merge in differences
+// between Tizen and Cordova MediaError objects.
+module.exports = {
+        MEDIA_ERR_NONE_ACTIVE : 0,
+        MEDIA_ERR_NONE_SUPPORTED : 4
+};
+});
+
+// file: lib/tizen/plugin/tizen/NetworkStatus.js
+define("cordova/plugin/tizen/NetworkStatus", function(require, exports, module) {
+/*global tizen:false */
+var Connection = require('cordova/plugin/Connection');
+
+module.exports = {
+    getConnectionInfo: function (successCallback, errorCallback) {
+        var cncType = Connection.NONE;
+        var infoCount = 0;
+
+        function infoCB() {
+            infoCount++;
+            if (infoCount > 1)
+               successCallback(cncType);
+        }
+
+        function errorCB(error) {
+           console.log("Error: " + error.code + "," + error.name + "," + error.message);
+           infoCB();
+        }
+
+        function wifiSuccessCB(wifi) {
+            if ((wifi.status === "ON")  && (wifi.ipAddress.length !== 0))
+                cncType = Connection.WIFI;
+            infoCB();
+        }
+
+        function cellularSuccessCB(cell) {
+            if ((cncType === Connection.NONE) && (cell.status === "ON") && (cell.ipAddress.length !== 0))
+                cncType = Connection.CELL_2G;
+            infoCB();
+        }
+
+        if (tizen.systeminfo.isSupported('WifiNetwork')) {
+            tizen.systeminfo.getPropertyValue('WifiNetwork', wifiSuccessCB, errorCB);
+        }
+
+        if (tizen.systeminfo.isSupported('CellularNetwork')) {
+            tizen.systeminfo.getPropertyValue('CellularNetwork', cellularSuccessCB, errorCB);
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Notification.js
+define("cordova/plugin/tizen/Notification", function(require, exports, module) {
+var SoundBeat = require('cordova/plugin/tizen/SoundBeat');
+
+/* TODO: get resource path from app environment? */
+var soundBeat = new SoundBeat(["./sounds/beep.wav"]);
+
+module.exports = {
+
+    alert: function(message, alertCallback, title, buttonName) {
+        return this.confirm(message, alertCallback, title, buttonName);
+    },
+
+    confirm: function(message, confirmCallback, title, buttonLabels) {
+        var index            =    null,
+            overlayElement    =    null,
+            popup            =    null,
+            element         =    null,
+            titleString        =     null,
+            messageString    =    null,
+            buttonString    =    null,
+            buttonsArray    =    null;
+
+
+        console.log ("message" , message);
+        console.log ("confirmCallback" , confirmCallback);
+        console.log ("title" , title);
+        console.log ("buttonLabels" , buttonLabels);
+
+        titleString = '<div class="popup-title"><p>' + title + '</p></div>';
+        messageString = '<div class="popup-text"><p>' + message + '</p></div>';
+        buttonString = '<div class="popup-button-bg"><ul>';
+
+        switch(typeof(buttonLabels))
+        {
+        case "string":
+            buttonsArray = buttonLabels.split(",");
+
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+
+        case "array":
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+        default:
+            console.log ("cordova/plugin/tizen/Notification, default, buttonLabels: ", buttonLabels);
+            break;
+        }
+
+        buttonString += '</ul></div>';
+
+        overlayElement = document.createElement("div");
+        overlayElement.className = 'ui-popupwindow-screen';
+
+        overlayElement.style.zIndex = 1001;
+        overlayElement.style.width = "100%";
+        overlayElement.style.height = "100%";
+        overlayElement.style.top = 0;
+        overlayElement.style.left = 0;
+        overlayElement.style.margin = 0;
+        overlayElement.style.padding = 0;
+        overlayElement.style.position = "absolute";
+
+        popup = document.createElement("div");
+        popup.className = "ui-popupwindow";
+        popup.style.position = "fixed";
+        popup.style.zIndex = 1002;
+        popup.innerHTML = titleString + messageString + buttonString;
+
+        document.body.appendChild(overlayElement);
+        document.body.appendChild(popup);
+
+        function createListener(button) {
+            return function() {
+                document.body.removeChild(overlayElement);
+                document.body.removeChild(popup);
+                confirmCallback(button.value);
+            };
+        }
+
+       for (index in buttonsArray) {
+           console.log ("index: ", index);
+
+           element = document.getElementById("popup-button-" + buttonsArray[index]);
+           element.addEventListener("click", createListener(element), false);
+       }
+    },
+
+    vibrate: function(milliseconds) {
+        console.log ("milliseconds" , milliseconds);
+
+        if (navigator.vibrate) {
+            navigator.vibrate(milliseconds);
+        }
+        else {
+            console.log ("cordova/plugin/tizen/Notification, vibrate API does not exists");
+        }
+    },
+
+    beep: function(count) {
+        console.log ("count" , count);
+        soundBeat.play(count);
+    }
+};
+
+
+
+});
+
+// file: lib/tizen/plugin/tizen/SoundBeat.js
+define("cordova/plugin/tizen/SoundBeat", function(require, exports, module) {
+/*global webkitAudioContext:false */
+/*
+ *  SoundBeat
+ * used by Notification Manager beep method
+ *
+ * This class provides sounds play
+ *
+ * uses W3C  Web Audio API
+ * uses BufferLoader object
+ *
+ * NOTE: the W3C Web Audio doc tells we do not need to recreate the audio
+ *       context to play a sound but only the audiosourcenode (createBufferSource)
+ *       in the webkit implementation we have to.
+ *
+ */
+
+var BufferLoader = require('cordova/plugin/tizen/BufferLoader');
+
+function SoundBeat(urlList) {
+    this.context = null;
+    this.urlList = urlList || null;
+    this.buffers = null;
+}
+
+/*
+ * This method play a loaded sounds on the Device
+ * @param {Number} times Number of times to play loaded sounds.
+ *
+ */
+SoundBeat.prototype.play = function(times) {
+
+    var i = 0, sources = [], that = this;
+
+    function finishedLoading (bufferList) {
+        that.buffers = bufferList;
+
+        for (i = 0; i < that.buffers.length ; i +=1) {
+            if (that.context) {
+                sources[i] = that.context.createBufferSource();
+
+                sources[i].buffer = that.buffers[i];
+                sources[i].connect (that.context.destination);
+
+                sources[i].loop = true;
+                sources[i].noteOn (0);
+                sources[i].noteOff(sources[i].buffer.duration * times);
+            }
+        }
+    }
+
+    if (webkitAudioContext !== null) {
+        this.context = new webkitAudioContext();
+    }
+    else {
+        console.log ("SoundBeat.prototype.play, w3c web audio api not supported");
+        this.context = null;
+    }
+
+    if (this.context === null) {
+        console.log ("SoundBeat.prototype.play, cannot create audio context object");
+        return;
+    }
+
+    this.bufferLoader = new BufferLoader (this.context, this.urlList, finishedLoading);
+    if (this.bufferLoader === null) {
+        console.log ("SoundBeat.prototype.play, cannot create buffer loader object");
+        return;
+    }
+
+    this.bufferLoader.load();
+};
+
+module.exports = SoundBeat;
+
+});
+
+// file: lib/tizen/plugin/tizen/contacts.js
+define("cordova/plugin/tizen/contacts", function(require, exports, module) {
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils');
+
+module.exports = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     *
+     * @return array of Contacts matching search criteria
+     */
+    find : function(fields, successCB, failCB, options) {
+
+        // Success callback is required. Throw exception if not specified.
+        if (typeof successCB !== 'function') {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+
+        // Search qualifier is required and cannot be empty.
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+            return;
+        }
+
+        // options are optional
+        var filter ="",
+            multiple = false,
+            contacts = [],
+            tizenFilter = null;
+
+        if (options) {
+            filter = options.filter || "";
+            multiple =  options.multiple || false;
+        }
+
+        if (filter){
+            tizenFilter = ContactUtils.buildFilterExpression(fields, filter);
+        }
+
+        tizen.contact.getDefaultAddressBook().find(
+            function(tizenContacts) {
+                if (multiple) {
+                    for (var index in tizenContacts) {
+                        contacts.push(ContactUtils.createContact(tizenContacts[index], fields));
+                    }
+                }
+                else {
+                    contacts.push(ContactUtils.createContact(tizenContacts[0], fields));
+                }
+
+                // return results
+                successCB(contacts);
+            },
+            function(error) {
+                if (typeof failCB === 'function') {
+                    failCB(ContactError.UNKNOWN_ERROR);
+                }
+            },
+            tizenFilter,
+            null);
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/manager.js
+define("cordova/plugin/tizen/manager", function(require, exports, module) {
+var cordova = require('cordova');
+
+module.exports = {
+    exec: function (successCallback, errorCallback, clazz, action, args) {
+        var plugin = require('cordova/plugin/tizen/' + clazz);
+
+        if (plugin && typeof plugin[action] === 'function') {
+            var result = plugin[action](successCallback, errorCallback, args);
+            return result || {status: cordova.callbackStatus.NO_RESULT};
+        }
+
+        return {"status" : cordova.callbackStatus.CLASS_NOT_FOUND_EXCEPTION, "message" : "Function " + clazz + "::" + action + " cannot be found"};
+    },
+    resume: function () {},
+    pause: function () {},
+    destroy: function () {}
+};
+
+});
+
+// file: lib/common/utils.js
+define("cordova/utils", function(require, exports, module) {
+var utils = exports;
+
+/**
+ * Returns an indication of whether the argument is an array or not
+ */
+utils.isArray = function(a) {
+    return Object.prototype.toString.call(a) == '[object Array]';
+};
+
+/**
+ * Returns an indication of whether the argument is a Date or not
+ */
+utils.isDate = function(d) {
+    return Object.prototype.toString.call(d) == '[object Date]';
+};
+
+/**
+ * Does a deep clone of the object.
+ */
+utils.clone = function(obj) {
+    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
+        return obj;
+    }
+
+    var retVal, i;
+
+    if(utils.isArray(obj)){
+        retVal = [];
+        for(i = 0; i < obj.length; ++i){
+            retVal.push(utils.clone(obj[i]));
+        }
+        return retVal;
+    }
+
+    retVal = {};
+    for(i in obj){
+        if(!(i in retVal) || retVal[i] != obj[i]) {
+            retVal[i] = utils.clone(obj[i]);
+        }
+    }
+    return retVal;
+};
+
+/**
+ * Returns a wrappered version of the function
+ */
+utils.close = function(context, func, params) {
+    if (typeof params == 'undefined') {
+        return function() {
+            return func.apply(context, arguments);
+        };
+    } else {
+        return function() {
+            return func.apply(context, params);
+        };
+    }
+};
+
+/**
+ * Create a UUID
+ */
+utils.createUUID = function() {
+    return UUIDcreatePart(4) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(6);
+};
+
+/**
+ * Extends a child object from a parent object using classical inheritance
+ * pattern.
+ */
+utils.extend = (function() {
+    // proxy used to establish prototype chain
+    var F = function() {};
+    // extend Child from Parent
+    return function(Child, Parent) {
+        F.prototype = Parent.prototype;
+        Child.prototype = new F();
+        Child.__super__ = Parent.prototype;
+        Child.prototype.constructor = Child;
+    };
+}());
+
+/**
+ * Alerts a message in any available way: alert or console.log.
+ */
+utils.alert = function(msg) {
+    if (alert) {
+        alert(msg);
+    } else if (console && console.log) {
+        console.log(msg);
+    }
+};
+
+/**
+ * Formats a string and arguments following it ala sprintf()
+ *
+ * see utils.vformat() for more information
+ */
+utils.format = function(formatString /* ,... */) {
+    var args = [].slice.call(arguments, 1);
+    return utils.vformat(formatString, args);
+};
+
+/**
+ * Formats a string and arguments following it ala vsprintf()
+ *
+ * format chars:
+ *   %j - format arg as JSON
+ *   %o - format arg as JSON
+ *   %c - format arg as ''
+ *   %% - replace with '%'
+ * any other char following % will format it's
+ * arg via toString().
+ *
+ * for rationale, see FireBug's Console API:
+ *    http://getfirebug.com/wiki/index.php/Console_API
+ */
+utils.vformat = function(formatString, args) {
+    if (formatString === null || formatString === undefined) return "";
+    if (arguments.length == 1) return formatString.toString();
+    if (typeof formatString != "string") return formatString.toString();
+
+    var pattern = /(.*?)%(.)(.*)/;
+    var rest    = formatString;
+    var result  = [];
+
+    while (args.length) {
+        var arg   = args.shift();
+        var match = pattern.exec(rest);
+
+        if (!match) break;
+
+        rest = match[3];
+
+        result.push(match[1]);
+
+        if (match[2] == '%') {
+            result.push('%');
+            args.unshift(arg);
+            continue;
+        }
+
+        result.push(formatted(arg, match[2]));
+    }
+
+    result.push(rest);
+
+    return result.join('');
+};
+
+//------------------------------------------------------------------------------
+function UUIDcreatePart(length) {
+    var uuidpart = "";
+    for (var i=0; i<length; i++) {
+        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
+        if (uuidchar.length == 1) {
+            uuidchar = "0" + uuidchar;
+        }
+        uuidpart += uuidchar;
+    }
+    return uuidpart;
+}
+
+//------------------------------------------------------------------------------
+function formatted(object, formatChar) {
+
+    try {
+        switch(formatChar) {
+            case 'j':
+            case 'o': return JSON.stringify(object);
+            case 'c': return '';
+        }
+    }
+    catch (e) {
+        return "error JSON.stringify()ing argument: " + e;
+    }
+
+    if ((object === null) || (object === undefined)) {
+        return Object.prototype.toString.call(object);
+    }
+
+    return object.toString();
+}
+
+});
+
+
+window.cordova = require('cordova');
+
+// file: lib/scripts/bootstrap.js
+(function (context) {
+    var channel = require("cordova/channel"),
+        _self = {
+            boot: function () {
+                /**
+                 * Create all cordova objects once page has fully loaded and native side is ready.
+                 */
+                channel.join(function() {
+                    var builder = require('cordova/builder'),
+                        base = require('cordova/common'),
+                        platform = require('cordova/platform');
+
+                    // Drop the common globals into the window object, but be nice and don't overwrite anything.
+                    builder.build(base.objects).intoButDontClobber(window);
+
+                    // Drop the platform-specific globals into the window object
+                    // and clobber any existing object.
+                    builder.build(platform.objects).intoAndClobber(window);
+
+                    // Merge the platform-specific overrides/enhancements into
+                    // the window object.
+                    if (typeof platform.merges !== 'undefined') {
+                        builder.build(platform.merges).intoAndMerge(window);
+                    }
+
+                    // Call the platform-specific initialization
+                    platform.initialize();
+
+                    // Fire event to notify that all objects are created
+                    channel.onCordovaReady.fire();
+
+                    // Fire onDeviceReady event once all constructors have run and
+                    // cordova info has been received from native side.
+                    channel.join(function() {
+                        require('cordova').fireDocumentEvent('deviceready');
+                    }, channel.deviceReadyChannelsArray);
+
+                }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);
+            }
+        };
+
+    // boot up once native side is ready
+    channel.onNativeReady.subscribeOnce(_self.boot);
+
+    // _nativeReady is global variable that the native side can set
+    // to signify that the native code is ready. It is a global since
+    // it may be called before any cordova JS is ready.
+    if (window._nativeReady) {
+        channel.onNativeReady.fire();
+    }
+
+}(window));
+
+// file: lib/scripts/bootstrap-tizen.js
+require('cordova/channel').onNativeReady.fire();
+
+
+})();
\ No newline at end of file
diff --git a/js/native.js b/js/native.js
new file mode 100644
index 0000000..62fb3d7
--- /dev/null
+++ b/js/native.js
@@ -0,0 +1,9 @@
+/*
+ * No real native code
+ */
+
+/* Needed for File API implementation */
+window.webkitFileReader = window.FileReader;
+
+window._nativeReady = true;
+
diff --git a/lib/cordova.js b/lib/cordova.js
new file mode 100644
index 0000000..04a0a99
--- /dev/null
+++ b/lib/cordova.js
@@ -0,0 +1,7075 @@
+/*
+ * No real native code
+ */
+
+/* Needed for File API implementation */
+window.webkitFileReader = window.FileReader;
+
+window._nativeReady = true;
+
+// commit 7dd17b00544742d14ecdeff2148a66480680f12b
+
+// File generated at :: Thu Jul 26 2012 17:32:56 GMT+0200 (CEST)
+
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+ 
+     http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+;(function() {
+
+// file: lib/scripts/require.js
+var require,
+    define;
+
+(function () {
+    var modules = {};
+
+    function build(module) {
+        var factory = module.factory;
+        module.exports = {};
+        delete module.factory;
+        factory(require, module.exports, module);
+        return module.exports;
+    }
+
+    require = function (id) {
+        if (!modules[id]) {
+            throw "module " + id + " not found";
+        }
+        return modules[id].factory ? build(modules[id]) : modules[id].exports;
+    };
+
+    define = function (id, factory) {
+        if (modules[id]) {
+            throw "module " + id + " already defined";
+        }
+
+        modules[id] = {
+            id: id,
+            factory: factory
+        };
+    };
+
+    define.remove = function (id) {
+        delete modules[id];
+    };
+
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+    module.exports.require = require;
+    module.exports.define = define;
+}
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+var channel = require('cordova/channel');
+
+/**
+ * Listen for DOMContentLoaded and notify our channel subscribers.
+ */
+document.addEventListener('DOMContentLoaded', function() {
+    channel.onDOMContentLoaded.fire();
+}, false);
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+    channel.onDOMContentLoaded.fire();
+}
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+    windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof documentEventHandlers[e] != 'undefined') {
+        if (evt === 'deviceready') {
+            documentEventHandlers[e].subscribeOnce(handler);
+        } else {
+            documentEventHandlers[e].subscribe(handler);
+        }
+    } else {
+        m_document_addEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof windowEventHandlers[e] != 'undefined') {
+        windowEventHandlers[e].subscribe(handler);
+    } else {
+        m_window_addEventListener.call(window, evt, handler, capture);
+    }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof documentEventHandlers[e] != "undefined") {
+        documentEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_document_removeEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubcribing from an event that is handled by a plugin
+    if (typeof windowEventHandlers[e] != "undefined") {
+        windowEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_window_removeEventListener.call(window, evt, handler, capture);
+    }
+};
+
+function createEvent(type, data) {
+    var event = document.createEvent('Events');
+    event.initEvent(type, false, false);
+    if (data) {
+        for (var i in data) {
+            if (data.hasOwnProperty(i)) {
+                event[i] = data[i];
+            }
+        }
+    }
+    return event;
+}
+
+if(typeof window.console === "undefined") {
+    window.console = {
+        log:function(){}
+    };
+}
+
+var cordova = {
+    define:define,
+    require:require,
+    /**
+     * Methods to add/remove your own addEventListener hijacking on document + window.
+     */
+    addWindowEventHandler:function(event, opts) {
+        return (windowEventHandlers[event] = channel.create(event, opts));
+    },
+    addDocumentEventHandler:function(event, opts) {
+        return (documentEventHandlers[event] = channel.create(event, opts));
+    },
+    removeWindowEventHandler:function(event) {
+        delete windowEventHandlers[event];
+    },
+    removeDocumentEventHandler:function(event) {
+        delete documentEventHandlers[event];
+    },
+    /**
+     * Retreive original event handlers that were replaced by Cordova
+     *
+     * @return object
+     */
+    getOriginalHandlers: function() {
+        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+    },
+    /**
+     * Method to fire event from native code
+     */
+    fireDocumentEvent: function(type, data) {
+        var evt = createEvent(type, data);
+        if (typeof documentEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                documentEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            document.dispatchEvent(evt);
+        }
+    },
+    fireWindowEvent: function(type, data) {
+        var evt = createEvent(type,data);
+        if (typeof windowEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                windowEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            window.dispatchEvent(evt);
+        }
+    },
+    // TODO: this is Android only; think about how to do this better
+    shuttingDown:false,
+    UsePolling:false,
+    // END TODO
+
+    // TODO: iOS only
+    // This queue holds the currently executing command and all pending
+    // commands executed with cordova.exec().
+    commandQueue:[],
+    // Indicates if we're currently in the middle of flushing the command
+    // queue on the native side.
+    commandQueueFlushing:false,
+    // END TODO
+    /**
+     * Plugin callback mechanism.
+     */
+    callbackId: 0,
+    callbacks:  {},
+    callbackStatus: {
+        NO_RESULT: 0,
+        OK: 1,
+        CLASS_NOT_FOUND_EXCEPTION: 2,
+        ILLEGAL_ACCESS_EXCEPTION: 3,
+        INSTANTIATION_EXCEPTION: 4,
+        MALFORMED_URL_EXCEPTION: 5,
+        IO_EXCEPTION: 6,
+        INVALID_ACTION: 7,
+        JSON_EXCEPTION: 8,
+        ERROR: 9
+    },
+
+    /**
+     * Called by native code when returning successful result from an action.
+     *
+     * @param callbackId
+     * @param args
+     */
+    callbackSuccess: function(callbackId, args) {
+        if (cordova.callbacks[callbackId]) {
+
+            // If result is to be sent to callback
+            if (args.status == cordova.callbackStatus.OK) {
+                try {
+                    if (cordova.callbacks[callbackId].success) {
+                        cordova.callbacks[callbackId].success(args.message);
+                    }
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+callbackId+" = "+e);
+                }
+            }
+
+            // Clear callback if not expecting any more results
+            if (!args.keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+
+    /**
+     * Called by native code when returning error result from an action.
+     *
+     * @param callbackId
+     * @param args
+     */
+    callbackError: function(callbackId, args) {
+        if (cordova.callbacks[callbackId]) {
+            try {
+                if (cordova.callbacks[callbackId].fail) {
+                    cordova.callbacks[callbackId].fail(args.message);
+                }
+            }
+            catch (e) {
+                console.log("Error in error callback: "+callbackId+" = "+e);
+            }
+
+            // Clear callback if not expecting any more results
+            if (!args.keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+    addConstructor: function(func) {
+        channel.onCordovaReady.subscribeOnce(function() {
+            try {
+                func();
+            } catch(e) {
+                console.log("Failed to run constructor: " + e);
+            }
+        });
+    }
+};
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addDocumentEventHandler('deviceready');
+
+module.exports = cordova;
+
+});
+
+// file: lib/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+    for (var prop in objects) {
+        if (objects.hasOwnProperty(prop)) {
+            func.apply(context, [objects[prop], prop]);
+        }
+    }
+}
+
+function include(parent, objects, clobber, merge) {
+    each(objects, function (obj, key) {
+        try {
+          var result = obj.path ? require(obj.path) : {};
+
+          if (clobber) {
+              // Clobber if it doesn't exist.
+              if (typeof parent[key] === 'undefined') {
+                  parent[key] = result;
+              } else if (typeof obj.path !== 'undefined') {
+                  // If merging, merge properties onto parent, otherwise, clobber.
+                  if (merge) {
+                      recursiveMerge(parent[key], result);
+                  } else {
+                      parent[key] = result;
+                  }
+              }
+              result = parent[key];
+          } else {
+            // Overwrite if not currently defined.
+            if (typeof parent[key] == 'undefined') {
+              parent[key] = result;
+            } else if (merge && typeof obj.path !== 'undefined') {
+              // If merging, merge parent onto result
+              recursiveMerge(result, parent[key]);
+              parent[key] = result;
+            } else {
+              // Set result to what already exists, so we can build children into it if they exist.
+              result = parent[key];
+            }
+          }
+
+          if (obj.children) {
+            include(result, obj.children, clobber, merge);
+          }
+        } catch(e) {
+          utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+        }
+    });
+}
+
+/**
+ * Merge properties from one object onto another recursively.  Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+    for (var prop in src) {
+        if (src.hasOwnProperty(prop)) {
+            if (typeof target.prototype !== 'undefined' && target.prototype.constructor === target) {
+                // If the target object is a constructor override off prototype.
+                target.prototype[prop] = src[prop];
+            } else {
+                target[prop] = typeof src[prop] === 'object' ? recursiveMerge(
+                        target[prop], src[prop]) : src[prop];
+            }
+        }
+    }
+    return target;
+}
+
+module.exports = {
+    build: function (objects) {
+        return {
+            intoButDontClobber: function (target) {
+                include(target, objects, false, false);
+            },
+            intoAndClobber: function(target) {
+                include(target, objects, true, false);
+            },
+            intoAndMerge: function(target) {
+                include(target, objects, true, true);
+            }
+        };
+    }
+};
+
+});
+
+// file: lib/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+var utils = require('cordova/utils');
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded         Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady              Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady             Internal event fired when all Cordova JavaScript objects have been created.
+ * onCordovaInfoReady         Internal event fired when device properties are available.
+ * onCordovaConnectionReady   Internal event fired when the connection property has been set.
+ * onDeviceReady              User event fired to indicate that Cordova is ready
+ * onResume                   User event fired to indicate a start/resume lifecycle event
+ * onPause                    User event fired to indicate a pause lifecycle event
+ * onDestroy                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The only Cordova events that user code should register for are:
+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ *      pause                 App has moved to background
+ *      resume                App has returned to foreground
+ *
+ * Listeners can be registered as:
+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);
+ *      document.addEventListener("resume", myResumeListener, false);
+ *      document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ *      window.onload
+ *      window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type  String the channel name
+ * @param opts  Object options to pass into the channel, currently
+ *                     supports:
+ *                     onSubscribe: callback that fires when
+ *                       something subscribes to the Channel. Sets
+ *                       context to the Channel.
+ *                     onUnsubscribe: callback that fires when
+ *                       something unsubscribes to the Channel. Sets
+ *                       context to the Channel.
+ */
+var Channel = function(type, opts) {
+    this.type = type;
+    this.handlers = {};
+    this.numHandlers = 0;
+    this.guid = 1;
+    this.fired = false;
+    this.enabled = true;
+    this.events = {
+        onSubscribe:null,
+        onUnsubscribe:null
+    };
+    if (opts) {
+        if (opts.onSubscribe) this.events.onSubscribe = opts.onSubscribe;
+        if (opts.onUnsubscribe) this.events.onUnsubscribe = opts.onUnsubscribe;
+    }
+},
+    channel = {
+        /**
+         * Calls the provided function only after all of the channels specified
+         * have been fired.
+         */
+        join: function (h, c) {
+            var i = c.length;
+            var len = i;
+            var f = function() {
+                if (!(--i)) h();
+            };
+            for (var j=0; j<len; j++) {
+                !c[j].fired?c[j].subscribeOnce(f):i--;
+            }
+            if (!i) h();
+        },
+        create: function (type, opts) {
+            channel[type] = new Channel(type, opts);
+            return channel[type];
+        },
+
+        /**
+         * cordova Channels that must fire before "deviceready" is fired.
+         */
+        deviceReadyChannelsArray: [],
+        deviceReadyChannelsMap: {},
+
+        /**
+         * Indicate that a feature needs to be initialized before it is ready to be used.
+         * This holds up Cordova's "deviceready" event until the feature has been initialized
+         * and Cordova.initComplete(feature) is called.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        waitForInitialization: function(feature) {
+            if (feature) {
+                var c = null;
+                if (this[feature]) {
+                    c = this[feature];
+                }
+                else {
+                    c = this.create(feature);
+                }
+                this.deviceReadyChannelsMap[feature] = c;
+                this.deviceReadyChannelsArray.push(c);
+            }
+        },
+
+        /**
+         * Indicate that initialization code has completed and the feature is ready to be used.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        initializationComplete: function(feature) {
+            var c = this.deviceReadyChannelsMap[feature];
+            if (c) {
+                c.fire();
+            }
+        }
+    };
+
+function forceFunction(f) {
+    if (f === null || f === undefined || typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c, g) {
+    // need a function to call
+    forceFunction(f);
+
+    var func = f;
+    if (typeof c == "object") { func = utils.close(c, f); }
+
+    g = g || func.observer_guid || f.observer_guid;
+    if (!g) {
+        // first time we've seen this subscriber
+        g = this.guid++;
+    }
+    else {
+        // subscriber already handled; dont set it twice
+        return g;
+    }
+    func.observer_guid = g;
+    f.observer_guid = g;
+    this.handlers[g] = func;
+    this.numHandlers++;
+    if (this.events.onSubscribe) this.events.onSubscribe.call(this);
+    if (this.fired) func.call(this);
+    return g;
+};
+
+/**
+ * Like subscribe but the function is only called once and then it
+ * auto-unsubscribes itself.
+ */
+Channel.prototype.subscribeOnce = function(f, c) {
+    // need a function to call
+    forceFunction(f);
+
+    var g = null;
+    var _this = this;
+    var m = function() {
+        f.apply(c || null, arguments);
+        _this.unsubscribe(g);
+    };
+    if (this.fired) {
+        if (typeof c == "object") { f = utils.close(c, f); }
+        f.apply(this, this.fireArgs);
+    } else {
+        g = this.subscribe(m);
+    }
+    return g;
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(g) {
+    // need a function to unsubscribe
+    if (g === null || g === undefined) { throw "You must pass _something_ into Channel.unsubscribe"; }
+
+    if (typeof g == 'function') { g = g.observer_guid; }
+    var handler = this.handlers[g];
+    if (handler) {
+        if (handler.observer_guid) handler.observer_guid=null;
+        this.handlers[g] = null;
+        delete this.handlers[g];
+        this.numHandlers--;
+        if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);
+    }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+    if (this.enabled) {
+        var fail = false;
+        this.fired = true;
+        for (var item in this.handlers) {
+            var handler = this.handlers[item];
+            if (typeof handler == 'function') {
+                var rv = (handler.apply(this, arguments)===false);
+                fail = fail || rv;
+            }
+        }
+        this.fireArgs = arguments;
+        return !fail;
+    }
+    return true;
+};
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.create('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.create('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.create('onCordovaReady');
+
+// Event to indicate that device properties are available
+channel.create('onCordovaInfoReady');
+
+// Event to indicate that the connection property has been set.
+channel.create('onCordovaConnectionReady');
+
+// Event to indicate that Cordova is ready
+channel.create('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.create('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onCordovaConnectionReady');
+
+module.exports = channel;
+
+});
+
+// file: lib/common/common.js
+define("cordova/common", function(require, exports, module) {
+module.exports = {
+    objects: {
+        cordova: {
+            path: 'cordova',
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                },
+                logger: {
+                    path: 'cordova/plugin/logger'
+                }
+            }
+        },
+        Cordova: {
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                }
+            }
+        },
+        PhoneGap:{
+            children: {
+                exec: {
+                    path: 'cordova/exec'
+                }
+            }
+        },
+        navigator: {
+            children: {
+                notification: {
+                    path: 'cordova/plugin/notification'
+                },
+                accelerometer: {
+                    path: 'cordova/plugin/accelerometer'
+                },
+                battery: {
+                    path: 'cordova/plugin/battery'
+                },
+                camera:{
+                    path: 'cordova/plugin/Camera'
+                },
+                compass:{
+                    path: 'cordova/plugin/compass'
+                },
+                contacts: {
+                    path: 'cordova/plugin/contacts'
+                },
+                device:{
+                    children:{
+                        capture: {
+                            path: 'cordova/plugin/capture'
+                        }
+                    }
+                },
+                geolocation: {
+                    path: 'cordova/plugin/geolocation'
+                },
+                network: {
+                    children: {
+                        connection: {
+                            path: 'cordova/plugin/network'
+                        }
+                    }
+                },
+                splashscreen: {
+                    path: 'cordova/plugin/splashscreen'
+                }
+            }
+        },
+        Acceleration: {
+            path: 'cordova/plugin/Acceleration'
+        },
+        Camera:{
+            path: 'cordova/plugin/CameraConstants'
+        },
+        CameraPopoverOptions: {
+            path: 'cordova/plugin/CameraPopoverOptions'
+        },
+        CaptureError: {
+            path: 'cordova/plugin/CaptureError'
+        },
+        CaptureAudioOptions:{
+            path: 'cordova/plugin/CaptureAudioOptions'
+        },
+        CaptureImageOptions: {
+            path: 'cordova/plugin/CaptureImageOptions'
+        },
+        CaptureVideoOptions: {
+            path: 'cordova/plugin/CaptureVideoOptions'
+        },
+        CompassHeading:{
+            path: 'cordova/plugin/CompassHeading'
+        },
+        CompassError:{
+            path: 'cordova/plugin/CompassError'
+        },
+        ConfigurationData: {
+            path: 'cordova/plugin/ConfigurationData'
+        },
+        Connection: {
+            path: 'cordova/plugin/Connection'
+        },
+        Contact: {
+            path: 'cordova/plugin/Contact'
+        },
+        ContactAddress: {
+            path: 'cordova/plugin/ContactAddress'
+        },
+        ContactError: {
+            path: 'cordova/plugin/ContactError'
+        },
+        ContactField: {
+            path: 'cordova/plugin/ContactField'
+        },
+        ContactFindOptions: {
+            path: 'cordova/plugin/ContactFindOptions'
+        },
+        ContactName: {
+            path: 'cordova/plugin/ContactName'
+        },
+        ContactOrganization: {
+            path: 'cordova/plugin/ContactOrganization'
+        },
+        Coordinates: {
+            path: 'cordova/plugin/Coordinates'
+        },
+        device: {
+            path: 'cordova/plugin/device'
+        },
+        DirectoryEntry: {
+            path: 'cordova/plugin/DirectoryEntry'
+        },
+        DirectoryReader: {
+            path: 'cordova/plugin/DirectoryReader'
+        },
+        Entry: {
+            path: 'cordova/plugin/Entry'
+        },
+        File: {
+            path: 'cordova/plugin/File'
+        },
+        FileEntry: {
+            path: 'cordova/plugin/FileEntry'
+        },
+        FileError: {
+            path: 'cordova/plugin/FileError'
+        },
+        FileReader: {
+            path: 'cordova/plugin/FileReader'
+        },
+        FileSystem: {
+            path: 'cordova/plugin/FileSystem'
+        },
+        FileTransfer: {
+            path: 'cordova/plugin/FileTransfer'
+        },
+        FileTransferError: {
+            path: 'cordova/plugin/FileTransferError'
+        },
+        FileUploadOptions: {
+            path: 'cordova/plugin/FileUploadOptions'
+        },
+        FileUploadResult: {
+            path: 'cordova/plugin/FileUploadResult'
+        },
+        FileWriter: {
+            path: 'cordova/plugin/FileWriter'
+        },
+        Flags: {
+            path: 'cordova/plugin/Flags'
+        },
+        LocalFileSystem: {
+            path: 'cordova/plugin/LocalFileSystem'
+        },
+        Media: {
+            path: 'cordova/plugin/Media'
+        },
+        MediaError: {
+            path: 'cordova/plugin/MediaError'
+        },
+        MediaFile: {
+            path: 'cordova/plugin/MediaFile'
+        },
+        MediaFileData:{
+            path: 'cordova/plugin/MediaFileData'
+        },
+        Metadata:{
+            path: 'cordova/plugin/Metadata'
+        },
+        Position: {
+            path: 'cordova/plugin/Position'
+        },
+        PositionError: {
+            path: 'cordova/plugin/PositionError'
+        },
+        ProgressEvent: {
+            path: 'cordova/plugin/ProgressEvent'
+        },
+        requestFileSystem:{
+            path: 'cordova/plugin/requestFileSystem'
+        },
+        resolveLocalFileSystemURI:{
+            path: 'cordova/plugin/resolveLocalFileSystemURI'
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/exec.js
+define("cordova/exec", function(require, exports, module) {
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchrounous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} successCB  The success callback
+ * @param {Function} failCB     The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ */
+
+var tizen = require('cordova/plugin/tizen/manager'),
+    cordova = require('cordova'),
+    utils = require('cordova/utils');
+
+module.exports = function(successCB, failCB, service, action, args) {
+
+    try {
+        var v = tizen.exec(successCB, failCB, service, action, args);
+
+        // If status is OK, then return value back to caller
+        if (v.status == cordova.callbackStatus.OK) {
+
+            // If there is a success callback, then call it now with returned value
+            if (successCB) {
+                try {
+                    successCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in success callback: "+ service + "." + action + " = " + e);
+                }
+
+            }
+            return v.message;
+        } else if (v.status == cordova.callbackStatus.NO_RESULT) {
+            // Nothing to do here
+        } else {
+            // If error, then display error
+            console.log("Error: " + service + "." + action + " Status=" + v.status + " Message=" + v.message);
+
+            // If there is a fail callback, then call it now with returned value
+            if (failCB) {
+                try {
+                    failCB(v.message);
+                }
+                catch (e) {
+                    console.log("Error in error callback: " + service + "." + action + " = "+e);
+                }
+            }
+            return null;
+        }
+    } catch (e) {
+        utils.alert("Error: " + e);
+    }
+};
+
+});
+
+// file: lib/tizen/platform.js
+define("cordova/platform", function(require, exports, module) {
+module.exports = {
+    id: "tizen",
+    initialize: function() {},
+    objects: {
+        device: {
+            path: "cordova/plugin/tizen/Device"
+        },
+        File: { // exists natively, override
+            path: "cordova/plugin/File"
+        },
+        FileReader: { // exists natively, override
+            path: "cordova/plugin/FileReader"
+        },
+        FileError: { //exists natively, override
+            path: "cordova/plugin/FileError"
+        }
+    },
+    merges: {
+        MediaError: { // exists natively
+            path: "cordova/plugin/tizen/MediaError"
+        },
+        navigator: {
+            children: {
+                device: {
+                    path: "cordova/plugin/tizen/Device"
+                },
+                contacts: {
+                    path: "cordova/plugin/tizen/contacts"
+                },
+               notification: {
+                   path: "cordova/plugin/tizen/Notification"
+               }
+            }
+        },
+        Contact: {
+            path: "cordova/plugin/tizen/Contact"
+        }
+    }
+};
+
+});
+
+// file: lib/common/plugin/Acceleration.js
+define("cordova/plugin/Acceleration", function(require, exports, module) {
+var Acceleration = function(x, y, z, timestamp) {
+    this.x = x;
+    this.y = y;
+    this.z = z;
+    this.timestamp = timestamp || (new Date()).getTime();
+};
+
+module.exports = Acceleration;
+
+});
+
+// file: lib/common/plugin/Camera.js
+define("cordova/plugin/Camera", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    Camera = require('cordova/plugin/CameraConstants');
+
+var cameraExport = {};
+
+// Tack on the Camera Constants to the base camera plugin.
+for (var key in Camera) {
+    cameraExport[key] = Camera[key];
+}
+
+/**
+ * Gets a picture from source defined by "options.sourceType", and returns the
+ * image as defined by the "options.destinationType" option.
+
+ * The defaults are sourceType=CAMERA and destinationType=FILE_URI.
+ *
+ * @param {Function} successCallback
+ * @param {Function} errorCallback
+ * @param {Object} options
+ */
+cameraExport.getPicture = function(successCallback, errorCallback, options) {
+    // successCallback required
+    if (typeof successCallback != "function") {
+        console.log("Camera Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback != "function")) {
+        console.log("Camera Error: errorCallback is not a function");
+        return;
+    }
+
+    var quality = 50;
+    if (options && typeof options.quality == "number") {
+        quality = options.quality;
+    } else if (options && typeof options.quality == "string") {
+        var qlity = parseInt(options.quality, 10);
+        if (isNaN(qlity) === false) {
+            quality = qlity.valueOf();
+        }
+    }
+
+    var destinationType = Camera.DestinationType.FILE_URI;
+    if (typeof options.destinationType == "number") {
+        destinationType = options.destinationType;
+    }
+
+    var sourceType = Camera.PictureSourceType.CAMERA;
+    if (typeof options.sourceType == "number") {
+        sourceType = options.sourceType;
+    }
+
+    var targetWidth = -1;
+    if (typeof options.targetWidth == "number") {
+        targetWidth = options.targetWidth;
+    } else if (typeof options.targetWidth == "string") {
+        var width = parseInt(options.targetWidth, 10);
+        if (isNaN(width) === false) {
+            targetWidth = width.valueOf();
+        }
+    }
+
+    var targetHeight = -1;
+    if (typeof options.targetHeight == "number") {
+        targetHeight = options.targetHeight;
+    } else if (typeof options.targetHeight == "string") {
+        var height = parseInt(options.targetHeight, 10);
+        if (isNaN(height) === false) {
+            targetHeight = height.valueOf();
+        }
+    }
+
+    var encodingType = Camera.EncodingType.JPEG;
+    if (typeof options.encodingType == "number") {
+        encodingType = options.encodingType;
+    }
+
+    var mediaType = Camera.MediaType.PICTURE;
+    if (typeof options.mediaType == "number") {
+        mediaType = options.mediaType;
+    }
+    var allowEdit = false;
+    if (typeof options.allowEdit == "boolean") {
+        allowEdit = options.allowEdit;
+    } else if (typeof options.allowEdit == "number") {
+        allowEdit = options.allowEdit <= 0 ? false : true;
+    }
+    var correctOrientation = false;
+    if (typeof options.correctOrientation == "boolean") {
+        correctOrientation = options.correctOrientation;
+    } else if (typeof options.correctOrientation == "number") {
+        correctOrientation = options.correctOrientation <=0 ? false : true;
+    }
+    var saveToPhotoAlbum = false;
+    if (typeof options.saveToPhotoAlbum == "boolean") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum;
+    } else if (typeof options.saveToPhotoAlbum == "number") {
+        saveToPhotoAlbum = options.saveToPhotoAlbum <=0 ? false : true;
+    }
+    var popoverOptions = null;
+    if (typeof options.popoverOptions == "object") {
+        popoverOptions = options.popoverOptions;
+    }
+
+    var args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
+                mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions];
+
+    exec(successCallback, errorCallback, "Camera", "takePicture", args);
+};
+
+cameraExport.cleanup = function(successCallback, errorCallback) {
+    exec(successCallback, errorCallback, "Camera", "cleanup", []);
+};
+
+module.exports = cameraExport;
+});
+
+// file: lib/common/plugin/CameraConstants.js
+define("cordova/plugin/CameraConstants", function(require, exports, module) {
+module.exports = {
+  DestinationType:{
+    DATA_URL: 0,         // Return base64 encoded string
+    FILE_URI: 1          // Return file uri (content://media/external/images/media/2 for Android)
+  },
+  EncodingType:{
+    JPEG: 0,             // Return JPEG encoded image
+    PNG: 1               // Return PNG encoded image
+  },
+  MediaType:{
+    PICTURE: 0,          // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType
+    VIDEO: 1,            // allow selection of video only, ONLY RETURNS URL
+    ALLMEDIA : 2         // allow selection from all media types
+  },
+  PictureSourceType:{
+    PHOTOLIBRARY : 0,    // Choose image from picture library (same as SAVEDPHOTOALBUM for Android)
+    CAMERA : 1,          // Take picture from camera
+    SAVEDPHOTOALBUM : 2  // Choose image from picture library (same as PHOTOLIBRARY for Android)
+  },
+  PopoverArrowDirection:{
+      ARROW_UP : 1,        // matches iOS UIPopoverArrowDirection constants to specify arrow location on popover
+      ARROW_DOWN : 2,
+      ARROW_LEFT : 4,
+      ARROW_RIGHT : 8,
+      ARROW_ANY : 15
+  }
+};
+});
+
+// file: lib/common/plugin/CameraPopoverOptions.js
+define("cordova/plugin/CameraPopoverOptions", function(require, exports, module) {
+var Camera = require('cordova/plugin/CameraConstants');
+
+/**
+ * Encapsulates options for iOS Popover image picker
+ */
+var CameraPopoverOptions = function(x,y,width,height,arrowDir){
+    // information of rectangle that popover should be anchored to
+    this.x = x || 0;
+    this.y = y || 32;
+    this.width = width || 320;
+    this.height = height || 480;
+    // The direction of the popover arrow
+    this.arrowDir = arrowDir || Camera.PopoverArrowDirection.ARROW_ANY;
+};
+
+module.exports = CameraPopoverOptions;
+});
+
+// file: lib/common/plugin/CaptureAudioOptions.js
+define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) {
+/**
+ * Encapsulates all audio capture operation configuration options.
+ */
+var CaptureAudioOptions = function(){
+    // Upper limit of sound clips user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single sound clip in seconds.
+    this.duration = 0;
+    // The selected audio mode. Must match with one of the elements in supportedAudioModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureAudioOptions;
+});
+
+// file: lib/common/plugin/CaptureError.js
+define("cordova/plugin/CaptureError", function(require, exports, module) {
+/**
+ * The CaptureError interface encapsulates all errors in the Capture API.
+ */
+var CaptureError = function(c) {
+   this.code = c || null;
+};
+
+// Camera or microphone failed to capture image or sound.
+CaptureError.CAPTURE_INTERNAL_ERR = 0;
+// Camera application or audio capture application is currently serving other capture request.
+CaptureError.CAPTURE_APPLICATION_BUSY = 1;
+// Invalid use of the API (e.g. limit parameter has value less than one).
+CaptureError.CAPTURE_INVALID_ARGUMENT = 2;
+// User exited camera application or audio capture application before capturing anything.
+CaptureError.CAPTURE_NO_MEDIA_FILES = 3;
+// The requested capture operation is not supported.
+CaptureError.CAPTURE_NOT_SUPPORTED = 20;
+
+module.exports = CaptureError;
+});
+
+// file: lib/common/plugin/CaptureImageOptions.js
+define("cordova/plugin/CaptureImageOptions", function(require, exports, module) {
+/**
+ * Encapsulates all image capture operation configuration options.
+ */
+var CaptureImageOptions = function(){
+    // Upper limit of images user can take. Value must be equal or greater than 1.
+    this.limit = 1;
+    // The selected image mode. Must match with one of the elements in supportedImageModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureImageOptions;
+});
+
+// file: lib/common/plugin/CaptureVideoOptions.js
+define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) {
+/**
+ * Encapsulates all video capture operation configuration options.
+ */
+var CaptureVideoOptions = function(){
+    // Upper limit of videos user can record. Value must be equal or greater than 1.
+    this.limit = 1;
+    // Maximum duration of a single video clip in seconds.
+    this.duration = 0;
+    // The selected video mode. Must match with one of the elements in supportedVideoModes array.
+    this.mode = null;
+};
+
+module.exports = CaptureVideoOptions;
+});
+
+// file: lib/common/plugin/CompassError.js
+define("cordova/plugin/CompassError", function(require, exports, module) {
+/**
+ *  CompassError.
+ *  An error code assigned by an implementation when an error has occured
+ * @constructor
+ */
+var CompassError = function(err) {
+    this.code = (err !== undefined ? err : null);
+};
+
+CompassError.COMPASS_INTERNAL_ERR = 0;
+CompassError.COMPASS_NOT_SUPPORTED = 20;
+
+module.exports = CompassError;
+});
+
+// file: lib/common/plugin/CompassHeading.js
+define("cordova/plugin/CompassHeading", function(require, exports, module) {
+var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, timestamp) {
+  this.magneticHeading = (magneticHeading !== undefined ? magneticHeading : null);
+  this.trueHeading = (trueHeading !== undefined ? trueHeading : null);
+  this.headingAccuracy = (headingAccuracy !== undefined ? headingAccuracy : null);
+  this.timestamp = (timestamp !== undefined ? timestamp : new Date().getTime());
+};
+
+module.exports = CompassHeading;
+});
+
+// file: lib/common/plugin/ConfigurationData.js
+define("cordova/plugin/ConfigurationData", function(require, exports, module) {
+/**
+ * Encapsulates a set of parameters that the capture device supports.
+ */
+function ConfigurationData() {
+    // The ASCII-encoded string in lower case representing the media type.
+    this.type = null;
+    // The height attribute represents height of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0.
+    this.height = 0;
+    // The width attribute represents width of the image or video in pixels.
+    // In the case of a sound clip this attribute has value 0
+    this.width = 0;
+}
+
+module.exports = ConfigurationData;
+});
+
+// file: lib/common/plugin/Connection.js
+define("cordova/plugin/Connection", function(require, exports, module) {
+/**
+ * Network status
+ */
+module.exports = {
+        UNKNOWN: "unknown",
+        ETHERNET: "ethernet",
+        WIFI: "wifi",
+        CELL_2G: "2g",
+        CELL_3G: "3g",
+        CELL_4G: "4g",
+        NONE: "none"
+};
+});
+
+// file: lib/common/plugin/Contact.js
+define("cordova/plugin/Contact", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils');
+
+/**
+* Converts primitives into Complex Object
+* Currently only used for Date fields
+*/
+function convertIn(contact) {
+    var value = contact.birthday;
+    try {
+      contact.birthday = new Date(parseFloat(value));
+    } catch (exception){
+      console.log("Cordova Contact convertIn error: exception creating date.");
+    }
+    return contact;
+}
+
+/**
+* Converts Complex objects into primitives
+* Only conversion at present is for Dates.
+**/
+
+function convertOut(contact) {
+    var value = contact.birthday;
+    if (value !== null) {
+        // try to make it a Date object if it is not already
+        if (!utils.isDate(value)){
+            try {
+                value = new Date(value);
+            } catch(exception){
+                value = null;
+            }
+        }
+        if (utils.isDate(value)){
+            value = value.valueOf(); // convert to milliseconds
+        }
+        contact.birthday = value;
+    }
+    return contact;
+}
+
+/**
+* Contains information about a single contact.
+* @constructor
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {Array.<ContactField>} phoneNumbers array of phone numbers
+* @param {Array.<ContactField>} emails array of email addresses
+* @param {Array.<ContactAddress>} addresses array of addresses
+* @param {Array.<ContactField>} ims instant messaging user ids
+* @param {Array.<ContactOrganization>} organizations
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} note user notes about contact
+* @param {Array.<ContactField>} photos
+* @param {Array.<ContactField>} categories
+* @param {Array.<ContactField>} urls contact's web sites
+*/
+var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses,
+    ims, organizations, birthday, note, photos, categories, urls) {
+    this.id = id || null;
+    this.rawId = null;
+    this.displayName = displayName || null;
+    this.name = name || null; // ContactName
+    this.nickname = nickname || null;
+    this.phoneNumbers = phoneNumbers || null; // ContactField[]
+    this.emails = emails || null; // ContactField[]
+    this.addresses = addresses || null; // ContactAddress[]
+    this.ims = ims || null; // ContactField[]
+    this.organizations = organizations || null; // ContactOrganization[]
+    this.birthday = birthday || null;
+    this.note = note || null;
+    this.photos = photos || null; // ContactField[]
+    this.categories = categories || null; // ContactField[]
+    this.urls = urls || null; // ContactField[]
+};
+
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+    var fail = function(code) {
+        errorCB(new ContactError(code));
+    };
+    if (this.id === null) {
+        fail(ContactError.UNKNOWN_ERROR);
+    }
+    else {
+        exec(successCB, fail, "Contacts", "remove", [this.id]);
+    }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+    var clonedContact = utils.clone(this);
+    var i;
+    clonedContact.id = null;
+    clonedContact.rawId = null;
+    // Loop through and clear out any id's in phones, emails, etc.
+    if (clonedContact.phoneNumbers) {
+        for (i = 0; i < clonedContact.phoneNumbers.length; i++) {
+            clonedContact.phoneNumbers[i].id = null;
+        }
+    }
+    if (clonedContact.emails) {
+        for (i = 0; i < clonedContact.emails.length; i++) {
+            clonedContact.emails[i].id = null;
+        }
+    }
+    if (clonedContact.addresses) {
+        for (i = 0; i < clonedContact.addresses.length; i++) {
+            clonedContact.addresses[i].id = null;
+        }
+    }
+    if (clonedContact.ims) {
+        for (i = 0; i < clonedContact.ims.length; i++) {
+            clonedContact.ims[i].id = null;
+        }
+    }
+    if (clonedContact.organizations) {
+        for (i = 0; i < clonedContact.organizations.length; i++) {
+            clonedContact.organizations[i].id = null;
+        }
+    }
+    if (clonedContact.categories) {
+        for (i = 0; i < clonedContact.categories.length; i++) {
+            clonedContact.categories[i].id = null;
+        }
+    }
+    if (clonedContact.photos) {
+        for (i = 0; i < clonedContact.photos.length; i++) {
+            clonedContact.photos[i].id = null;
+        }
+    }
+    if (clonedContact.urls) {
+        for (i = 0; i < clonedContact.urls.length; i++) {
+            clonedContact.urls[i].id = null;
+        }
+    }
+    return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+  var fail = function(code) {
+      errorCB(new ContactError(code));
+  };
+    var success = function(result) {
+      if (result) {
+          if (typeof successCB === 'function') {
+              var fullContact = require('cordova/plugin/contacts').create(result);
+              successCB(convertIn(fullContact));
+          }
+      }
+      else {
+          // no Entry object returned
+          fail(ContactError.UNKNOWN_ERROR);
+      }
+  };
+    var dupContact = convertOut(utils.clone(this));
+    exec(success, fail, "Contacts", "save", [dupContact]);
+};
+
+
+module.exports = Contact;
+
+});
+
+// file: lib/common/plugin/ContactAddress.js
+define("cordova/plugin/ContactAddress", function(require, exports, module) {
+/**
+* Contact address.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code
+* @param formatted // NOTE: not a W3C standard
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+
+var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.formatted = formatted || null;
+    this.streetAddress = streetAddress || null;
+    this.locality = locality || null;
+    this.region = region || null;
+    this.postalCode = postalCode || null;
+    this.country = country || null;
+};
+
+module.exports = ContactAddress;
+});
+
+// file: lib/common/plugin/ContactError.js
+define("cordova/plugin/ContactError", function(require, exports, module) {
+/**
+ *  ContactError.
+ *  An error code assigned by an implementation when an error has occured
+ * @constructor
+ */
+var ContactError = function(err) {
+    this.code = (typeof err != 'undefined' ? err : null);
+};
+
+/**
+ * Error codes
+ */
+ContactError.UNKNOWN_ERROR = 0;
+ContactError.INVALID_ARGUMENT_ERROR = 1;
+ContactError.TIMEOUT_ERROR = 2;
+ContactError.PENDING_OPERATION_ERROR = 3;
+ContactError.IO_ERROR = 4;
+ContactError.NOT_SUPPORTED_ERROR = 5;
+ContactError.PERMISSION_DENIED_ERROR = 20;
+
+module.exports = ContactError;
+});
+
+// file: lib/common/plugin/ContactField.js
+define("cordova/plugin/ContactField", function(require, exports, module) {
+/**
+* Generic contact field.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param type
+* @param value
+* @param pref
+*/
+var ContactField = function(type, value, pref) {
+    this.id = null;
+    this.type = (type && type.toString()) || null;
+    this.value = (value && value.toString()) || null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+};
+
+module.exports = ContactField;
+});
+
+// file: lib/common/plugin/ContactFindOptions.js
+define("cordova/plugin/ContactFindOptions", function(require, exports, module) {
+/**
+ * ContactFindOptions.
+ * @constructor
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ */
+
+var ContactFindOptions = function(filter, multiple) {
+    this.filter = filter || '';
+    this.multiple = (typeof multiple != 'undefined' ? multiple : false);
+};
+
+module.exports = ContactFindOptions;
+});
+
+// file: lib/common/plugin/ContactName.js
+define("cordova/plugin/ContactName", function(require, exports, module) {
+/**
+* Contact name.
+* @constructor
+* @param formatted // NOTE: not part of W3C standard
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
+var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
+    this.formatted = formatted || null;
+    this.familyName = familyName || null;
+    this.givenName = givenName || null;
+    this.middleName = middle || null;
+    this.honorificPrefix = prefix || null;
+    this.honorificSuffix = suffix || null;
+};
+
+module.exports = ContactName;
+});
+
+// file: lib/common/plugin/ContactOrganization.js
+define("cordova/plugin/ContactOrganization", function(require, exports, module) {
+/**
+* Contact organization.
+* @constructor
+* @param {DOMString} id unique identifier, should only be set by native code // NOTE: not a W3C standard
+* @param name
+* @param dept
+* @param title
+* @param startDate
+* @param endDate
+* @param location
+* @param desc
+*/
+
+var ContactOrganization = function(pref, type, name, dept, title) {
+    this.id = null;
+    this.pref = (typeof pref != 'undefined' ? pref : false);
+    this.type = type || null;
+    this.name = name || null;
+    this.department = dept || null;
+    this.title = title || null;
+};
+
+module.exports = ContactOrganization;
+});
+
+// file: lib/common/plugin/Coordinates.js
+define("cordova/plugin/Coordinates", function(require, exports, module) {
+/**
+ * This class contains position information.
+ * @param {Object} lat
+ * @param {Object} lng
+ * @param {Object} alt
+ * @param {Object} acc
+ * @param {Object} head
+ * @param {Object} vel
+ * @param {Object} altacc
+ * @constructor
+ */
+var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) {
+    /**
+     * The latitude of the position.
+     */
+    this.latitude = lat;
+    /**
+     * The longitude of the position,
+     */
+    this.longitude = lng;
+    /**
+     * The accuracy of the position.
+     */
+    this.accuracy = acc;
+    /**
+     * The altitude of the position.
+     */
+    this.altitude = (alt !== undefined ? alt : null);
+    /**
+     * The direction the device is moving at the position.
+     */
+    this.heading = (head !== undefined ? head : null);
+    /**
+     * The velocity with which the device is moving at the position.
+     */
+    this.speed = (vel !== undefined ? vel : null);
+
+    if (this.speed === 0 || this.speed === null) {
+        this.heading = NaN;
+    }
+
+    /**
+     * The altitude accuracy of the position.
+     */
+    this.altitudeAccuracy = (altacc !== undefined) ? altacc : null;
+};
+
+module.exports = Coordinates;
+
+});
+
+// file: lib/common/plugin/DirectoryEntry.js
+define("cordova/plugin/DirectoryEntry", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileError = require('cordova/plugin/FileError'),
+    DirectoryReader = require('cordova/plugin/DirectoryReader');
+
+/**
+ * An interface representing a directory on the file system.
+ *
+ * {boolean} isFile always false (readonly)
+ * {boolean} isDirectory always true (readonly)
+ * {DOMString} name of the directory, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the directory (readonly)
+ * TODO: implement this!!! {FileSystem} filesystem on which the directory resides (readonly)
+ */
+var DirectoryEntry = function(name, fullPath) {
+     DirectoryEntry.__super__.constructor.apply(this, [false, true, name, fullPath]);
+};
+
+utils.extend(DirectoryEntry, Entry);
+
+/**
+ * Creates a new DirectoryReader to read entries from this directory
+ */
+DirectoryEntry.prototype.createReader = function() {
+    return new DirectoryReader(this.fullPath);
+};
+
+/**
+ * Creates or looks up a directory
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory
+ * @param {Flags} options to create or excluively create the directory
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getDirectory", [this.fullPath, path, options]);
+};
+
+/**
+ * Deletes a directory and all of it's contents
+ *
+ * @param {Function} successCallback is called with no parameters
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "removeRecursively", [this.fullPath]);
+};
+
+/**
+ * Creates or looks up a file
+ *
+ * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file
+ * @param {Flags} options to create or excluively create the file
+ * @param {Function} successCallback is called with the new entry
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var FileEntry = require('cordova/plugin/FileEntry');
+        var entry = new FileEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFile", [this.fullPath, path, options]);
+};
+
+module.exports = DirectoryEntry;
+
+});
+
+// file: lib/common/plugin/DirectoryReader.js
+define("cordova/plugin/DirectoryReader", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError') ;
+
+/**
+ * An interface that lists the files and directories in a directory.
+ */
+function DirectoryReader(path) {
+    this.path = path || null;
+}
+
+/**
+ * Returns a list of entries from a directory.
+ *
+ * @param {Function} successCallback is called with a list of entries
+ * @param {Function} errorCallback is called with a FileError
+ */
+DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var retVal = [];
+        for (var i=0; i<result.length; i++) {
+            var entry = null;
+            if (result[i].isDirectory) {
+                entry = new (require('cordova/plugin/DirectoryEntry'))();
+            }
+            else if (result[i].isFile) {
+                entry = new (require('cordova/plugin/FileEntry'))();
+            }
+            entry.isDirectory = result[i].isDirectory;
+            entry.isFile = result[i].isFile;
+            entry.name = result[i].name;
+            entry.fullPath = result[i].fullPath;
+            retVal.push(entry);
+        }
+        successCallback(retVal);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "readEntries", [this.path]);
+};
+
+module.exports = DirectoryReader;
+
+});
+
+// file: lib/common/plugin/Entry.js
+define("cordova/plugin/Entry", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    Metadata = require('cordova/plugin/Metadata');
+
+/**
+ * Represents a file or directory on the local file system.
+ *
+ * @param isFile
+ *            {boolean} true if Entry is a file (readonly)
+ * @param isDirectory
+ *            {boolean} true if Entry is a directory (readonly)
+ * @param name
+ *            {DOMString} name of the file or directory, excluding the path
+ *            leading to it (readonly)
+ * @param fullPath
+ *            {DOMString} the absolute full path to the file or directory
+ *            (readonly)
+ */
+function Entry(isFile, isDirectory, name, fullPath, fileSystem) {
+    this.isFile = (typeof isFile != 'undefined'?isFile:false);
+    this.isDirectory = (typeof isDirectory != 'undefined'?isDirectory:false);
+    this.name = name || '';
+    this.fullPath = fullPath || '';
+    this.filesystem = fileSystem || null;
+}
+
+/**
+ * Look up the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ */
+Entry.prototype.getMetadata = function(successCallback, errorCallback) {
+  var success = typeof successCallback !== 'function' ? null : function(lastModified) {
+      var metadata = new Metadata(lastModified);
+      successCallback(metadata);
+  };
+  var fail = typeof errorCallback !== 'function' ? null : function(code) {
+      errorCallback(new FileError(code));
+  };
+
+  exec(success, fail, "File", "getMetadata", [this.fullPath]);
+};
+
+/**
+ * Set the metadata of the entry.
+ *
+ * @param successCallback
+ *            {Function} is called with a Metadata object
+ * @param errorCallback
+ *            {Function} is called with a FileError
+ * @param metadataObject
+ *            {Object} keys and values to set
+ */
+Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {
+
+  exec(successCallback, errorCallback, "File", "setMetadata", [this.fullPath, metadataObject]);
+};
+
+/**
+ * Move a file or directory to a new location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to move this entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new DirectoryEntry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+    // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "moveTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Copy a directory to a different location.
+ *
+ * @param parent
+ *            {DirectoryEntry} the directory to which to copy the entry
+ * @param newName
+ *            {DOMString} new name of the entry, defaults to the current name
+ * @param successCallback
+ *            {Function} called with the new Entry object
+ * @param errorCallback
+ *            {Function} called with a FileError
+ */
+Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    // user must specify parent Entry
+    if (!parent) {
+        fail(FileError.NOT_FOUND_ERR);
+        return;
+    }
+
+        // source path
+    var srcPath = this.fullPath,
+        // entry name
+        name = newName || this.name,
+        // success callback
+        success = function(entry) {
+            if (entry) {
+                if (typeof successCallback === 'function') {
+                    // create appropriate Entry object
+                    var result = (entry.isDirectory) ? new (require('cordova/plugin/DirectoryEntry'))(entry.name, entry.fullPath) : new (require('cordova/plugin/FileEntry'))(entry.name, entry.fullPath);
+                    try {
+                        successCallback(result);
+                    }
+                    catch (e) {
+                        console.log('Error invoking callback: ' + e);
+                    }
+                }
+            }
+            else {
+                // no Entry object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+
+    // copy
+    exec(success, fail, "File", "copyTo", [srcPath, parent.fullPath, name]);
+};
+
+/**
+ * Return a URL that can be used to identify this entry.
+ */
+Entry.prototype.toURL = function() {
+    // fullPath attribute contains the full URL
+    return this.fullPath;
+};
+
+/**
+ * Returns a URI that can be used to identify this entry.
+ *
+ * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
+ * @return uri
+ */
+Entry.prototype.toURI = function(mimeType) {
+    console.log("DEPRECATED: Update your code to use 'toURL'");
+    // fullPath attribute contains the full URI
+    return this.toURL();
+};
+
+/**
+ * Remove a file or directory. It is an error to attempt to delete a
+ * directory that is not empty. It is an error to attempt to delete a
+ * root directory of a file system.
+ *
+ * @param successCallback {Function} called with no parameters
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.remove = function(successCallback, errorCallback) {
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(successCallback, fail, "File", "remove", [this.fullPath]);
+};
+
+/**
+ * Look up the parent DirectoryEntry of this entry.
+ *
+ * @param successCallback {Function} called with the parent DirectoryEntry object
+ * @param errorCallback {Function} called with a FileError
+ */
+Entry.prototype.getParent = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(result) {
+        var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+        var entry = new DirectoryEntry(result.name, result.fullPath);
+        successCallback(entry);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getParent", [this.fullPath]);
+};
+
+module.exports = Entry;
+});
+
+// file: lib/common/plugin/File.js
+define("cordova/plugin/File", function(require, exports, module) {
+/**
+ * Constructor.
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+
+var File = function(name, fullPath, type, lastModifiedDate, size){
+    this.name = name || '';
+    this.fullPath = fullPath || null;
+    this.type = type || null;
+    this.lastModifiedDate = lastModifiedDate || null;
+    this.size = size || 0;
+};
+
+module.exports = File;
+});
+
+// file: lib/common/plugin/FileEntry.js
+define("cordova/plugin/FileEntry", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    Entry = require('cordova/plugin/Entry'),
+    FileWriter = require('cordova/plugin/FileWriter'),
+    File = require('cordova/plugin/File'),
+    FileError = require('cordova/plugin/FileError');
+
+/**
+ * An interface representing a file on the file system.
+ *
+ * {boolean} isFile always true (readonly)
+ * {boolean} isDirectory always false (readonly)
+ * {DOMString} name of the file, excluding the path leading to it (readonly)
+ * {DOMString} fullPath the absolute full path to the file (readonly)
+ * {FileSystem} filesystem on which the file resides (readonly)
+ */
+var FileEntry = function(name, fullPath) {
+     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath]);
+};
+
+utils.extend(FileEntry, Entry);
+
+/**
+ * Creates a new FileWriter associated with the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new FileWriter
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.createWriter = function(successCallback, errorCallback) {
+    this.file(function(filePointer) {
+        var writer = new FileWriter(filePointer);
+
+        if (writer.fileName === null || writer.fileName === "") {
+            if (typeof errorCallback === "function") {
+                errorCallback(new FileError(FileError.INVALID_STATE_ERR));
+            }
+        } else {
+            if (typeof successCallback === "function") {
+                successCallback(writer);
+            }
+        }
+    }, errorCallback);
+};
+
+/**
+ * Returns a File that represents the current state of the file that this FileEntry represents.
+ *
+ * @param {Function} successCallback is called with the new File object
+ * @param {Function} errorCallback is called with a FileError
+ */
+FileEntry.prototype.file = function(successCallback, errorCallback) {
+    var win = typeof successCallback !== 'function' ? null : function(f) {
+        var file = new File(f.name, f.fullPath, f.type, f.lastModifiedDate, f.size);
+        successCallback(file);
+    };
+    var fail = typeof errorCallback !== 'function' ? null : function(code) {
+        errorCallback(new FileError(code));
+    };
+    exec(win, fail, "File", "getFileMetadata", [this.fullPath]);
+};
+
+
+module.exports = FileEntry;
+});
+
+// file: lib/common/plugin/FileError.js
+define("cordova/plugin/FileError", function(require, exports, module) {
+/**
+ * FileError
+ */
+function FileError(error) {
+  this.code = error || null;
+}
+
+// File error codes
+// Found in DOMException
+FileError.NOT_FOUND_ERR = 1;
+FileError.SECURITY_ERR = 2;
+FileError.ABORT_ERR = 3;
+
+// Added by File API specification
+FileError.NOT_READABLE_ERR = 4;
+FileError.ENCODING_ERR = 5;
+FileError.NO_MODIFICATION_ALLOWED_ERR = 6;
+FileError.INVALID_STATE_ERR = 7;
+FileError.SYNTAX_ERR = 8;
+FileError.INVALID_MODIFICATION_ERR = 9;
+FileError.QUOTA_EXCEEDED_ERR = 10;
+FileError.TYPE_MISMATCH_ERR = 11;
+FileError.PATH_EXISTS_ERR = 12;
+
+module.exports = FileError;
+});
+
+// file: lib/common/plugin/FileReader.js
+define("cordova/plugin/FileReader", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class reads the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To read from the SD card, the file name is "sdcard/my_file.txt"
+ * @constructor
+ */
+var FileReader = function() {
+    this.fileName = "";
+
+    this.readyState = 0; // FileReader.EMPTY
+
+    // File data
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onloadstart = null;    // When the read starts.
+    this.onprogress = null;     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progess.loaded/progress.total)
+    this.onload = null;         // When the read has successfully completed.
+    this.onerror = null;        // When the read has failed (see errors).
+    this.onloadend = null;      // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the read has been aborted. For instance, by invoking the abort() method.
+};
+
+// States
+FileReader.EMPTY = 0;
+FileReader.LOADING = 1;
+FileReader.DONE = 2;
+
+/**
+ * Abort reading file.
+ */
+FileReader.prototype.abort = function() {
+    this.result = null;
+
+    if (this.readyState == FileReader.DONE || this.readyState == FileReader.EMPTY) {
+      return;
+    }
+
+    this.readyState = FileReader.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === 'function') {
+        this.onabort(new ProgressEvent('abort', {target:this}));
+    }
+    // If load end callback
+    if (typeof this.onloadend === 'function') {
+        this.onloadend(new ProgressEvent('loadend', {target:this}));
+    }
+};
+
+/**
+ * Read text file.
+ *
+ * @param file          {File} File object containing file properties
+ * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)
+ */
+FileReader.prototype.readAsText = function(file, encoding) {
+    // Figure out pathing
+    this.fileName = '';
+    if (typeof file.fullPath === 'undefined') {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    // Default encoding is UTF-8
+    var enc = encoding ? encoding : "UTF-8";
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // null result
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsText", [this.fileName, enc]);
+};
+
+
+/**
+ * Read file and return data as a base64 encoded data url.
+ * A data url is of the form:
+ *      data:[<mediatype>][;base64],<data>
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsDataURL = function(file) {
+    this.fileName = "";
+    if (typeof file.fullPath === "undefined") {
+        this.fileName = file;
+    } else {
+        this.fileName = file.fullPath;
+    }
+
+    // Already loading something
+    if (this.readyState == FileReader.LOADING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // LOADING state
+    this.readyState = FileReader.LOADING;
+
+    // If loadstart callback
+    if (typeof this.onloadstart === "function") {
+        this.onloadstart(new ProgressEvent("loadstart", {target:this}));
+    }
+
+    var me = this;
+
+    // Read file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            // Save result
+            me.result = r;
+
+            // If onload callback
+            if (typeof me.onload === "function") {
+                me.onload(new ProgressEvent("load", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileReader.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileReader.DONE;
+
+            me.result = null;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {target:me}));
+            }
+
+            // If onloadend callback
+            if (typeof me.onloadend === "function") {
+                me.onloadend(new ProgressEvent("loadend", {target:me}));
+            }
+        }, "File", "readAsDataURL", [this.fileName]);
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsBinaryString = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('method "readAsBinaryString" is not supported at this time.');
+};
+
+/**
+ * Read file and return data as a binary data.
+ *
+ * @param file          {File} File object containing file properties
+ */
+FileReader.prototype.readAsArrayBuffer = function(file) {
+    // TODO - Can't return binary data to browser.
+    console.log('This method is not supported at this time.');
+};
+
+module.exports = FileReader;
+});
+
+// file: lib/common/plugin/FileSystem.js
+define("cordova/plugin/FileSystem", function(require, exports, module) {
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry');
+
+/**
+ * An interface representing a file system
+ *
+ * @constructor
+ * {DOMString} name the unique name of the file system (readonly)
+ * {DirectoryEntry} root directory of the file system (readonly)
+ */
+var FileSystem = function(name, root) {
+    this.name = name || null;
+    if (root) {
+        this.root = new DirectoryEntry(root.name, root.fullPath);
+    }
+};
+
+module.exports = FileSystem;
+
+});
+
+// file: lib/common/plugin/FileTransfer.js
+define("cordova/plugin/FileTransfer", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileTransferError = require('cordova/plugin/FileTransferError');
+
+/**
+ * FileTransfer uploads a file to a remote server.
+ * @constructor
+ */
+var FileTransfer = function() {};
+
+/**
+* Given an absolute file path, uploads a file on the device to a remote server
+* using a multipart HTTP request.
+* @param filePath {String}           Full path of the file on the device
+* @param server {String}             URL of the server to receive the file
+* @param successCallback (Function}  Callback to be invoked when upload has completed
+* @param errorCallback {Function}    Callback to be invoked upon error
+* @param options {FileUploadOptions} Optional parameters such as file name and mimetype
+* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
+*/
+FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {
+    // sanity parameter checking
+    if (!filePath || !server) throw new Error("FileTransfer.upload requires filePath and server URL parameters at the minimum.");
+    // check for options
+    var fileKey = null;
+    var fileName = null;
+    var mimeType = null;
+    var params = null;
+    var chunkedMode = true;
+    if (options) {
+        fileKey = options.fileKey;
+        fileName = options.fileName;
+        mimeType = options.mimeType;
+        if (options.chunkedMode !== null || typeof options.chunkedMode != "undefined") {
+            chunkedMode = options.chunkedMode;
+        }
+        if (options.params) {
+            params = options.params;
+        }
+        else {
+            params = {};
+        }
+    }
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    exec(successCallback, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode]);
+};
+
+/**
+ * Downloads a file form a given URL and saves it to the specified directory.
+ * @param source {String}          URL of the server to receive the file
+ * @param target {String}         Full path of the file on the device
+ * @param successCallback (Function}  Callback to be invoked when upload has completed
+ * @param errorCallback {Function}    Callback to be invoked upon error
+ */
+FileTransfer.prototype.download = function(source, target, successCallback, errorCallback) {
+    // sanity parameter checking
+    if (!source || !target) throw new Error("FileTransfer.download requires source URI and target URI parameters at the minimum.");
+    var win = function(result) {
+        var entry = null;
+        if (result.isDirectory) {
+            entry = new (require('cordova/plugin/DirectoryEntry'))();
+        }
+        else if (result.isFile) {
+            entry = new (require('cordova/plugin/FileEntry'))();
+        }
+        entry.isDirectory = result.isDirectory;
+        entry.isFile = result.isFile;
+        entry.name = result.name;
+        entry.fullPath = result.fullPath;
+        successCallback(entry);
+    };
+
+    var fail = function(e) {
+        var error = new FileTransferError(e.code, e.source, e.target, e.http_status);
+        errorCallback(error);
+    };
+
+    exec(win, errorCallback, 'FileTransfer', 'download', [source, target]);
+};
+
+module.exports = FileTransfer;
+
+});
+
+// file: lib/common/plugin/FileTransferError.js
+define("cordova/plugin/FileTransferError", function(require, exports, module) {
+/**
+ * FileTransferError
+ * @constructor
+ */
+var FileTransferError = function(code, source, target, status) {
+    this.code = code || null;
+    this.source = source || null;
+    this.target = target || null;
+    this.http_status = status || null;
+};
+
+FileTransferError.FILE_NOT_FOUND_ERR = 1;
+FileTransferError.INVALID_URL_ERR = 2;
+FileTransferError.CONNECTION_ERR = 3;
+
+module.exports = FileTransferError;
+
+});
+
+// file: lib/common/plugin/FileUploadOptions.js
+define("cordova/plugin/FileUploadOptions", function(require, exports, module) {
+/**
+ * Options to customize the HTTP request used to upload files.
+ * @constructor
+ * @param fileKey {String}   Name of file request parameter.
+ * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.
+ * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.
+ * @param params {Object}    Object with key: value params to send to the server.
+ */
+var FileUploadOptions = function(fileKey, fileName, mimeType, params) {
+    this.fileKey = fileKey || null;
+    this.fileName = fileName || null;
+    this.mimeType = mimeType || null;
+    this.params = params || null;
+};
+
+module.exports = FileUploadOptions;
+});
+
+// file: lib/common/plugin/FileUploadResult.js
+define("cordova/plugin/FileUploadResult", function(require, exports, module) {
+/**
+ * FileUploadResult
+ * @constructor
+ */
+var FileUploadResult = function() {
+    this.bytesSent = 0;
+    this.responseCode = null;
+    this.response = null;
+};
+
+module.exports = FileUploadResult;
+});
+
+// file: lib/common/plugin/FileWriter.js
+define("cordova/plugin/FileWriter", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    FileError = require('cordova/plugin/FileError'),
+    ProgressEvent = require('cordova/plugin/ProgressEvent');
+
+/**
+ * This class writes to the mobile device file system.
+ *
+ * For Android:
+ *      The root directory is the root of the file system.
+ *      To write to the SD card, the file name is "sdcard/my_file.txt"
+ *
+ * @constructor
+ * @param file {File} File object containing file properties
+ * @param append if true write to the end of the file, otherwise overwrite the file
+ */
+var FileWriter = function(file) {
+    this.fileName = "";
+    this.length = 0;
+    if (file) {
+        this.fileName = file.fullPath || file;
+        this.length = file.size || 0;
+    }
+    // default is to write at the beginning of the file
+    this.position = 0;
+
+    this.readyState = 0; // EMPTY
+
+    this.result = null;
+
+    // Error
+    this.error = null;
+
+    // Event handlers
+    this.onwritestart = null;   // When writing starts
+    this.onprogress = null;     // While writing the file, and reporting partial file data
+    this.onwrite = null;        // When the write has successfully completed.
+    this.onwriteend = null;     // When the request has completed (either in success or failure).
+    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.
+    this.onerror = null;        // When the write has failed (see errors).
+};
+
+// States
+FileWriter.INIT = 0;
+FileWriter.WRITING = 1;
+FileWriter.DONE = 2;
+
+/**
+ * Abort writing file.
+ */
+FileWriter.prototype.abort = function() {
+    // check for invalid state
+    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // set error
+    this.error = new FileError(FileError.ABORT_ERR);
+
+    this.readyState = FileWriter.DONE;
+
+    // If abort callback
+    if (typeof this.onabort === "function") {
+        this.onabort(new ProgressEvent("abort", {"target":this}));
+    }
+
+    // If write end callback
+    if (typeof this.onwriteend === "function") {
+        this.onwriteend(new ProgressEvent("writeend", {"target":this}));
+    }
+};
+
+/**
+ * Writes data to the file
+ *
+ * @param text to be written
+ */
+FileWriter.prototype.write = function(text) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":me}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // position always increases by bytes written because file would be extended
+            me.position += r;
+            // The length of the file is now where we are done writing.
+
+            me.length = me.position;
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "write", [this.fileName, text, this.position]);
+};
+
+/**
+ * Moves the file pointer to the location specified.
+ *
+ * If the offset is a negative number the position of the file
+ * pointer is rewound.  If the offset is greater than the file
+ * size the position is set to the end of the file.
+ *
+ * @param offset is the location to move the file pointer to.
+ */
+FileWriter.prototype.seek = function(offset) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    if (!offset && offset !== 0) {
+        return;
+    }
+
+    // See back from end of file.
+    if (offset < 0) {
+        this.position = Math.max(offset + this.length, 0);
+    }
+    // Offset is bigger then file size so set position
+    // to the end of the file.
+    else if (offset > this.length) {
+        this.position = this.length;
+    }
+    // Offset is between 0 and file size so set the position
+    // to start writing.
+    else {
+        this.position = offset;
+    }
+};
+
+/**
+ * Truncates the file to the size specified.
+ *
+ * @param size to chop the file at.
+ */
+FileWriter.prototype.truncate = function(size) {
+    // Throw an exception if we are already writing a file
+    if (this.readyState === FileWriter.WRITING) {
+        throw new FileError(FileError.INVALID_STATE_ERR);
+    }
+
+    // WRITING state
+    this.readyState = FileWriter.WRITING;
+
+    var me = this;
+
+    // If onwritestart callback
+    if (typeof me.onwritestart === "function") {
+        me.onwritestart(new ProgressEvent("writestart", {"target":this}));
+    }
+
+    // Write file
+    exec(
+        // Success callback
+        function(r) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Update the length of the file
+            me.length = r;
+            me.position = Math.min(me.position, r);
+
+            // If onwrite callback
+            if (typeof me.onwrite === "function") {
+                me.onwrite(new ProgressEvent("write", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        },
+        // Error callback
+        function(e) {
+            // If DONE (cancelled), then don't do anything
+            if (me.readyState === FileWriter.DONE) {
+                return;
+            }
+
+            // DONE state
+            me.readyState = FileWriter.DONE;
+
+            // Save error
+            me.error = new FileError(e);
+
+            // If onerror callback
+            if (typeof me.onerror === "function") {
+                me.onerror(new ProgressEvent("error", {"target":me}));
+            }
+
+            // If onwriteend callback
+            if (typeof me.onwriteend === "function") {
+                me.onwriteend(new ProgressEvent("writeend", {"target":me}));
+            }
+        }, "File", "truncate", [this.fileName, size]);
+};
+
+module.exports = FileWriter;
+
+});
+
+// file: lib/common/plugin/Flags.js
+define("cordova/plugin/Flags", function(require, exports, module) {
+/**
+ * Supplies arguments to methods that lookup or create files and directories.
+ *
+ * @param create
+ *            {boolean} file or directory if it doesn't exist
+ * @param exclusive
+ *            {boolean} used with create; if true the command will fail if
+ *            target path exists
+ */
+function Flags(create, exclusive) {
+    this.create = create || false;
+    this.exclusive = exclusive || false;
+}
+
+module.exports = Flags;
+});
+
+// file: lib/common/plugin/LocalFileSystem.js
+define("cordova/plugin/LocalFileSystem", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+/**
+ * Represents a local file system.
+ */
+var LocalFileSystem = function() {
+
+};
+
+LocalFileSystem.TEMPORARY = 0; //temporary, with no guarantee of persistence
+LocalFileSystem.PERSISTENT = 1; //persistent
+
+module.exports = LocalFileSystem;
+});
+
+// file: lib/common/plugin/Media.js
+define("cordova/plugin/Media", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+var mediaObjects = {};
+
+/**
+ * This class provides access to the device media, interfaces to both sound and video
+ *
+ * @constructor
+ * @param src                   The file name or url to play
+ * @param successCallback       The callback to be called when the file is done playing or recording.
+ *                                  successCallback()
+ * @param errorCallback         The callback to be called if there is an error.
+ *                                  errorCallback(int errorCode) - OPTIONAL
+ * @param statusCallback        The callback to be called when media status has changed.
+ *                                  statusCallback(int statusCode) - OPTIONAL
+ */
+var Media = function(src, successCallback, errorCallback, statusCallback) {
+
+    // successCallback optional
+    if (successCallback && (typeof successCallback !== "function")) {
+        console.log("Media Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Media Error: errorCallback is not a function");
+        return;
+    }
+
+    // statusCallback optional
+    if (statusCallback && (typeof statusCallback !== "function")) {
+        console.log("Media Error: statusCallback is not a function");
+        return;
+    }
+
+    this.id = utils.createUUID();
+    mediaObjects[this.id] = this;
+    this.src = src;
+    this.successCallback = successCallback;
+    this.errorCallback = errorCallback;
+    this.statusCallback = statusCallback;
+    this._duration = -1;
+    this._position = -1;
+    exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
+};
+
+// Media messages
+Media.MEDIA_STATE = 1;
+Media.MEDIA_DURATION = 2;
+Media.MEDIA_POSITION = 3;
+Media.MEDIA_ERROR = 9;
+
+// Media states
+Media.MEDIA_NONE = 0;
+Media.MEDIA_STARTING = 1;
+Media.MEDIA_RUNNING = 2;
+Media.MEDIA_PAUSED = 3;
+Media.MEDIA_STOPPED = 4;
+Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
+
+// "static" function to return existing objs.
+Media.get = function(id) {
+    return mediaObjects[id];
+};
+
+/**
+ * Start or resume playing audio file.
+ */
+Media.prototype.play = function(options) {
+    exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
+};
+
+/**
+ * Stop playing audio file.
+ */
+Media.prototype.stop = function() {
+    var me = this;
+    exec(function() {
+        me._position = 0;
+        me.successCallback();
+    }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
+};
+
+/**
+ * Seek or jump to a new time in the track..
+ */
+Media.prototype.seekTo = function(milliseconds) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+    }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
+};
+
+/**
+ * Pause playing audio file.
+ */
+Media.prototype.pause = function() {
+    exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
+};
+
+/**
+ * Get duration of an audio file.
+ * The duration is only set for audio that is playing, paused or stopped.
+ *
+ * @return      duration or -1 if not known.
+ */
+Media.prototype.getDuration = function() {
+    return this._duration;
+};
+
+/**
+ * Get position of audio.
+ */
+Media.prototype.getCurrentPosition = function(success, fail) {
+    var me = this;
+    exec(function(p) {
+        me._position = p;
+        success(p);
+    }, fail, "Media", "getCurrentPositionAudio", [this.id]);
+};
+
+/**
+ * Start recording audio file.
+ */
+Media.prototype.startRecord = function() {
+    exec(this.successCallback, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
+};
+
+/**
+ * Stop recording audio file.
+ */
+Media.prototype.stopRecord = function() {
+    exec(this.successCallback, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
+};
+
+/**
+ * Release the resources.
+ */
+Media.prototype.release = function() {
+    exec(null, this.errorCallback, "Media", "release", [this.id]);
+};
+
+/**
+ * Adjust the volume.
+ */
+Media.prototype.setVolume = function(volume) {
+    exec(null, null, "Media", "setVolume", [this.id, volume]);
+};
+
+/**
+ * Audio has status update.
+ * PRIVATE
+ *
+ * @param id            The media object id (string)
+ * @param status        The status code (int)
+ * @param msg           The status message (string)
+ */
+Media.onStatus = function(id, msg, value) {
+    var media = mediaObjects[id];
+    // If state update
+    if (msg === Media.MEDIA_STATE) {
+        if (value === Media.MEDIA_STOPPED) {
+            if (media.successCallback) {
+                media.successCallback();
+            }
+        }
+        if (media.statusCallback) {
+            media.statusCallback(value);
+        }
+    }
+    else if (msg === Media.MEDIA_DURATION) {
+        media._duration = value;
+    }
+    else if (msg === Media.MEDIA_ERROR) {
+        if (media.errorCallback) {
+            // value should be a MediaError object when msg == MEDIA_ERROR
+            media.errorCallback(value);
+        }
+    }
+    else if (msg === Media.MEDIA_POSITION) {
+        media._position = value;
+    }
+};
+
+module.exports = Media;
+});
+
+// file: lib/common/plugin/MediaError.js
+define("cordova/plugin/MediaError", function(require, exports, module) {
+/**
+ * This class contains information about any Media errors.
+ * @constructor
+ */
+var MediaError = function(code, msg) {
+    this.code = (code !== undefined ? code : null);
+    this.message = msg || "";
+};
+
+MediaError.MEDIA_ERR_NONE_ACTIVE    = 0;
+MediaError.MEDIA_ERR_ABORTED        = 1;
+MediaError.MEDIA_ERR_NETWORK        = 2;
+MediaError.MEDIA_ERR_DECODE         = 3;
+MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
+
+module.exports = MediaError;
+});
+
+// file: lib/common/plugin/MediaFile.js
+define("cordova/plugin/MediaFile", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    File = require('cordova/plugin/File'),
+    CaptureError = require('cordova/plugin/CaptureError');
+/**
+ * Represents a single file.
+ *
+ * name {DOMString} name of the file, without path information
+ * fullPath {DOMString} the full path of the file, including the name
+ * type {DOMString} mime type
+ * lastModifiedDate {Date} last modified date
+ * size {Number} size of the file in bytes
+ */
+var MediaFile = function(name, fullPath, type, lastModifiedDate, size){
+    MediaFile.__super__.constructor.apply(this, arguments);
+};
+
+utils.extend(MediaFile, File);
+
+/**
+ * Request capture format data for a specific file and type
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ */
+MediaFile.prototype.getFormatData = function(successCallback, errorCallback) {
+    if (typeof this.fullPath === "undefined" || this.fullPath === null) {
+        errorCallback(new CaptureError(CaptureError.CAPTURE_INVALID_ARGUMENT));
+    } else {
+        exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]);
+    }
+};
+
+// TODO: can we axe this?
+/**
+ * Casts a PluginResult message property  (array of objects) to an array of MediaFile objects
+ * (used in Objective-C and Android)
+ *
+ * @param {PluginResult} pluginResult
+ */
+MediaFile.cast = function(pluginResult) {
+    var mediaFiles = [];
+    for (var i=0; i<pluginResult.message.length; i++) {
+        var mediaFile = new MediaFile();
+        mediaFile.name = pluginResult.message[i].name;
+        mediaFile.fullPath = pluginResult.message[i].fullPath;
+        mediaFile.type = pluginResult.message[i].type;
+        mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate;
+        mediaFile.size = pluginResult.message[i].size;
+        mediaFiles.push(mediaFile);
+    }
+    pluginResult.message = mediaFiles;
+    return pluginResult;
+};
+
+module.exports = MediaFile;
+
+});
+
+// file: lib/common/plugin/MediaFileData.js
+define("cordova/plugin/MediaFileData", function(require, exports, module) {
+/**
+ * MediaFileData encapsulates format information of a media file.
+ *
+ * @param {DOMString} codecs
+ * @param {long} bitrate
+ * @param {long} height
+ * @param {long} width
+ * @param {float} duration
+ */
+var MediaFileData = function(codecs, bitrate, height, width, duration){
+    this.codecs = codecs || null;
+    this.bitrate = bitrate || 0;
+    this.height = height || 0;
+    this.width = width || 0;
+    this.duration = duration || 0;
+};
+
+module.exports = MediaFileData;
+});
+
+// file: lib/common/plugin/Metadata.js
+define("cordova/plugin/Metadata", function(require, exports, module) {
+/**
+ * Information about the state of the file or directory
+ *
+ * {Date} modificationTime (readonly)
+ */
+var Metadata = function(time) {
+    this.modificationTime = (typeof time != 'undefined'?new Date(time):null);
+};
+
+module.exports = Metadata;
+});
+
+// file: lib/common/plugin/Position.js
+define("cordova/plugin/Position", function(require, exports, module) {
+var Coordinates = require('cordova/plugin/Coordinates');
+
+var Position = function(coords, timestamp) {
+    if (coords) {
+        this.coords = new Coordinates(coords.latitude, coords.longitude, coords.altitude, coords.accuracy, coords.heading, coords.velocity, coords.altitudeAccuracy);
+    } else {
+        this.coords = new Coordinates();
+    }
+    this.timestamp = (timestamp !== undefined) ? timestamp : new Date();
+};
+
+module.exports = Position;
+
+});
+
+// file: lib/common/plugin/PositionError.js
+define("cordova/plugin/PositionError", function(require, exports, module) {
+/**
+ * Position error object
+ *
+ * @constructor
+ * @param code
+ * @param message
+ */
+var PositionError = function(code, message) {
+    this.code = code || null;
+    this.message = message || '';
+};
+
+PositionError.PERMISSION_DENIED = 1;
+PositionError.POSITION_UNAVAILABLE = 2;
+PositionError.TIMEOUT = 3;
+
+module.exports = PositionError;
+});
+
+// file: lib/common/plugin/ProgressEvent.js
+define("cordova/plugin/ProgressEvent", function(require, exports, module) {
+// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill
+// Feature test: See if we can instantiate a native ProgressEvent;
+// if so, use that approach,
+// otherwise fill-in with our own implementation.
+//
+// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.
+var ProgressEvent = (function() {
+    /*
+    var createEvent = function(data) {
+        var event = document.createEvent('Events');
+        event.initEvent('ProgressEvent', false, false);
+        if (data) {
+            for (var i in data) {
+                if (data.hasOwnProperty(i)) {
+                    event[i] = data[i];
+                }
+            }
+            if (data.target) {
+                // TODO: cannot call <some_custom_object>.dispatchEvent
+                // need to first figure out how to implement EventTarget
+            }
+        }
+        return event;
+    };
+    try {
+        var ev = createEvent({type:"abort",target:document});
+        return function ProgressEvent(type, data) {
+            data.type = type;
+            return createEvent(data);
+        };
+    } catch(e){
+    */
+        return function ProgressEvent(type, dict) {
+            this.type = type;
+            this.bubbles = false;
+            this.cancelBubble = false;
+            this.cancelable = false;
+            this.lengthComputable = false;
+            this.loaded = dict && dict.loaded ? dict.loaded : 0;
+            this.total = dict && dict.total ? dict.total : 0;
+            this.target = dict && dict.target ? dict.target : null;
+        };
+    //}
+})();
+
+module.exports = ProgressEvent;
+});
+
+// file: lib/common/plugin/accelerometer.js
+define("cordova/plugin/accelerometer", function(require, exports, module) {
+/**
+ * This class provides access to device accelerometer data.
+ * @constructor
+ */
+var utils = require("cordova/utils"),
+    exec = require("cordova/exec"),
+    Acceleration = require('cordova/plugin/Acceleration');
+
+// Is the accel sensor running?
+var running = false;
+
+// Keeps reference to watchAcceleration calls.
+var timers = {};
+
+// Array of listeners; used to keep track of when we should call start and stop.
+var listeners = [];
+
+// Last returned acceleration object from native
+var accel = null;
+
+// Tells native to start.
+function start() {
+    exec(function(a) {
+        var tempListeners = listeners.slice(0);
+        accel = new Acceleration(a.x, a.y, a.z, a.timestamp);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].win(accel);
+        }
+    }, function(e) {
+        var tempListeners = listeners.slice(0);
+        for (var i = 0, l = tempListeners.length; i < l; i++) {
+            tempListeners[i].fail(e);
+        }
+    }, "Accelerometer", "start", []);
+    running = true;
+}
+
+// Tells native to stop.
+function stop() {
+    exec(null, null, "Accelerometer", "stop", []);
+    running = false;
+}
+
+// Adds a callback pair to the listeners array
+function createCallbackPair(win, fail) {
+    return {win:win, fail:fail};
+}
+
+// Removes a win/fail listener pair from the listeners array
+function removeListeners(l) {
+    var idx = listeners.indexOf(l);
+    if (idx > -1) {
+        listeners.splice(idx, 1);
+        if (listeners.length === 0) {
+            stop();
+        }
+    }
+}
+
+var accelerometer = {
+    /**
+     * Asynchronously aquires the current acceleration.
+     *
+     * @param {Function} successCallback    The function to call when the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     */
+    getCurrentAcceleration: function(successCallback, errorCallback, options) {
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "getCurrentAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        var p;
+        var win = function(a) {
+            removeListeners(p);
+            successCallback(a);
+        };
+        var fail = function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        };
+
+        p = createCallbackPair(win, fail);
+        listeners.push(p);
+
+        if (!running) {
+            start();
+        }
+    },
+
+    /**
+     * Asynchronously aquires the acceleration repeatedly at a given interval.
+     *
+     * @param {Function} successCallback    The function to call each time the acceleration data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the acceleration data. (OPTIONAL)
+     * @param {AccelerationOptions} options The options for getting the accelerometer data such as timeout. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchAcceleration: function(successCallback, errorCallback, options) {
+        // Default interval (10 sec)
+        var frequency = (options && options.frequency && typeof options.frequency == 'number') ? options.frequency : 10000;
+
+        // successCallback required
+        if (typeof successCallback !== "function") {
+            throw "watchAcceleration must be called with at least a success callback function as first parameter.";
+        }
+
+        // Keep reference to watch id, and report accel readings as often as defined in frequency
+        var id = utils.createUUID();
+
+        var p = createCallbackPair(function(){}, function(e) {
+            removeListeners(p);
+            errorCallback(e);
+        });
+        listeners.push(p);
+
+        timers[id] = {
+            timer:window.setInterval(function() {
+                if (accel) {
+                    successCallback(accel);
+                }
+            }, frequency),
+            listeners:p
+        };
+
+        if (running) {
+            // If we're already running then immediately invoke the success callback
+            // but only if we have retreived a value, sample code does not check for null ...
+            if(accel) {
+                successCallback(accel);
+            }
+        } else {
+            start();
+        }
+
+        return id;
+    },
+
+    /**
+     * Clears the specified accelerometer watch.
+     *
+     * @param {String} id       The id of the watch returned from #watchAcceleration.
+     */
+    clearWatch: function(id) {
+        // Stop javascript timer & remove from timer list
+        if (id && timers[id]) {
+            window.clearInterval(timers[id].timer);
+            removeListeners(timers[id].listeners);
+            delete timers[id];
+        }
+    }
+};
+
+module.exports = accelerometer;
+
+});
+
+// file: lib/common/plugin/battery.js
+define("cordova/plugin/battery", function(require, exports, module) {
+/**
+ * This class contains information about the current battery status.
+ * @constructor
+ */
+var cordova = require('cordova'),
+    exec = require('cordova/exec');
+
+function handlers() {
+  return battery.channels.batterystatus.numHandlers +
+         battery.channels.batterylow.numHandlers +
+         battery.channels.batterycritical.numHandlers;
+}
+
+var Battery = function() {
+    this._level = null;
+    this._isPlugged = null;
+    // Create new event handlers on the window (returns a channel instance)
+    var subscriptionEvents = {
+      onSubscribe:this.onSubscribe,
+      onUnsubscribe:this.onUnsubscribe
+    };
+    this.channels = {
+      batterystatus:cordova.addWindowEventHandler("batterystatus", subscriptionEvents),
+      batterylow:cordova.addWindowEventHandler("batterylow", subscriptionEvents),
+      batterycritical:cordova.addWindowEventHandler("batterycritical", subscriptionEvents)
+    };
+};
+/**
+ * Event handlers for when callbacks get registered for the battery.
+ * Keep track of how many handlers we have so we can start and stop the native battery listener
+ * appropriately (and hopefully save on battery life!).
+ */
+Battery.prototype.onSubscribe = function() {
+  var me = battery;
+  // If we just registered the first handler, make sure native listener is started.
+  if (handlers() === 1) {
+    exec(me._status, me._error, "Battery", "start", []);
+  }
+};
+
+Battery.prototype.onUnsubscribe = function() {
+  var me = battery;
+
+  // If we just unregistered the last handler, make sure native listener is stopped.
+  if (handlers() === 0) {
+      exec(null, null, "Battery", "stop", []);
+  }
+};
+
+/**
+ * Callback for battery status
+ *
+ * @param {Object} info            keys: level, isPlugged
+ */
+Battery.prototype._status = function(info) {
+    if (info) {
+        var me = battery;
+    var level = info.level;
+        if (me._level !== level || me._isPlugged !== info.isPlugged) {
+            // Fire batterystatus event
+            cordova.fireWindowEvent("batterystatus", info);
+
+            // Fire low battery event
+            if (level === 20 || level === 5) {
+                if (level === 20) {
+                    cordova.fireWindowEvent("batterylow", info);
+                }
+                else {
+                    cordova.fireWindowEvent("batterycritical", info);
+                }
+            }
+        }
+        me._level = level;
+        me._isPlugged = info.isPlugged;
+    }
+};
+
+/**
+ * Error callback for battery start
+ */
+Battery.prototype._error = function(e) {
+    console.log("Error initializing Battery: " + e);
+};
+
+var battery = new Battery();
+
+module.exports = battery;
+});
+
+// file: lib/common/plugin/capture.js
+define("cordova/plugin/capture", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    MediaFile = require('cordova/plugin/MediaFile');
+
+/**
+ * Launches a capture of different types.
+ *
+ * @param (DOMString} type
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+function _capture(type, successCallback, errorCallback, options) {
+    var win = function(pluginResult) {
+        var mediaFiles = [];
+        var i;
+        for (i = 0; i < pluginResult.length; i++) {
+            var mediaFile = new MediaFile();
+            mediaFile.name = pluginResult[i].name;
+            mediaFile.fullPath = pluginResult[i].fullPath;
+            mediaFile.type = pluginResult[i].type;
+            mediaFile.lastModifiedDate = pluginResult[i].lastModifiedDate;
+            mediaFile.size = pluginResult[i].size;
+            mediaFiles.push(mediaFile);
+        }
+        successCallback(mediaFiles);
+    };
+    exec(win, errorCallback, "Capture", type, [options]);
+}
+/**
+ * The Capture interface exposes an interface to the camera and microphone of the hosting device.
+ */
+function Capture() {
+    this.supportedAudioModes = [];
+    this.supportedImageModes = [];
+    this.supportedVideoModes = [];
+}
+
+/**
+ * Launch audio recorder application for recording audio clip(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureAudioOptions} options
+ */
+Capture.prototype.captureAudio = function(successCallback, errorCallback, options){
+    _capture("captureAudio", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch camera application for taking image(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureImageOptions} options
+ */
+Capture.prototype.captureImage = function(successCallback, errorCallback, options){
+    _capture("captureImage", successCallback, errorCallback, options);
+};
+
+/**
+ * Launch device camera application for recording video(s).
+ *
+ * @param {Function} successCB
+ * @param {Function} errorCB
+ * @param {CaptureVideoOptions} options
+ */
+Capture.prototype.captureVideo = function(successCallback, errorCallback, options){
+    _capture("captureVideo", successCallback, errorCallback, options);
+};
+
+
+module.exports = new Capture();
+
+});
+
+// file: lib/common/plugin/compass.js
+define("cordova/plugin/compass", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    utils = require('cordova/utils'),
+    CompassHeading = require('cordova/plugin/CompassHeading'),
+    CompassError = require('cordova/plugin/CompassError'),
+    timers = {},
+    compass = {
+        /**
+         * Asynchronously acquires the current heading.
+         * @param {Function} successCallback The function to call when the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {CompassOptions} options The options for getting the heading data (not used).
+         */
+        getCurrentHeading:function(successCallback, errorCallback, options) {
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var win = function(result) {
+                var ch = new CompassHeading(result.magneticHeading, result.trueHeading, result.headingAccuracy, result.timestamp);
+                successCallback(ch);
+            };
+            var fail = function(code) {
+                var ce = new CompassError(code);
+                errorCallback(ce);
+            };
+
+            // Get heading
+            exec(win, fail, "Compass", "getHeading", [options]);
+        },
+
+        /**
+         * Asynchronously acquires the heading repeatedly at a given interval.
+         * @param {Function} successCallback The function to call each time the heading
+         * data is available
+         * @param {Function} errorCallback The function to call when there is an error
+         * getting the heading data.
+         * @param {HeadingOptions} options The options for getting the heading data
+         * such as timeout and the frequency of the watch. For iOS, filter parameter
+         * specifies to watch via a distance filter rather than time.
+         */
+        watchHeading:function(successCallback, errorCallback, options) {
+            // Default interval (100 msec)
+            var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100;
+            var filter = (options !== undefined && options.filter !== undefined) ? options.filter : 0;
+
+            // successCallback required
+            if (typeof successCallback !== "function") {
+              console.log("Compass Error: successCallback is not a function");
+              return;
+            }
+
+            // errorCallback optional
+            if (errorCallback && (typeof errorCallback !== "function")) {
+              console.log("Compass Error: errorCallback is not a function");
+              return;
+            }
+
+            var id = utils.createUUID();
+            if (filter > 0) {
+                // is an iOS request for watch by filter, no timer needed
+                timers[id] = "iOS";
+                compass.getCurrentHeading(successCallback, errorCallback, options);
+            } else {
+                // Start watch timer to get headings
+                timers[id] = window.setInterval(function() {
+                    compass.getCurrentHeading(successCallback, errorCallback);
+                }, frequency);
+            }
+
+            return id;
+        },
+
+        /**
+         * Clears the specified heading watch.
+         * @param {String} watchId The ID of the watch returned from #watchHeading.
+         */
+        clearWatch:function(id) {
+            // Stop javascript timer & remove from timer list
+            if (id && timers[id]) {
+                if (timers[id] != "iOS") {
+                      clearInterval(timers[id]);
+                  } else {
+                    // is iOS watch by filter so call into device to stop
+                    exec(null, null, "Compass", "stopHeading", []);
+                }
+                delete timers[id];
+            }
+        }
+    };
+
+module.exports = compass;
+});
+
+// file: lib/common/plugin/console-via-logger.js
+define("cordova/plugin/console-via-logger", function(require, exports, module) {
+//------------------------------------------------------------------------------
+
+var logger = require("cordova/plugin/logger");
+var utils  = require("cordova/utils");
+
+//------------------------------------------------------------------------------
+// object that we're exporting
+//------------------------------------------------------------------------------
+var console = module.exports;
+
+//------------------------------------------------------------------------------
+// copy of the original console object
+//------------------------------------------------------------------------------
+var WinConsole = window.console;
+
+//------------------------------------------------------------------------------
+// whether to use the logger
+//------------------------------------------------------------------------------
+var UseLogger = false;
+
+//------------------------------------------------------------------------------
+// Timers
+//------------------------------------------------------------------------------
+var Timers = {};
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+function noop() {}
+
+//------------------------------------------------------------------------------
+// used for unimplemented methods
+//------------------------------------------------------------------------------
+console.useLogger = function (value) {
+    if (arguments.length) UseLogger = !!value;
+
+    if (UseLogger) {
+        if (logger.useConsole()) {
+            throw new Error("console and logger are too intertwingly");
+        }
+    }
+
+    return UseLogger;
+};
+
+//------------------------------------------------------------------------------
+console.log = function() {
+    if (logger.useConsole()) return;
+    logger.log.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.error = function() {
+    if (logger.useConsole()) return;
+    logger.error.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.warn = function() {
+    if (logger.useConsole()) return;
+    logger.warn.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.info = function() {
+    if (logger.useConsole()) return;
+    logger.info.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.debug = function() {
+    if (logger.useConsole()) return;
+    logger.debug.apply(logger, [].slice.call(arguments));
+};
+
+//------------------------------------------------------------------------------
+console.assert = function(expression) {
+    if (expression) return;
+
+    var message = utils.vformat(arguments[1], [].slice.call(arguments, 2));
+    console.log("ASSERT: " + message);
+};
+
+//------------------------------------------------------------------------------
+console.clear = function() {};
+
+//------------------------------------------------------------------------------
+console.dir = function(object) {
+    console.log("%o", object);
+};
+
+//------------------------------------------------------------------------------
+console.dirxml = function(node) {
+    console.log(node.innerHTML);
+};
+
+//------------------------------------------------------------------------------
+console.trace = noop;
+
+//------------------------------------------------------------------------------
+console.group = console.log;
+
+//------------------------------------------------------------------------------
+console.groupCollapsed = console.log;
+
+//------------------------------------------------------------------------------
+console.groupEnd = noop;
+
+//------------------------------------------------------------------------------
+console.time = function(name) {
+    Timers[name] = new Date().valueOf();
+};
+
+//------------------------------------------------------------------------------
+console.timeEnd = function(name) {
+    var timeStart = Timers[name];
+    if (!timeStart) {
+        console.warn("unknown timer: " + name);
+        return;
+    }
+
+    var timeElapsed = new Date().valueOf() - timeStart;
+    console.log(name + ": " + timeElapsed + "ms");
+};
+
+//------------------------------------------------------------------------------
+console.timeStamp = noop;
+
+//------------------------------------------------------------------------------
+console.profile = noop;
+
+//------------------------------------------------------------------------------
+console.profileEnd = noop;
+
+//------------------------------------------------------------------------------
+console.count = noop;
+
+//------------------------------------------------------------------------------
+console.exception = console.log;
+
+//------------------------------------------------------------------------------
+console.table = function(data, columns) {
+    console.log("%o", data);
+};
+
+//------------------------------------------------------------------------------
+// return a new function that calls both functions passed as args
+//------------------------------------------------------------------------------
+function wrapperedOrigCall(orgFunc, newFunc) {
+    return function() {
+        var args = [].slice.call(arguments);
+        try { orgFunc.apply(WinConsole, args); } catch (e) {}
+        try { newFunc.apply(console,    args); } catch (e) {}
+    };
+}
+
+//------------------------------------------------------------------------------
+// For every function that exists in the original console object, that
+// also exists in the new console object, wrap the new console method
+// with one that calls both
+//------------------------------------------------------------------------------
+for (var key in console) {
+    if (typeof WinConsole[key] == "function") {
+        console[key] = wrapperedOrigCall(WinConsole[key], console[key]);
+    }
+}
+
+});
+
+// file: lib/common/plugin/contacts.js
+define("cordova/plugin/contacts", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+* Represents a group of Contacts.
+* @constructor
+*/
+var contacts = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     * @param fields that should be searched
+     * @param successCB success callback
+     * @param errorCB error callback
+     * @param {ContactFindOptions} options that can be applied to contact searching
+     * @return array of Contacts matching search criteria
+     */
+    find:function(fields, successCB, errorCB, options) {
+        if (!successCB) {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+        if (!fields || (utils.isArray(fields) && fields.length === 0)) {
+            if (typeof errorCB === "function") {
+                errorCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+        } else {
+            var win = function(result) {
+                var cs = [];
+                for (var i = 0, l = result.length; i < l; i++) {
+                    cs.push(contacts.create(result[i]));
+                }
+                successCB(cs);
+            };
+            exec(win, errorCB, "Contacts", "search", [fields, options]);
+        }
+    },
+
+    /**
+     * This function creates a new contact, but it does not persist the contact
+     * to device storage. To persist the contact to device storage, invoke
+     * contact.save().
+     * @param properties an object who's properties will be examined to create a new Contact
+     * @returns new Contact object
+     */
+    create:function(properties) {
+        var i;
+        var contact = new Contact();
+        for (i in properties) {
+            if (typeof contact[i] !== 'undefined' && properties.hasOwnProperty(i)) {
+                contact[i] = properties[i];
+            }
+        }
+        return contact;
+    }
+};
+
+module.exports = contacts;
+
+});
+
+// file: lib/common/plugin/device.js
+define("cordova/plugin/device", function(require, exports, module) {
+var channel = require('cordova/channel'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+/**
+ * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the
+ * phone, etc.
+ * @constructor
+ */
+function Device() {
+    this.available = false;
+    this.platform = null;
+    this.version = null;
+    this.name = null;
+    this.uuid = null;
+    this.cordova = null;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getInfo(function(info) {
+            me.available = true;
+            me.platform = info.platform;
+            me.version = info.version;
+            me.name = info.name;
+            me.uuid = info.uuid;
+            me.cordova = info.cordova;
+            channel.onCordovaInfoReady.fire();
+        },function(e) {
+            me.available = false;
+            utils.alert("[ERROR] Error initializing Cordova: " + e);
+        });
+    });
+}
+
+/**
+ * Get device info
+ *
+ * @param {Function} successCallback The function to call when the heading data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)
+ */
+Device.prototype.getInfo = function(successCallback, errorCallback) {
+
+    // successCallback required
+    if (typeof successCallback !== "function") {
+        console.log("Device Error: successCallback is not a function");
+        return;
+    }
+
+    // errorCallback optional
+    if (errorCallback && (typeof errorCallback !== "function")) {
+        console.log("Device Error: errorCallback is not a function");
+        return;
+    }
+
+    // Get info
+    exec(successCallback, errorCallback, "Device", "getDeviceInfo", []);
+};
+
+module.exports = new Device();
+
+});
+
+// file: lib/common/plugin/geolocation.js
+define("cordova/plugin/geolocation", function(require, exports, module) {
+var utils = require('cordova/utils'),
+    exec = require('cordova/exec'),
+    PositionError = require('cordova/plugin/PositionError'),
+    Position = require('cordova/plugin/Position');
+
+var timers = {};   // list of timers in use
+
+// Returns default params, overrides if provided with values
+function parseParameters(options) {
+    var opt = {
+        maximumAge: 0,
+        enableHighAccuracy: false,
+        timeout: Infinity
+    };
+
+    if (options) {
+        if (options.maximumAge !== undefined && !isNaN(options.maximumAge) && options.maximumAge > 0) {
+            opt.maximumAge = options.maximumAge;
+        }
+        if (options.enableHighAccuracy !== undefined) {
+            opt.enableHighAccuracy = options.enableHighAccuracy;
+        }
+        if (options.timeout !== undefined && !isNaN(options.timeout)) {
+            if (options.timeout < 0) {
+                opt.timeout = 0;
+            } else {
+                opt.timeout = options.timeout;
+            }
+        }
+    }
+
+    return opt;
+}
+
+// Returns a timeout failure, closed over a specified timeout value and error callback.
+function createTimeout(errorCallback, timeout) {
+    var t = setTimeout(function() {
+        clearTimeout(t);
+        t = null;
+        errorCallback({
+            code:PositionError.TIMEOUT,
+            message:"Position retrieval timed out."
+        });
+    }, timeout);
+    return t;
+}
+
+var geolocation = {
+    lastPosition:null, // reference to last known (cached) position returned
+    /**
+   * Asynchronously aquires the current position.
+   *
+   * @param {Function} successCallback    The function to call when the position data is available
+   * @param {Function} errorCallback      The function to call when there is an error getting the heading position. (OPTIONAL)
+   * @param {PositionOptions} options     The options for getting the position data. (OPTIONAL)
+   */
+    getCurrentPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("getCurrentPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        // Timer var that will fire an error callback if no position is retrieved from native
+        // before the "timeout" param provided expires
+        var timeoutTimer = null;
+
+        var win = function(p) {
+            clearTimeout(timeoutTimer);
+            if (!timeoutTimer) {
+                // Timeout already happened, or native fired error callback for
+                // this geo request.
+                // Don't continue with success callback.
+                return;
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+        var fail = function(e) {
+            clearTimeout(timeoutTimer);
+            timeoutTimer = null;
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        // Check our cached position, if its timestamp difference with current time is less than the maximumAge, then just
+        // fire the success callback with the cached position.
+        if (geolocation.lastPosition && options.maximumAge && (((new Date()).getTime() - geolocation.lastPosition.timestamp.getTime()) <= options.maximumAge)) {
+            successCallback(geolocation.lastPosition);
+        // If the cached position check failed and the timeout was set to 0, error out with a TIMEOUT error object.
+        } else if (options.timeout === 0) {
+            fail({
+                code:PositionError.TIMEOUT,
+                message:"timeout value in PositionOptions set to 0 and no cached Position object available, or cached Position object's age exceed's provided PositionOptions' maximumAge parameter."
+            });
+        // Otherwise we have to call into native to retrieve a position.
+        } else {
+            if (options.timeout !== Infinity) {
+                // If the timeout value was not set to Infinity (default), then
+                // set up a timeout function that will fire the error callback
+                // if no successful position was retrieved before timeout expired.
+                timeoutTimer = createTimeout(fail, options.timeout);
+            } else {
+                // This is here so the check in the win function doesn't mess stuff up
+                // may seem weird but this guarantees timeoutTimer is
+                // always truthy before we call into native
+                timeoutTimer = true;
+            }
+            exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.maximumAge]);
+        }
+        return timeoutTimer;
+    },
+    /**
+     * Asynchronously watches the geolocation for changes to geolocation.  When a change occurs,
+     * the successCallback is called with the new location.
+     *
+     * @param {Function} successCallback    The function to call each time the location data is available
+     * @param {Function} errorCallback      The function to call when there is an error getting the location data. (OPTIONAL)
+     * @param {PositionOptions} options     The options for getting the location data such as frequency. (OPTIONAL)
+     * @return String                       The watch id that must be passed to #clearWatch to stop watching.
+     */
+    watchPosition:function(successCallback, errorCallback, options) {
+        if (arguments.length === 0) {
+            throw new Error("watchPosition must be called with at least one argument.");
+        }
+        options = parseParameters(options);
+
+        var id = utils.createUUID();
+
+        // Tell device to get a position ASAP, and also retrieve a reference to the timeout timer generated in getCurrentPosition
+        timers[id] = geolocation.getCurrentPosition(successCallback, errorCallback, options);
+
+        var fail = function(e) {
+            clearTimeout(timers[id]);
+            var err = new PositionError(e.code, e.message);
+            if (errorCallback) {
+                errorCallback(err);
+            }
+        };
+
+        var win = function(p) {
+            clearTimeout(timers[id]);
+            if (options.timeout !== Infinity) {
+                timers[id] = createTimeout(fail, options.timeout);
+            }
+            var pos = new Position(
+                {
+                    latitude:p.latitude,
+                    longitude:p.longitude,
+                    altitude:p.altitude,
+                    accuracy:p.accuracy,
+                    heading:p.heading,
+                    velocity:p.velocity,
+                    altitudeAccuracy:p.altitudeAccuracy
+                },
+                (p.timestamp === undefined ? new Date() : ((p.timestamp instanceof Date) ? p.timestamp : new Date(p.timestamp)))
+            );
+            geolocation.lastPosition = pos;
+            successCallback(pos);
+        };
+
+        exec(win, fail, "Geolocation", "addWatch", [id, options.enableHighAccuracy]);
+
+        return id;
+    },
+    /**
+     * Clears the specified heading watch.
+     *
+     * @param {String} id       The ID of the watch returned from #watchPosition
+     */
+    clearWatch:function(id) {
+        if (id && timers[id] !== undefined) {
+            clearTimeout(timers[id]);
+            delete timers[id];
+            exec(null, null, "Geolocation", "clearWatch", [id]);
+        }
+    }
+};
+
+module.exports = geolocation;
+
+});
+
+// file: lib/common/plugin/logger.js
+define("cordova/plugin/logger", function(require, exports, module) {
+//------------------------------------------------------------------------------
+// The logger module exports the following properties/functions:
+//
+// LOG                          - constant for the level LOG
+// ERROR                        - constant for the level ERROR
+// WARN                         - constant for the level WARN
+// INFO                         - constant for the level INFO
+// DEBUG                        - constant for the level DEBUG
+// logLevel()                   - returns current log level
+// logLevel(value)              - sets and returns a new log level
+// useConsole()                 - returns whether logger is using console
+// useConsole(value)            - sets and returns whether logger is using console
+// log(message,...)             - logs a message at level LOG
+// error(message,...)           - logs a message at level ERROR
+// warn(message,...)            - logs a message at level WARN
+// info(message,...)            - logs a message at level INFO
+// debug(message,...)           - logs a message at level DEBUG
+// logLevel(level,message,...)  - logs a message specified level
+//
+//------------------------------------------------------------------------------
+
+var logger = exports;
+
+var exec    = require('cordova/exec');
+var utils   = require('cordova/utils');
+
+var UseConsole   = true;
+var Queued       = [];
+var DeviceReady  = false;
+var CurrentLevel;
+
+/**
+ * Logging levels
+ */
+
+var Levels = [
+    "LOG",
+    "ERROR",
+    "WARN",
+    "INFO",
+    "DEBUG"
+];
+
+/*
+ * add the logging levels to the logger object and
+ * to a separate levelsMap object for testing
+ */
+
+var LevelsMap = {};
+for (var i=0; i<Levels.length; i++) {
+    var level = Levels[i];
+    LevelsMap[level] = i;
+    logger[level]    = level;
+}
+
+CurrentLevel = LevelsMap.WARN;
+
+/**
+ * Getter/Setter for the logging level
+ *
+ * Returns the current logging level.
+ *
+ * When a value is passed, sets the logging level to that value.
+ * The values should be one of the following constants:
+ *    logger.LOG
+ *    logger.ERROR
+ *    logger.WARN
+ *    logger.INFO
+ *    logger.DEBUG
+ *
+ * The value used determines which messages get printed.  The logging
+ * values above are in order, and only messages logged at the logging
+ * level or above will actually be displayed to the user.  Eg, the
+ * default level is WARN, so only messages logged with LOG, ERROR, or
+ * WARN will be displayed; INFO and DEBUG messages will be ignored.
+ */
+logger.level = function (value) {
+    if (arguments.length) {
+        if (LevelsMap[value] === null) {
+            throw new Error("invalid logging level: " + value);
+        }
+        CurrentLevel = LevelsMap[value];
+    }
+
+    return Levels[CurrentLevel];
+};
+
+/**
+ * Getter/Setter for the useConsole functionality
+ *
+ * When useConsole is true, the logger will log via the
+ * browser 'console' object.  Otherwise, it will use the
+ * native Logger plugin.
+ */
+logger.useConsole = function (value) {
+    if (arguments.length) UseConsole = !!value;
+
+    if (UseConsole) {
+        if (typeof console == "undefined") {
+            throw new Error("global console object is not defined");
+        }
+
+        if (typeof console.log != "function") {
+            throw new Error("global console object does not have a log function");
+        }
+
+        if (typeof console.useLogger == "function") {
+            if (console.useLogger()) {
+                throw new Error("console and logger are too intertwingly");
+            }
+        }
+    }
+
+    return UseConsole;
+};
+
+/**
+ * Logs a message at the LOG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.log   = function(message) { logWithArgs("LOG",   arguments); };
+
+/**
+ * Logs a message at the ERROR level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.error = function(message) { logWithArgs("ERROR", arguments); };
+
+/**
+ * Logs a message at the WARN level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.warn  = function(message) { logWithArgs("WARN",  arguments); };
+
+/**
+ * Logs a message at the INFO level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.info  = function(message) { logWithArgs("INFO",  arguments); };
+
+/**
+ * Logs a message at the DEBUG level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.debug = function(message) { logWithArgs("DEBUG", arguments); };
+
+// log at the specified level with args
+function logWithArgs(level, args) {
+    args = [level].concat([].slice.call(args));
+    logger.logLevel.apply(logger, args);
+}
+
+/**
+ * Logs a message at the specified level.
+ *
+ * Parameters passed after message are used applied to
+ * the message with utils.format()
+ */
+logger.logLevel = function(level, message /* , ... */) {
+    // format the message with the parameters
+    var formatArgs = [].slice.call(arguments, 2);
+    message    = utils.vformat(message, formatArgs);
+
+    if (LevelsMap[level] === null) {
+        throw new Error("invalid logging level: " + level);
+    }
+
+    if (LevelsMap[level] > CurrentLevel) return;
+
+    // queue the message if not yet at deviceready
+    if (!DeviceReady && !UseConsole) {
+        Queued.push([level, message]);
+        return;
+    }
+
+    // if not using the console, use the native logger
+    if (!UseConsole) {
+        exec(null, null, "Logger", "logLevel", [level, message]);
+        return;
+    }
+
+    // make sure console is not using logger
+    if (console.__usingCordovaLogger) {
+        throw new Error("console and logger are too intertwingly");
+    }
+
+    // log to the console
+    switch (level) {
+        case logger.LOG:   console.log(message); break;
+        case logger.ERROR: console.log("ERROR: " + message); break;
+        case logger.WARN:  console.log("WARN: "  + message); break;
+        case logger.INFO:  console.log("INFO: "  + message); break;
+        case logger.DEBUG: console.log("DEBUG: " + message); break;
+    }
+};
+
+// when deviceready fires, log queued messages
+logger.__onDeviceReady = function() {
+    if (DeviceReady) return;
+
+    DeviceReady = true;
+
+    for (var i=0; i<Queued.length; i++) {
+        var messageArgs = Queued[i];
+        logger.logLevel(messageArgs[0], messageArgs[1]);
+    }
+
+    Queued = null;
+};
+
+// add a deviceready event to log queued messages
+document.addEventListener("deviceready", logger.__onDeviceReady, false);
+
+});
+
+// file: lib/common/plugin/network.js
+define("cordova/plugin/network", function(require, exports, module) {
+var exec = require('cordova/exec'),
+    cordova = require('cordova'),
+    channel = require('cordova/channel');
+
+var NetworkConnection = function () {
+    this.type = null;
+    this._firstRun = true;
+    this._timer = null;
+    this.timeout = 500;
+
+    var me = this;
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getInfo(function (info) {
+            me.type = info;
+            if (info === "none") {
+                // set a timer if still offline at the end of timer send the offline event
+                me._timer = setTimeout(function(){
+                    cordova.fireDocumentEvent("offline");
+                    me._timer = null;
+                    }, me.timeout);
+            } else {
+                // If there is a current offline event pending clear it
+                if (me._timer !== null) {
+                    clearTimeout(me._timer);
+                    me._timer = null;
+                }
+                cordova.fireDocumentEvent("online");
+            }
+
+            // should only fire this once
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+        },
+        function (e) {
+            // If we can't get the network info we should still tell Cordova
+            // to fire the deviceready event.
+            if (me._firstRun) {
+                me._firstRun = false;
+                channel.onCordovaConnectionReady.fire();
+            }
+            console.log("Error initializing Network Connection: " + e);
+        });
+    });
+};
+
+/**
+ * Get connection info
+ *
+ * @param {Function} successCallback The function to call when the Connection data is available
+ * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL)
+ */
+NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) {
+    // Get info
+    exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []);
+};
+
+module.exports = new NetworkConnection();
+});
+
+// file: lib/common/plugin/notification.js
+define("cordova/plugin/notification", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+/**
+ * Provides access to notifications on the device.
+ */
+
+module.exports = {
+
+    /**
+     * Open a native alert dialog, with a customizable title and button text.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} completeCallback   The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Alert)
+     * @param {String} buttonLabel          Label of the close button (default: OK)
+     */
+    alert: function(message, completeCallback, title, buttonLabel) {
+        var _title = (title || "Alert");
+        var _buttonLabel = (buttonLabel || "OK");
+        exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]);
+    },
+
+    /**
+     * Open a native confirm dialog, with a customizable title and button text.
+     * The result that the user selects is returned to the result callback.
+     *
+     * @param {String} message              Message to print in the body of the alert
+     * @param {Function} resultCallback     The callback that is called when user clicks on a button.
+     * @param {String} title                Title of the alert dialog (default: Confirm)
+     * @param {String} buttonLabels         Comma separated list of the labels of the buttons (default: 'OK,Cancel')
+     */
+    confirm: function(message, resultCallback, title, buttonLabels) {
+        var _title = (title || "Confirm");
+        var _buttonLabels = (buttonLabels || "OK,Cancel");
+        exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]);
+    },
+
+    /**
+     * Causes the device to vibrate.
+     *
+     * @param {Integer} mills       The number of milliseconds to vibrate for.
+     */
+    vibrate: function(mills) {
+        exec(null, null, "Notification", "vibrate", [mills]);
+    },
+
+    /**
+     * Causes the device to beep.
+     * On Android, the default notification ringtone is played "count" times.
+     *
+     * @param {Integer} count       The number of beeps.
+     */
+    beep: function(count) {
+        exec(null, null, "Notification", "beep", [count]);
+    }
+};
+});
+
+// file: lib/common/plugin/requestFileSystem.js
+define("cordova/plugin/requestFileSystem", function(require, exports, module) {
+var FileError = require('cordova/plugin/FileError'),
+    FileSystem = require('cordova/plugin/FileSystem'),
+    exec = require('cordova/exec');
+
+/**
+ * Request a file system in which to store application data.
+ * @param type  local file system type
+ * @param size  indicates how much storage space, in bytes, the application expects to need
+ * @param successCallback  invoked with a FileSystem object
+ * @param errorCallback  invoked if error occurs retrieving file system
+ */
+var requestFileSystem = function(type, size, successCallback, errorCallback) {
+    var fail = function(code) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(code));
+        }
+    };
+
+    if (type < 0 || type > 3) {
+        fail(FileError.SYNTAX_ERR);
+    } else {
+        // if successful, return a FileSystem object
+        var success = function(file_system) {
+            if (file_system) {
+                if (typeof successCallback === 'function') {
+                    // grab the name and root from the file system object
+                    var result = new FileSystem(file_system.name, file_system.root);
+                    successCallback(result);
+                }
+            }
+            else {
+                // no FileSystem object returned
+                fail(FileError.NOT_FOUND_ERR);
+            }
+        };
+        exec(success, fail, "File", "requestFileSystem", [type, size]);
+    }
+};
+
+module.exports = requestFileSystem;
+});
+
+// file: lib/common/plugin/resolveLocalFileSystemURI.js
+define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) {
+var DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    FileError = require('cordova/plugin/FileError'),
+    exec = require('cordova/exec');
+
+/**
+ * Look up file system Entry referred to by local URI.
+ * @param {DOMString} uri  URI referring to a local file or directory
+ * @param successCallback  invoked with Entry object corresponding to URI
+ * @param errorCallback    invoked if error occurs retrieving file system entry
+ */
+module.exports = function(uri, successCallback, errorCallback) {
+    // error callback
+    var fail = function(error) {
+        if (typeof errorCallback === 'function') {
+            errorCallback(new FileError(error));
+        }
+    };
+    // sanity check for 'not:valid:filename'
+    if(!uri || uri.split(":").length > 2) {
+        setTimeout( function() {
+            fail(FileError.ENCODING_ERR);
+        },0);
+        return;
+    }
+    // if successful, return either a file or directory entry
+    var success = function(entry) {
+        var result;
+        if (entry) {
+            if (typeof successCallback === 'function') {
+                // create appropriate Entry object
+                result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath) : new FileEntry(entry.name, entry.fullPath);
+                try {
+                    successCallback(result);
+                }
+                catch (e) {
+                    console.log('Error invoking callback: ' + e);
+                }
+            }
+        }
+        else {
+            // no Entry object returned
+            fail(FileError.NOT_FOUND_ERR);
+        }
+    };
+
+    exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]);
+};
+
+});
+
+// file: lib/common/plugin/splashscreen.js
+define("cordova/plugin/splashscreen", function(require, exports, module) {
+var exec = require('cordova/exec');
+
+var splashscreen = {
+    show:function() {
+        exec(null, null, "SplashScreen", "show", []);
+    },
+    hide:function() {
+        exec(null, null, "SplashScreen", "hide", []);
+    }
+};
+
+module.exports = splashscreen;
+});
+
+// file: lib/tizen/plugin/tizen/Accelerometer.js
+define("cordova/plugin/tizen/Accelerometer", function(require, exports, module) {
+var callback = null;
+
+module.exports = {
+    start: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+        callback = function (motion) {
+            successCallback({
+                x: motion.accelerationIncludingGravity.x,
+                y: motion.accelerationIncludingGravity.y,
+                z: motion.accelerationIncludingGravity.z,
+                timestamp: motion.timeStamp
+            });
+        };
+        window.addEventListener("devicemotion", callback);
+    },
+    stop: function (successCallback, errorCallback) {
+        window.removeEventListener("devicemotion", callback);
+    }
+};
+});
+
+// file: lib/tizen/plugin/tizen/Battery.js
+define("cordova/plugin/tizen/Battery", function(require, exports, module) {
+/*global tizen:false */
+var id = null;
+
+module.exports = {
+    start: function(successCallback, errorCallback) {
+        var tizenSuccessCallback = function(power) {
+            if (successCallback) {
+                successCallback({level: Math.round(power.level * 100), isPlugged: power.isCharging});
+            }
+        };
+
+        if (id === null) {
+            id = tizen.systeminfo.addPropertyValueChangeListener("Power", tizenSuccessCallback);
+        }
+        tizen.systeminfo.getPropertyValue("Power", tizenSuccessCallback, errorCallback);
+    },
+
+    stop: function(successCallback, errorCallback) {
+        tizen.systeminfo.removePropertyValueChangeListener(id);
+        id = null;
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/BufferLoader.js
+define("cordova/plugin/tizen/BufferLoader", function(require, exports, module) {
+/*
+ * Buffer Loader Object
+ * This class provides a sound buffer for one or more sounds
+ * holded in a local file located by an url
+ *
+ * uses W3C  Web Audio API
+ *
+ * @constructor
+ *
+ * @param {AudioContext} audio context object
+ * @param {Array} urlList, array of url for sound to load
+ * @param {function} callback , called after buffer was loaded
+ *
+ */
+
+function BufferLoader(context, urlList, callback) {
+    this.context = context;
+    this.urlList = urlList;
+    this.onload = callback;
+    this.bufferList = [];
+    this.loadCount = 0;
+}
+
+/*
+ * This method loads a sound into a buffer
+ * @param {Array} urlList, array of url for sound to load
+ * @param {Number} index, buffer index in the array where to load the url sound
+ *
+ */
+
+BufferLoader.prototype.loadBuffer = function(url, index) {
+    // Load buffer asynchronously
+    var request = null,
+        loader = null;
+
+    request = new XMLHttpRequest();
+
+    if (request === null) {
+        console.log ("BufferLoader.prototype.loadBuffer, cannot allocate XML http request");
+        return;
+    }
+
+    request.open("GET", url, true);
+    request.responseType = "arraybuffer";
+
+    loader = this;
+
+    request.onload = function() {
+    // Asynchronously decode the audio file data in request.response
+    loader.context.decodeAudioData(
+        request.response,
+        function(buffer) {
+                if (!buffer) {
+                    console.log ("BufferLoader.prototype.loadBuffer,error decoding file data: " + url);
+                    return;
+                }
+
+                loader.bufferList[index] = buffer;
+
+                if (++loader.loadCount == loader.urlList.length) {
+                    loader.onload(loader.bufferList);
+                }
+            }
+        );
+    };
+
+    request.onerror = function() {
+        console.log ("BufferLoader.prototype.loadBuffer, XHR error");
+    };
+
+    request.send();
+};
+
+/*
+ * This method loads all sounds identified by their url
+ * and that where given to the object constructor
+ *
+ */
+
+BufferLoader.prototype.load = function() {
+    for (var i = 0; i < this.urlList.length; ++i) {
+        this.loadBuffer(this.urlList[i], i);
+    }
+};
+
+module.exports = BufferLoader;
+
+});
+
+// file: lib/tizen/plugin/tizen/Camera.js
+define("cordova/plugin/tizen/Camera", function(require, exports, module) {
+/*global tizen:false */
+var Camera = require('cordova/plugin/CameraConstants');
+
+function makeReplyCallback(successCallback, errorCallback) {
+    return {
+        onsuccess: function(reply) {
+            if (reply.length > 0) {
+                successCallback(reply[0].value);
+            } else {
+                errorCallback('Picture selection aborted');
+            }
+        },
+        onfail: function() {
+           console.log('The service launch failed');
+        }
+    };
+}
+
+module.exports = {
+    takePicture: function(successCallback, errorCallback, args) {
+        var destinationType = args[1],
+            sourceType = args[2],
+            encodingType = args[5],
+            mediaType = args[6];
+            // Not supported
+            /*
+            quality = args[0]
+            targetWidth = args[3]
+            targetHeight = args[4]
+            allowEdit = args[7]
+            correctOrientation = args[8]
+            saveToPhotoAlbum = args[9]
+            */
+
+        if (destinationType !== Camera.DestinationType.FILE_URI) {
+            errorCallback('DestinationType not supported');
+            return;
+        }
+        if (mediaType !== Camera.MediaType.PICTURE) {
+            errorCallback('MediaType not supported');
+            return;
+        }
+
+        var mimeType;
+        if (encodingType === Camera.EncodingType.JPEG) {
+            mimeType = 'image/jpeg';
+        } else if (encodingType === Camera.EncodingType.PNG) {
+            mimeType = 'image/png';
+        } else {
+            mimeType = 'image/*';
+        }
+
+        var serviceId;
+        if (sourceType === Camera.PictureSourceType.CAMERA) {
+            serviceId = 'http://tizen.org/appsvc/operation/create_content';
+        } else {
+            serviceId = 'http://tizen.org/appsvc/operation/pick';
+        }
+
+        var service = new tizen.ApplicationService(serviceId, null, mimeType, null);
+        tizen.application.launchService(service, null, null,
+                function(error) { errorCallback(error.message); },
+                makeReplyCallback(successCallback, errorCallback));
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Compass.js
+define("cordova/plugin/tizen/Compass", function(require, exports, module) {
+var CompassError = require('cordova/plugin/CompassError'),
+    callback = null, ready = false;
+
+module.exports = {
+    getHeading: function(successCallback, errorCallback) {
+        if (window.DeviceOrientationEvent !== undefined) {
+            callback = function (orientation) {
+                var heading = 360 - orientation.alpha;
+                if (ready) {
+                    successCallback({
+                        magneticHeading: heading,
+                        trueHeading: heading,
+                        headingAccuracy: 0,
+                        timestamp: orientation.timeStamp
+                    });
+                    window.removeEventListener("deviceorientation", callback);
+                }
+                ready = true;
+            };
+            ready = false; // workaround invalid first event value returned by WRT
+            window.addEventListener("deviceorientation", callback);
+        }
+        else {
+            errorCallback(CompassError.COMPASS_NOT_SUPPORTED);
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Contact.js
+define("cordova/plugin/tizen/Contact", function(require, exports, module) {
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils'),
+    utils = require('cordova/utils'),
+    exec = require('cordova/exec');
+
+// ------------------
+// Utility functions
+// ------------------
+
+
+/**
+ * Retrieves a Tizen Contact object from the device by its unique id.
+ *
+ * @param uid
+ *            Unique id of the contact on the device
+ * @return {tizen.Contact} Tizen Contact object or null if contact with
+ *         specified id is not found
+ */
+var findByUniqueId = function(id) {
+
+    if (!id) {
+        return null;
+    }
+
+    var tizenContact = null;
+
+    tizen.contact.getDefaultAddressBook().find(
+        function _successCallback(contacts){
+            tizenContact = contacts[0];
+        },
+        function _errorCallback(error){
+            console.log("tizen find error " + error);
+        },
+        new tizen.AttributeFilter('id', 'CONTAINS', id),
+        new tizen.SortMode('id', 'ASC'));
+
+    return tizenContact || null;
+};
+
+
+var traceTizenContact = function (tizenContact) {
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.id " + tizenContact.id);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.lastUpdated " + tizenContact.lastUpdated);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.name " + tizenContact.name);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.account " + tizenContact.account);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.addresses " + tizenContact.addresses);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.photoURI " + tizenContact.photoURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.phoneNumbers " + tizenContact.phoneNumbers);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.emails " + tizenContact.emails);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.birthday " + tizenContact.birthday);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.organization " + tizenContact.organization);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.notes " + tizenContact.notes);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.urls " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.isFavorite " + tizenContact.isFavorite);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.ringtonesURI " + tizenContact.ringtonesURI);
+    console.log("cordova/plugin/tizen/Contact/  tizenContact.categories " + tizenContact.categories);
+};
+
+
+/**
+ * Creates a Tizen contact object from the W3C Contact object and persists
+ * it to device storage.
+ *
+ * @param {Contact}
+ *            contact The contact to save
+ * @return a new contact object with all properties set
+ */
+var saveToDevice = function(contact) {
+
+    if (!contact) {
+        return;
+    }
+
+    var tizenContact = null;
+    var update = false;
+    var i = 0;
+
+    // if the underlying Tizen Contact object already exists, retrieve it for
+    // update
+    if (contact.id) {
+        // we must attempt to retrieve the BlackBerry contact from the device
+        // because this may be an update operation
+        tizenContact = findByUniqueId(contact.id);
+    }
+
+    // contact not found on device, create a new one
+    if (!tizenContact) {
+        tizenContact = new tizen.Contact();
+    }
+    // update the existing contact
+    else {
+        update = true;
+    }
+
+    // NOTE: The user may be working with a partial Contact object, because only
+    // user-specified Contact fields are returned from a find operation (blame
+    // the W3C spec). If this is an update to an existing Contact, we don't
+    // want to clear an attribute from the contact database simply because the
+    // Contact object that the user passed in contains a null value for that
+    // attribute. So we only copy the non-null Contact attributes to the
+    // Tizen Contact object before saving.
+    //
+    // This means that a user must explicitly set a Contact attribute to a
+    // non-null value in order to update it in the contact database.
+    //
+    traceTizenContact (tizenContact);
+
+    // display name
+    if (contact.displayName !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            tizenContact.name.displayName = contact.displayName;
+        }
+    }
+
+    // name
+    if (contact.name !== null) {
+        if (contact.name.givenName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.firstName = contact.name.givenName;
+            }
+        }
+
+        if  (contact.name.middleName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.middleName = contact.name.middleName;
+            }
+        }
+
+        if (contact.name.familyName) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.lastName = contact.name.familyName;
+            }
+        }
+
+        if (contact.name.honorificPrefix) {
+            if (tizenContact.name === null) {
+                tizenContact.name = new tizen.ContactName();
+            }
+            if (tizenContact.name !== null) {
+                tizenContact.name.prefix = contact.name.honorificPrefix;
+            }
+        }
+    }
+
+    // nickname
+    if (contact.nickname !== null) {
+        if (tizenContact.name === null) {
+            tizenContact.name = new tizen.ContactName();
+        }
+        if (tizenContact.name !== null) {
+            if (!utils.isArray(tizenContact.name.nicknames))
+            {
+                tizenContact.name.nicknames = [];
+            }
+            tizenContact.name.nicknames[0] = contact.nickname;
+        }
+    }
+    else {
+        tizenContact.name.nicknames = [];
+    }
+
+    // note
+    if (contact.note !== null) {
+        if (tizenContact.note === null) {
+            tizenContact.note = [];
+        }
+        if (tizenContact.note !== null) {
+            tizenContact.note[0] = contact.note;
+        }
+    }
+
+    // photos
+    if (contact.photos && utils.isArray(contact.emails) && contact.emails.length > 0) {
+        tizenContact.photoURI = contact.photos[0];
+    }
+
+    if (utils.isDate(contact.birthday)) {
+        if (!utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday = new Date();
+        }
+        if (utils.isDate(tizenContact.birthday)) {
+            tizenContact.birthday.setDate(contact.birthday.getDate());
+        }
+    }
+
+    // Tizen supports many addresses
+    if (utils.isArray(contact.emails)) {
+
+        // if this is an update, re initialize email addresses
+        if (update) {
+            // doit on effacer sur un update??????
+        }
+
+        // copy the first three email addresses found
+        var emails = [];
+        for (i = 0; i < contact.emails.length; i += 1) {
+            var emailTypes = [];
+
+            emailTypes.push (contact.emails[i].type);
+
+            if (contact.emails[i].pref) {
+                emailTypes.push ("PREF");
+            }
+
+            emails.push(
+                new tizen.ContactEmailAddress(
+                    contact.emails[i].value,
+                    emailTypes)
+            );
+        }
+        tizenContact.emails = emails.length > 0 ? emails : [];
+    }
+    else {
+        tizenContact.emails = [];
+    }
+
+    // Tizen supports many phone numbers
+    // copy into appropriate fields based on type
+    if (utils.isArray(contact.phoneNumbers)) {
+        // if this is an update, re-initialize phone numbers
+        if (update) {
+        }
+
+        var phoneNumbers = [];
+
+        for (i = 0; i < contact.phoneNumbers.length; i += 1) {
+
+            if (!contact.phoneNumbers[i] || !contact.phoneNumbers[i].value) {
+                continue;
+            }
+
+             var phoneTypes = [];
+             phoneTypes.push (contact.phoneNumbers[i].type);
+
+             if (contact.phoneNumbers[i].pref) {
+                 phoneTypes.push ("PREF");
+             }
+
+            phoneNumbers.push(
+                new tizen.ContactPhoneNumber(
+                    contact.phoneNumbers[i].value,
+                    phoneTypes)
+            );
+        }
+
+        tizenContact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : [];
+    } else {
+        tizenContact.phoneNumbers = [];
+    }
+
+    if (utils.isArray(contact.addresses)) {
+        // if this is an update, re-initialize addresses
+        if (update) {
+        }
+
+        var addresses = [],
+            address = null;
+
+        for ( i = 0; i < contact.addresses.length; i += 1) {
+            address = contact.addresses[i];
+
+            if (!address || address.id === undefined || address.pref === undefined || address.type === undefined || address.formatted === undefined) {
+                continue;
+            }
+
+            var addressTypes = [];
+            addressTypes.push (address.type);
+
+            if (address.pref) {
+                addressTypes.push ("PREF");
+            }
+
+            addresses.push(
+                new tizen.ContactAddress({
+                         country:                   address.country,
+                         region :                   address.region,
+                         city:                      address.locality,
+                         streetAddress:             address.streetAddress,
+                         additionalInformation:     "",
+                         postalCode:                address.postalCode,
+                         types :                    addressTypes
+                }));
+
+        }
+        tizenContact.addresses = addresses.length > 0 ? addresses : [];
+
+    } else{
+        tizenContact.addresses = [];
+    }
+
+    // copy first url found to BlackBerry 'webpage' field
+    if (utils.isArray(contact.urls)) {
+        // if this is an update, re-initialize web page
+        if (update) {
+        }
+
+        var url = null,
+            urls = [];
+
+        for ( i = 0; i< contact.urls.length; i+= 1) {
+            url = contact.urls[i];
+
+            if (!url || !url.value) {
+                continue;
+            }
+
+            urls.push( new tizen.ContactWebSite(url.value, url.type));
+        }
+        tizenContact.urls = urls.length > 0 ? urls : [];
+    } else{
+        tizenContact.urls = [];
+    }
+
+    if (utils.isArray(contact.organizations && contact.organizations.length > 0) ) {
+        // if this is an update, re-initialize org attributes
+        var organization = contact.organizations[0];
+
+         tizenContact.organization = new tizen.ContacOrganization({
+             name:          organization.name,
+             department:    organization.department,
+             office:        "",
+             title:         organization.title,
+             role:          "",
+             logoURI:       ""
+         });
+    }
+
+    // categories
+    if (utils.isArray(contact.categories)) {
+        tizenContact.categories = [];
+
+        var category = null;
+
+        for (i = 0; i < contact.categories.length; i += 1) {
+            category = contact.categories[i];
+
+            if (typeof category === "string") {
+                tizenContact.categories.push(category);
+            }
+        }
+    }
+    else {
+        tizenContact.categories = [];
+    }
+
+    // save to device
+    // in tizen contact mean update or add
+    // later we might use addBatch and updateBatch
+    if (update){
+        tizen.contact.getDefaultAddressBook().update(tizenContact);
+    }
+    else {
+        tizen.contact.getDefaultAddressBook().add(tizenContact);
+    }
+
+    // Use the fully populated Tizen contact object to create a
+    // corresponding W3C contact object.
+    return ContactUtils.createContact(tizenContact, [ "*" ]);
+};
+
+
+/**
+ * Creates a Tizen ContactAddress object from a W3C ContactAddress.
+ *
+ * @return {tizen.ContactAddress} a Tizen ContactAddress object
+ */
+var createTizenAddress = function(address) {
+
+    var type = null,
+        pref = null,
+        typesAr = [];
+
+    if (address === null) {
+        return null;
+    }
+
+
+    var tizenAddress = new tizen.ContactAddress();
+
+    if (tizenAddress === null) {
+        return null;
+    }
+
+    typesAr.push(address.type);
+
+    if (address.pref) {
+        typesAr.push("PREF");
+    }
+
+    tizenAddress.country = address.country || "";
+    tizenAddress.region = address.region || "";
+    tizenAddress.city = address.locality || "";
+    tizenAddress.streetAddress = address.streetAddress || "";
+    tizenAddress.postalCode = address.postalCode || "";
+    tizenAddress.types = typesAr || "";
+
+    return tizenAddress;
+};
+
+module.exports = {
+    /**
+     * Persists contact to device storage.
+     */
+
+    save : function(successCB, failCB) {
+
+        try {
+            // save the contact and store it's unique id
+            var fullContact = saveToDevice(this);
+
+            this.id = fullContact.id;
+
+            // This contact object may only have a subset of properties
+            // if the save was an update of an existing contact. This is
+            // because the existing contact was likely retrieved using a
+            // subset of properties, so only those properties were set in the
+            // object. For this reason, invoke success with the contact object
+            // returned by saveToDevice since it is fully populated.
+
+            if (typeof successCB === 'function') {
+                successCB(fullContact);
+            }
+        }
+        catch (error) {
+            console.log('Error saving contact: ' +  error);
+
+            if (typeof failCB === 'function') {
+                failCB (new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    },
+
+    /**
+     * Removes contact from device storage.
+     *
+     * @param successCB
+     *            successCB callback
+     * @param failCB
+     *            error callback
+     */
+    remove : function (successCB, failCB) {
+
+        try {
+            // retrieve contact from device by id
+            var tizenContact = null;
+
+            if (this.id) {
+                tizenContact = findByUniqueId(this.id);
+            }
+
+
+            // if contact was found, remove it
+            if (tizenContact) {
+
+                tizen.contact.getDefaultAddressBook().remove(tizenContact.id);
+
+                if (typeof success === 'function') {
+                    successCB(this);
+                }
+            }
+            // attempting to remove a contact that hasn't been saved
+            else if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+        catch (error) {
+            console.log('Error removing contact ' + this.id + ": " + error);
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.UNKNOWN_ERROR));
+            }
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/ContactUtils.js
+define("cordova/plugin/tizen/ContactUtils", function(require, exports, module) {
+/*global tizen:false */
+var ContactAddress = require('cordova/plugin/ContactAddress'),
+    ContactName = require('cordova/plugin/ContactName'),
+    ContactField = require('cordova/plugin/ContactField'),
+    ContactOrganization = require('cordova/plugin/ContactOrganization'),
+    utils = require('cordova/utils'),
+    Contact = require('cordova/plugin/Contact');
+
+/**
+ * Mappings for each Contact field that may be used in a find operation. Maps
+ * W3C Contact fields to one or more fields in a Tizen contact object.
+ *
+ * Example: user searches with a filter on the Contact 'name' field:
+ *
+ * <code>Contacts.find(['name'], onSuccess, onFail, {filter:'Bob'});</code>
+ *
+ * The 'name' field does not exist in a Tizen contact. Instead, a filter
+ * expression will be built to search the Tizen contacts using the
+ * Tizen 'title', 'firstName' and 'lastName' fields.
+ */
+var fieldMappings = {
+    "id" : ["id"],
+    "displayName" : ["name.displayName"],
+    "nickname": ["name.nicknames"],
+    "name" : [ "name.prefix", "name.firstName", "name.lastName" ],
+    "phoneNumbers" : ["phoneNumbers.number","phoneNumbers.types"],
+    "emails" : ["emails.types", "emails.email"],
+    "addresses" : ["addresses.country","addresses.region","addresses.city","addresses.streetAddress","addresses.postalCode","addresses.country","addresses.types"],
+    "organizations" : ["organization.name","organization.department","organization.office", "organization.title"],
+    "birthday" : ["birthday"],
+    "note" : ["notes"],
+    "photos" : ["photoURI"],
+    "categories" : ["categories"],
+    "urls" : ["urls.url", "urls.type"]
+};
+
+/*
+ * Build an array of all of the valid W3C Contact fields. This is used to
+ * substitute all the fields when ["*"] is specified.
+ */
+var allFields = [];
+
+(function initializeAllFieldsMapping() {
+
+    for ( var key in fieldMappings) {
+        allFields.push(key);
+    }
+    // as we want it to be executed once
+    function initializeAllFieldsMapping() {
+    }
+
+})();
+
+/**
+ * Create a W3C ContactAddress object from a Tizen Address object
+ *
+ * @param {String}
+ *            type the type of address (e.g. work, home)
+ * @param {tizen.ContactAddress}
+ *            tizenAddress a Tizen Address object
+ * @return {ContactAddress} a contact address object or null if the specified
+ *         address is null
+ */
+var createContactAddress = function(type, tizenAddress) {
+    if (!tizenAddress) {
+        return null;
+    }
+
+    var streetAddress = tizenAddress.streetAddress;
+    var locality = tizenAddress.city || "";
+    var region = tizenAddress.region || "";
+    var postalCode = tizenAddress.postalCode || "";
+    var country = tizenAddress.country || "";
+    var formatted = streetAddress + ", " + locality + ", " + region + ", " + postalCode + ", " + country;
+
+    var contact = new ContactAddress(null, type, formatted, streetAddress, locality, region, postalCode, country);
+
+    return contact;
+};
+
+module.exports = {
+    /**
+     * Builds Tizen filter expressions for contact search using the
+     * contact fields and search filter provided.
+     *
+     * @param {String[]}
+     *            fields Array of Contact fields to search
+     * @param {String}
+     *            filter Filter, or search string
+     * @param {Boolean}
+     *                 multiple, one contacts or more wanted as result
+     * @return filter expression or null if fields is empty or filter is null or
+     *         empty
+     */
+
+    buildFilterExpression: function(fields, filter) {
+        // ensure filter exists
+        if (!filter || filter === "") {
+            return null;
+        }
+
+        if ((fields.length === 1) && (fields[0] === "*")) {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // build a filter expression using all Contact fields provided
+        var compositeFilter = null,
+            attributeFilter = null,
+            filterExpression = null,
+            matchFlag = "CONTAINS",
+            matchValue = filter,
+            attributesArray = [];
+
+        if (fields && utils.isArray(fields)) {
+
+            for ( var field in fields) {
+
+                if (!fields[field]) {
+                    continue;
+                }
+
+                // retrieve Tizen contact fields that map Cordova fields specified
+                // (tizenFields is a string or an array of strings)
+                var tizenFields = fieldMappings[fields[field]];
+
+                if (!tizenFields) {
+                    // does something maps
+                    continue;
+                }
+
+                // construct the filter expression using the Tizen fields
+                for ( var index in tizenFields) {
+                    attributeFilter = new tizen.AttributeFilter(tizenFields[index], matchFlag, matchValue);
+                    if (attributeFilter !== null) {
+                        attributesArray.push(attributeFilter);
+                    }
+                }
+            }
+        }
+
+        // fullfil tizen find attribute as a single or a composite attribute
+        if (attributesArray.length == 1 ) {
+            filterExpression = attributeFilter[0];
+        } else if (attributesArray.length > 1) {
+            // combine the filters as a Union
+            filterExpression = new tizen.CompositeFilter("UNION", attributesArray);
+        } else {
+            filterExpression = null;
+        }
+
+        return filterExpression;
+    },
+
+
+
+    /**
+     * Creates a Contact object from a Tizen Contact object, copying only
+     * the fields specified.
+     *
+     * This is intended as a privately used function but it is made globally
+     * available so that a Contact.save can convert a BlackBerry contact object
+     * into its W3C equivalent.
+     *
+     * @param {tizen.Contact}
+     *            tizenContact Tizen Contact object
+     * @param {String[]}
+     *            fields array of contact fields that should be copied
+     * @return {Contact} a contact object containing the specified fields or
+     *         null if the specified contact is null
+     */
+    createContact: function(tizenContact, fields) {
+
+        if (!tizenContact) {
+            return null;
+        }
+
+        // construct a new contact object
+        // always copy the contact id and displayName fields
+        var contact = new Contact(tizenContact.id, tizenContact.name.displayName);
+
+
+        // nothing to do
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            return contact;
+        } else if (fields.length === 1 && fields[0] === "*") {
+            // Cordova enhancement to allow fields value of ["*"] to indicate
+            // all supported fields.
+            fields = allFields;
+        }
+
+        // add the fields specified
+        for ( var key in fields) {
+
+            var field = fields[key],
+                index = 0;
+
+            if (!field) {
+                continue;
+            }
+
+            // name
+            if (field.indexOf('name') === 0) {
+
+                var formattedName = (tizenContact.name.prefix || "");
+
+                if (tizenContact.name.firstName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.firstName || "");
+                }
+
+                if (tizenContact.name.middleName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.middleName || "");
+                }
+
+                if (tizenContact.name.lastName) {
+                    formattedName += ' ';
+                    formattedName += (tizenContact.name.lastName || "");
+                }
+
+                contact.name = new ContactName(
+                        formattedName,
+                        tizenContact.name.lastName,
+                        tizenContact.name.firstName,
+                        tizenContact.name.middleName,
+                        tizenContact.name.prefix,
+                        null);
+            }
+
+            // phoneNumbers
+            else if (field.indexOf('phoneNumbers') === 0) {
+
+                var phoneNumbers = [];
+
+                for (index = 0 ; index < tizenContact.phoneNumbers.length ; ++index) {
+
+                    phoneNumbers.push(
+                            new ContactField(
+                                    'PHONE',
+                                    tizenContact.phoneNumbers[index].number,
+                                    ((tizenContact.phoneNumbers[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+
+
+                contact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : null;
+            }
+
+            // emails
+            else if (field.indexOf('emails') === 0) {
+
+                var emails = [];
+
+                for (index = 0 ; index < tizenContact.emails.length ; ++index) {
+
+                    emails.push(
+                        new ContactField(
+                            'EMAILS',
+                            tizenContact.emails[index].email,
+                            ((tizenContact.emails[index].types[1]) &&  (tizenContact.emails[index].types[1] === "PREF") ) ? true : false));
+                }
+                contact.emails = emails.length > 0 ? emails : null;
+            }
+
+            // addresses
+            else if (field.indexOf('addresses') === 0) {
+
+                var addresses = [];
+                for (index = 0 ; index < tizenContact.addresses.length ; ++index) {
+
+                    addresses.push(
+                            new ContactAddress(
+                                    ((tizenContact.addresses[index].types[1] &&  tizenContact.addresses[index].types[1] === "PREF") ? true : false),
+                                    tizenContact.addresses[index].types[0] ? tizenContact.addresses[index].types[0] : "HOME",
+                                    null,
+                                    tizenContact.addresses[index].streetAddress,
+                                    tizenContact.addresses[index].city,
+                                    tizenContact.addresses[index].region,
+                                    tizenContact.addresses[index].postalCode,
+                                    tizenContact.addresses[index].country ));
+                }
+
+                contact.addresses = addresses.length > 0 ? addresses : null;
+            }
+
+            // birthday
+            else if (field.indexOf('birthday') === 0) {
+                if (utils.isDate(tizenContact.birthday)) {
+                    contact.birthday = tizenContact.birthday;
+                }
+            }
+
+            // note only one in Tizen Contact
+            else if (field.indexOf('note') === 0) {
+                if (tizenContact.note) {
+                    contact.note = tizenContact.note[0];
+                }
+            }
+
+            // organizations
+            else if (field.indexOf('organizations') === 0) {
+
+                var organizations = [];
+
+                // there's only one organization in a Tizen Address
+
+                if (tizenContact.organization) {
+                    organizations.push(
+                            new ContactOrganization(
+                                    true,
+                                    'WORK',
+                                    tizenContact.organization.name,
+                                    tizenContact.organization.department,
+                                    tizenContact.organization.jobTitle));
+                }
+
+                contact.organizations = organizations.length > 0 ? organizations : null;
+            }
+
+            // categories
+            else if (field.indexOf('categories') === 0) {
+
+                var categories = [];
+
+                if (tizenContact.categories) {
+
+                    for (index = 0 ; index < tizenContact.categories.length ; ++index) {
+                        categories.push(
+                                new ContactField(
+                                        'MAIN',
+                                        tizenContact.categories,
+                                        (index === 0) ));
+                    }
+
+                    contact.categories = categories.length > 0 ? categories : null;
+                }
+            }
+
+            // urls
+            else if (field.indexOf('urls') === 0) {
+                var urls = [];
+
+                if (tizenContact.urls) {
+                    for (index = 0 ; index <tizenContact.urls.length ; ++index) {
+                        urls.push(
+                                new ContactField(
+                                        tizenContact.urls[index].type,
+                                        tizenContact.urls[index].url,
+                                        (index === 0)));
+                    }
+                }
+
+                contact.urls = urls.length > 0 ? urls : null;
+            }
+
+            // photos
+            else if (field.indexOf('photos') === 0) {
+                var photos = [];
+
+                if (tizenContact.photoURI) {
+                    photos.push(new ContactField('URI', tizenContact.photoURI, true));
+                }
+
+                contact.photos = photos.length > 0 ? photos : null;
+            }
+        }
+
+        return contact;
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Device.js
+define("cordova/plugin/tizen/Device", function(require, exports, module) {
+/*global tizen:false */
+var channel = require('cordova/channel');
+
+// Tell cordova channel to wait on the CordovaInfoReady event
+channel.waitForInitialization('onCordovaInfoReady');
+
+function Device() {
+    this.version = null;
+    this.uuid = null;
+    this.name = null;
+    this.cordova =  "2.0.0";
+    this.platform = "Tizen";
+
+    var me = this;
+
+    function onSuccessCallback(sysInfoProp) {
+        me.name = sysInfoProp.model;
+        me.uuid = sysInfoProp.imei;
+        me.version = sysInfoProp.version;
+        channel.onCordovaInfoReady.fire();
+    }
+
+    function onErrorCallback(error) {
+        console.log("error initializing cordova: " + error);
+    }
+
+    channel.onCordovaReady.subscribeOnce(function() {
+        me.getDeviceInfo(onSuccessCallback, onErrorCallback);
+    });
+}
+
+Device.prototype.getDeviceInfo = function(success, fail, args) {
+    tizen.systeminfo.getPropertyValue("Device", success, fail);
+};
+
+module.exports = new Device();
+
+});
+
+// file: lib/tizen/plugin/tizen/File.js
+define("cordova/plugin/tizen/File", function(require, exports, module) {
+/*global WebKitBlobBuilder:false */
+var FileError = require('cordova/plugin/FileError'),
+    DirectoryEntry = require('cordova/plugin/DirectoryEntry'),
+    FileEntry = require('cordova/plugin/FileEntry'),
+    File = require('cordova/plugin/File'),
+    FileSystem = require('cordova/plugin/FileSystem');
+
+var nativeRequestFileSystem = window.webkitRequestFileSystem,
+    nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL,
+    NativeFileReader = window.FileReader;
+
+function getFileSystemName(nativeFs) {
+    return (nativeFs.name.indexOf("Persistent") != -1) ? "persistent" : "temporary";
+}
+
+function makeEntry(entry) {
+    if (entry.isDirectory) {
+        return new DirectoryEntry(entry.name, decodeURI(entry.toURL()));
+    }
+    else {
+        return new FileEntry(entry.name, decodeURI(entry.toURL()));
+    }
+}
+
+module.exports = {
+    /* requestFileSystem */
+    requestFileSystem: function(successCallback, errorCallback, args) {
+        var type = args[0],
+            size = args[1];
+
+        nativeRequestFileSystem(type, size, function(nativeFs) {
+            successCallback(new FileSystem(getFileSystemName(nativeFs), makeEntry(nativeFs.root)));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* resolveLocalFileSystemURI */
+    resolveLocalFileSystemURI: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            successCallback(makeEntry(entry));
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryReader */
+    readEntries: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(dirEntry) {
+            var reader = dirEntry.createReader();
+            reader.readEntries(function(entries) {
+                var retVal = [];
+                for (var i = 0; i < entries.length; i++) {
+                    retVal.push(makeEntry(entries[i]));
+                }
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* Entry */
+    getMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getMetadata(function(metaData) {
+                successCallback(metaData.modificationTime);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    moveTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.moveTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    copyTo: function(successCallback, errorCallback, args) {
+        var srcUri = args[0],
+            parentUri = args[1],
+            name = args[2];
+
+        nativeResolveLocalFileSystemURI(srcUri, function(source) {
+            nativeResolveLocalFileSystemURI(parentUri, function(parent) {
+                source.copyTo(parent, name, function(entry) {
+                    successCallback(makeEntry(entry));
+                }, function(error) {
+                    errorCallback(error.code);
+                });
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    remove: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.remove(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getParent: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getParent(function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileEntry */
+    getFileMetadata: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.file(function(file) {
+                var retVal = new File(file.name, decodeURI(entry.toURL()), file.type, file.lastModifiedDate, file.size);
+                successCallback(retVal);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* DirectoryEntry */
+    getDirectory: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getDirectory(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    removeRecursively: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            if (entry.fullPath === "/") {
+                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            } else {
+                entry.removeRecursively(successCallback, function(error) {
+                    errorCallback(error.code);
+                });
+            }
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    getFile: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            path = args[1],
+            options = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            entry.getFile(path, options, function(entry) {
+                successCallback(makeEntry(entry));
+            }, function(error) {
+                if (error.code === FileError.INVALID_MODIFICATION_ERR) {
+                    if (options.create) {
+                        errorCallback(FileError.PATH_EXISTS_ERR);
+                    } else {
+                        errorCallback(FileError.ENCODING_ERR);
+                    }
+                } else {
+                    errorCallback(error.code);
+                }
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileReader */
+    readAsText: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            encoding = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsText(file, encoding);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    readAsDataURL: function(successCallback, errorCallback, args) {
+        var uri = args[0];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onLoadEnd = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(evt.target.result);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            var reader = new NativeFileReader();
+
+            reader.onloadend = onLoadEnd;
+            reader.onerror = onError;
+            entry.file(function(file) {
+                reader.readAsDataURL(file);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    /* FileWriter */
+    write: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            text = args[1],
+            position = args[2];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.position - position);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                var blob = new WebKitBlobBuilder();
+                blob.append(text);
+
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.seek(position);
+                writer.write(blob.getBlob('text/plain'));
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    },
+
+    truncate: function(successCallback, errorCallback, args) {
+        var uri = args[0],
+            size = args[1];
+
+        nativeResolveLocalFileSystemURI(uri, function(entry) {
+            var onWriteEnd = function(evt) {
+                    if(!evt.target.error) {
+                        successCallback(evt.target.length);
+                    } else {
+                        errorCallback(evt.target.error.code);
+                    }
+            },
+                onError = function(evt) {
+                    errorCallback(evt.target.error.code);
+            };
+
+            entry.createWriter(function(writer) {
+                writer.onwriteend = onWriteEnd;
+                writer.onerror = onError;
+
+                writer.truncate(size);
+            }, function(error) {
+                errorCallback(error.code);
+            });
+        }, function(error) {
+            errorCallback(error.code);
+        });
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/FileTransfer.js
+define("cordova/plugin/tizen/FileTransfer", function(require, exports, module) {
+/*global WebKitBlobBuilder:false */
+var FileEntry = require('cordova/plugin/FileEntry'),
+    FileTransferError = require('cordova/plugin/FileTransferError'),
+    FileUploadResult = require('cordova/plugin/FileUploadResult');
+
+var nativeResolveLocalFileSystemURI = window.webkitResolveLocalFileSystemURL;
+
+function getParentPath(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(0, pos + 1);
+}
+
+function getFileName(filePath) {
+    var pos = filePath.lastIndexOf('/');
+    return filePath.substring(pos + 1);
+}
+
+module.exports = {
+    upload: function(successCallback, errorCallback, args) {
+        var filePath = args[0],
+            server = args[1],
+            fileKey = args[2],
+            fileName = args[3],
+            mimeType = args[4],
+            params = args[5],
+            /*trustAllHosts = args[6],*/
+            chunkedMode = args[7];
+
+        nativeResolveLocalFileSystemURI(filePath, function(entry) {
+            entry.file(function(file) {
+                function uploadFile(blobFile) {
+                    var fd = new FormData();
+
+                    fd.append(fileKey, blobFile, fileName);
+                    for (var prop in params) {
+                        if(params.hasOwnProperty(prop)) {
+                            fd.append(prop, params[prop]);
+                        }
+                    }
+
+                    var xhr = new XMLHttpRequest();
+                    xhr.open("POST", server);
+                    xhr.onload = function(evt) {
+                        if (xhr.status == 200) {
+                            var result = new FileUploadResult();
+                            result.bytesSent = file.size;
+                            result.responseCode = xhr.status;
+                            result.response = xhr.response;
+                            successCallback(result);
+                        } else if (xhr.status == 404) {
+                            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                        } else {
+                            errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                        }
+                    };
+                    xhr.ontimeout = function(evt) {
+                        errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                    };
+
+                    xhr.send(fd);
+                }
+
+                var bytesPerChunk;
+                if (chunkedMode === true) {
+                    bytesPerChunk = 1024 * 1024; // 1MB chunk sizes.
+                } else {
+                    bytesPerChunk = file.size;
+                }
+                var start = 0;
+                var end = bytesPerChunk;
+                while (start < file.size) {
+                    var chunk = file.webkitSlice(start, end, mimeType);
+                    uploadFile(chunk);
+                    start = end;
+                    end = start + bytesPerChunk;
+                }
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            }
+            );
+        },
+        function(error) {
+            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+        }
+        );
+    },
+
+    download: function(successCallback, errorCallback, args) {
+        var url = args[0],
+            filePath = args[1];
+
+        var xhr = new XMLHttpRequest();
+
+        function writeFile(fileEntry) {
+            fileEntry.createWriter(function(writer) {
+                writer.onwriteend = function(evt) {
+                    if (!evt.target.error) {
+                        successCallback(new FileEntry(fileEntry.name, fileEntry.toURL()));
+                    } else {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    }
+                };
+
+                writer.onerror = function(evt) {
+                    errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                };
+
+                var builder = new WebKitBlobBuilder();
+                builder.append(xhr.response);
+                var blob = builder.getBlob();
+                writer.write(blob);
+            },
+            function(error) {
+                errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+            });
+        }
+
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == xhr.DONE) {
+                if (xhr.status == 200 && xhr.response) {
+                    nativeResolveLocalFileSystemURI(getParentPath(filePath), function(dir) {
+                        dir.getFile(getFileName(filePath), {create: true}, writeFile, function(error) {
+                            errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                        });
+                    }, function(error) {
+                        errorCallback(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR));
+                    });
+                } else if (xhr.status == 404) {
+                    errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR));
+                } else {
+                    errorCallback(new FileTransferError(FileTransferError.CONNECTION_ERR));
+                }
+            }
+        };
+
+        xhr.open("GET", url, true);
+        xhr.responseType = "arraybuffer";
+        xhr.send();
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Media.js
+define("cordova/plugin/tizen/Media", function(require, exports, module) {
+/*global Media:false, webkitURL:false */
+var MediaError = require('cordova/plugin/MediaError'),
+    audioObjects = {};
+
+module.exports = {
+    create: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::create() - id =" + id + ", src =" + src);
+        audioObjects[id] = new Audio(src);
+        audioObjects[id].onStalledCB = function () {
+            console.log("media::onStalled()");
+             audioObjects[id].timer = window.setTimeout(function () {
+                    audioObjects[id].pause();
+                    if (audioObjects[id].currentTime !== 0)
+                        audioObjects[id].currentTime = 0;
+                    console.log("media::onStalled() - MEDIA_ERROR -> " + MediaError.MEDIA_ERR_ABORTED);
+                    var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, "Stalled");
+                    Media.onStatus(id, Media.MEDIA_ERROR, err);
+                }, 2000);
+        };
+        audioObjects[id].onEndedCB = function () {
+            console.log("media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        };
+        audioObjects[id].onErrorCB = function () {
+            console.log("media::onErrorCB() - MEDIA_ERROR -> " + event.srcElement.error);
+            Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error);
+        };
+        audioObjects[id].onPlayCB = function () {
+            console.log("media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
+        };
+        audioObjects[id].onPlayingCB = function () {
+            console.log("media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING");
+            Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);
+        };
+        audioObjects[id].onDurationChangeCB = function () {
+            console.log("media::onDurationChangeCB() - MEDIA_DURATION -> " +  audioObjects[id].duration);
+            Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration);
+        };
+        audioObjects[id].onTimeUpdateCB = function () {
+            console.log("media::onTimeUpdateCB() - MEDIA_POSITION -> " +  audioObjects[id].currentTime);
+            Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime);
+        };
+        audioObjects[id].onCanPlayCB = function () {
+            console.log("media::onCanPlayCB()");
+            window.clearTimeout(audioObjects[id].timer);
+            audioObjects[id].play();
+        };
+      },
+    startPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1], options = args[2];
+        console.log("media::startPlayingAudio() - id =" + id + ", src =" + src + ", options =" + options);
+        audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB);
+        audioObjects[id].play();
+    },
+    stopPlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        audioObjects[id].pause();
+        if (audioObjects[id].currentTime !== 0)
+            audioObjects[id].currentTime = 0;
+        console.log("media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED");
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
+        audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB);
+        audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB);
+        audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
+        audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB);
+        audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB);
+        audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB);
+        audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB);
+    },
+    seekToAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], milliseconds = args[1];
+        console.log("media::seekToAudio()");
+         audioObjects[id].currentTime = milliseconds;
+        successCallback( audioObjects[id].currentTime);
+    },
+    pausePlayingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED");
+        audioObjects[id].pause();
+        Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED);
+    },
+    getCurrentPositionAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::getCurrentPositionAudio()");
+        successCallback(audioObjects[id].currentTime);
+    },
+    release: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        window.clearTimeout(audioObjects[id].timer);
+        console.log("media::release()");
+    },
+    setVolume: function (successCallback, errorCallback, args) {
+        var id = args[0], volume = args[1];
+        console.log("media::setVolume()");
+        audioObjects[id].volume = volume;
+    },
+    startRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0], src = args[1];
+        console.log("media::startRecordingAudio() - id =" + id + ", src =" + src);
+
+        function gotStreamCB(stream) {
+            audioObjects[id].src = webkitURL.createObjectURL(stream);
+            console.log("media::startRecordingAudio() - stream CB");
+        }
+
+        function gotStreamFailedCB(error) {
+            console.log("media::startRecordingAudio() - error CB:" + error.toString());
+        }
+
+        if (navigator.webkitGetUserMedia) {
+            audioObjects[id] = new Audio();
+            navigator.webkitGetUserMedia('audio', gotStreamCB, gotStreamFailedCB);
+        } else {
+            console.log("webkitGetUserMedia not supported");
+        }
+        successCallback();
+    },
+    stopRecordingAudio: function (successCallback, errorCallback, args) {
+        var id = args[0];
+        console.log("media::stopRecordingAudio() - id =" + id);
+        audioObjects[id].pause();
+        successCallback();
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/MediaError.js
+define("cordova/plugin/tizen/MediaError", function(require, exports, module) {
+
+// The MediaError object already exists on Tizen. This prevents the Cordova
+// version from being defined. This object is used to merge in differences
+// between Tizen and Cordova MediaError objects.
+module.exports = {
+        MEDIA_ERR_NONE_ACTIVE : 0,
+        MEDIA_ERR_NONE_SUPPORTED : 4
+};
+});
+
+// file: lib/tizen/plugin/tizen/NetworkStatus.js
+define("cordova/plugin/tizen/NetworkStatus", function(require, exports, module) {
+/*global tizen:false */
+var Connection = require('cordova/plugin/Connection');
+
+module.exports = {
+    getConnectionInfo: function (successCallback, errorCallback) {
+        var cncType = Connection.NONE;
+        var infoCount = 0;
+
+        function infoCB() {
+            infoCount++;
+            if (infoCount > 1)
+               successCallback(cncType);
+        }
+
+        function errorCB(error) {
+           console.log("Error: " + error.code + "," + error.name + "," + error.message);
+           infoCB();
+        }
+
+        function wifiSuccessCB(wifi) {
+            if ((wifi.status === "ON")  && (wifi.ipAddress.length !== 0))
+                cncType = Connection.WIFI;
+            infoCB();
+        }
+
+        function cellularSuccessCB(cell) {
+            if ((cncType === Connection.NONE) && (cell.status === "ON") && (cell.ipAddress.length !== 0))
+                cncType = Connection.CELL_2G;
+            infoCB();
+        }
+
+        if (tizen.systeminfo.isSupported('WifiNetwork')) {
+            tizen.systeminfo.getPropertyValue('WifiNetwork', wifiSuccessCB, errorCB);
+        }
+
+        if (tizen.systeminfo.isSupported('CellularNetwork')) {
+            tizen.systeminfo.getPropertyValue('CellularNetwork', cellularSuccessCB, errorCB);
+        }
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/Notification.js
+define("cordova/plugin/tizen/Notification", function(require, exports, module) {
+var SoundBeat = require('cordova/plugin/tizen/SoundBeat');
+
+/* TODO: get resource path from app environment? */
+var soundBeat = new SoundBeat(["./sounds/beep.wav"]);
+
+module.exports = {
+
+    alert: function(message, alertCallback, title, buttonName) {
+        return this.confirm(message, alertCallback, title, buttonName);
+    },
+
+    confirm: function(message, confirmCallback, title, buttonLabels) {
+        var index            =    null,
+            overlayElement    =    null,
+            popup            =    null,
+            element         =    null,
+            titleString        =     null,
+            messageString    =    null,
+            buttonString    =    null,
+            buttonsArray    =    null;
+
+
+        console.log ("message" , message);
+        console.log ("confirmCallback" , confirmCallback);
+        console.log ("title" , title);
+        console.log ("buttonLabels" , buttonLabels);
+
+        titleString = '<div class="popup-title"><p>' + title + '</p></div>';
+        messageString = '<div class="popup-text"><p>' + message + '</p></div>';
+        buttonString = '<div class="popup-button-bg"><ul>';
+
+        switch(typeof(buttonLabels))
+        {
+        case "string":
+            buttonsArray = buttonLabels.split(",");
+
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+
+        case "array":
+            if (buttonsArray === null) {
+                buttonsArray = buttonLabels;
+            }
+
+            for (index in buttonsArray) {
+                buttonString += '<li><input id="popup-button-' + buttonsArray[index]+
+                                '" type="button" value="' + buttonsArray[index] + '" /></li>';
+                console.log ("index: ", index,"");
+                console.log ("buttonsArray[index]: ", buttonsArray[index]);
+                console.log ("buttonString: ", buttonString);
+            }
+            break;
+        default:
+            console.log ("cordova/plugin/tizen/Notification, default, buttonLabels: ", buttonLabels);
+            break;
+        }
+
+        buttonString += '</ul></div>';
+
+        overlayElement = document.createElement("div");
+        overlayElement.className = 'ui-popupwindow-screen';
+
+        overlayElement.style.zIndex = 1001;
+        overlayElement.style.width = "100%";
+        overlayElement.style.height = "100%";
+        overlayElement.style.top = 0;
+        overlayElement.style.left = 0;
+        overlayElement.style.margin = 0;
+        overlayElement.style.padding = 0;
+        overlayElement.style.position = "absolute";
+
+        popup = document.createElement("div");
+        popup.className = "ui-popupwindow";
+        popup.style.position = "fixed";
+        popup.style.zIndex = 1002;
+        popup.innerHTML = titleString + messageString + buttonString;
+
+        document.body.appendChild(overlayElement);
+        document.body.appendChild(popup);
+
+        function createListener(button) {
+            return function() {
+                document.body.removeChild(overlayElement);
+                document.body.removeChild(popup);
+                confirmCallback(button.value);
+            };
+        }
+
+       for (index in buttonsArray) {
+           console.log ("index: ", index);
+
+           element = document.getElementById("popup-button-" + buttonsArray[index]);
+           element.addEventListener("click", createListener(element), false);
+       }
+    },
+
+    vibrate: function(milliseconds) {
+        console.log ("milliseconds" , milliseconds);
+
+        if (navigator.vibrate) {
+            navigator.vibrate(milliseconds);
+        }
+        else {
+            console.log ("cordova/plugin/tizen/Notification, vibrate API does not exists");
+        }
+    },
+
+    beep: function(count) {
+        console.log ("count" , count);
+        soundBeat.play(count);
+    }
+};
+
+
+
+});
+
+// file: lib/tizen/plugin/tizen/SoundBeat.js
+define("cordova/plugin/tizen/SoundBeat", function(require, exports, module) {
+/*global webkitAudioContext:false */
+/*
+ *  SoundBeat
+ * used by Notification Manager beep method
+ *
+ * This class provides sounds play
+ *
+ * uses W3C  Web Audio API
+ * uses BufferLoader object
+ *
+ * NOTE: the W3C Web Audio doc tells we do not need to recreate the audio
+ *       context to play a sound but only the audiosourcenode (createBufferSource)
+ *       in the webkit implementation we have to.
+ *
+ */
+
+var BufferLoader = require('cordova/plugin/tizen/BufferLoader');
+
+function SoundBeat(urlList) {
+    this.context = null;
+    this.urlList = urlList || null;
+    this.buffers = null;
+}
+
+/*
+ * This method play a loaded sounds on the Device
+ * @param {Number} times Number of times to play loaded sounds.
+ *
+ */
+SoundBeat.prototype.play = function(times) {
+
+    var i = 0, sources = [], that = this;
+
+    function finishedLoading (bufferList) {
+        that.buffers = bufferList;
+
+        for (i = 0; i < that.buffers.length ; i +=1) {
+            if (that.context) {
+                sources[i] = that.context.createBufferSource();
+
+                sources[i].buffer = that.buffers[i];
+                sources[i].connect (that.context.destination);
+
+                sources[i].loop = true;
+                sources[i].noteOn (0);
+                sources[i].noteOff(sources[i].buffer.duration * times);
+            }
+        }
+    }
+
+    if (webkitAudioContext !== null) {
+        this.context = new webkitAudioContext();
+    }
+    else {
+        console.log ("SoundBeat.prototype.play, w3c web audio api not supported");
+        this.context = null;
+    }
+
+    if (this.context === null) {
+        console.log ("SoundBeat.prototype.play, cannot create audio context object");
+        return;
+    }
+
+    this.bufferLoader = new BufferLoader (this.context, this.urlList, finishedLoading);
+    if (this.bufferLoader === null) {
+        console.log ("SoundBeat.prototype.play, cannot create buffer loader object");
+        return;
+    }
+
+    this.bufferLoader.load();
+};
+
+module.exports = SoundBeat;
+
+});
+
+// file: lib/tizen/plugin/tizen/contacts.js
+define("cordova/plugin/tizen/contacts", function(require, exports, module) {
+/*global tizen:false */
+var ContactError = require('cordova/plugin/ContactError'),
+    utils = require('cordova/utils'),
+    ContactUtils = require('cordova/plugin/tizen/ContactUtils');
+
+module.exports = {
+    /**
+     * Returns an array of Contacts matching the search criteria.
+     *
+     * @return array of Contacts matching search criteria
+     */
+    find : function(fields, successCB, failCB, options) {
+
+        // Success callback is required. Throw exception if not specified.
+        if (typeof successCB !== 'function') {
+            throw new TypeError("You must specify a success callback for the find command.");
+        }
+
+        // Search qualifier is required and cannot be empty.
+        if (!fields || !(utils.isArray(fields)) || fields.length === 0) {
+            if (typeof failCB === 'function') {
+                failCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR));
+            }
+            return;
+        }
+
+        // options are optional
+        var filter ="",
+            multiple = false,
+            contacts = [],
+            tizenFilter = null;
+
+        if (options) {
+            filter = options.filter || "";
+            multiple =  options.multiple || false;
+        }
+
+        if (filter){
+            tizenFilter = ContactUtils.buildFilterExpression(fields, filter);
+        }
+
+        tizen.contact.getDefaultAddressBook().find(
+            function(tizenContacts) {
+                if (multiple) {
+                    for (var index in tizenContacts) {
+                        contacts.push(ContactUtils.createContact(tizenContacts[index], fields));
+                    }
+                }
+                else {
+                    contacts.push(ContactUtils.createContact(tizenContacts[0], fields));
+                }
+
+                // return results
+                successCB(contacts);
+            },
+            function(error) {
+                if (typeof failCB === 'function') {
+                    failCB(ContactError.UNKNOWN_ERROR);
+                }
+            },
+            tizenFilter,
+            null);
+    }
+};
+
+});
+
+// file: lib/tizen/plugin/tizen/manager.js
+define("cordova/plugin/tizen/manager", function(require, exports, module) {
+var cordova = require('cordova');
+
+module.exports = {
+    exec: function (successCallback, errorCallback, clazz, action, args) {
+        var plugin = require('cordova/plugin/tizen/' + clazz);
+
+        if (plugin && typeof plugin[action] === 'function') {
+            var result = plugin[action](successCallback, errorCallback, args);
+            return result || {status: cordova.callbackStatus.NO_RESULT};
+        }
+
+        return {"status" : cordova.callbackStatus.CLASS_NOT_FOUND_EXCEPTION, "message" : "Function " + clazz + "::" + action + " cannot be found"};
+    },
+    resume: function () {},
+    pause: function () {},
+    destroy: function () {}
+};
+
+});
+
+// file: lib/common/utils.js
+define("cordova/utils", function(require, exports, module) {
+var utils = exports;
+
+/**
+ * Returns an indication of whether the argument is an array or not
+ */
+utils.isArray = function(a) {
+    return Object.prototype.toString.call(a) == '[object Array]';
+};
+
+/**
+ * Returns an indication of whether the argument is a Date or not
+ */
+utils.isDate = function(d) {
+    return Object.prototype.toString.call(d) == '[object Date]';
+};
+
+/**
+ * Does a deep clone of the object.
+ */
+utils.clone = function(obj) {
+    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
+        return obj;
+    }
+
+    var retVal, i;
+
+    if(utils.isArray(obj)){
+        retVal = [];
+        for(i = 0; i < obj.length; ++i){
+            retVal.push(utils.clone(obj[i]));
+        }
+        return retVal;
+    }
+
+    retVal = {};
+    for(i in obj){
+        if(!(i in retVal) || retVal[i] != obj[i]) {
+            retVal[i] = utils.clone(obj[i]);
+        }
+    }
+    return retVal;
+};
+
+/**
+ * Returns a wrappered version of the function
+ */
+utils.close = function(context, func, params) {
+    if (typeof params == 'undefined') {
+        return function() {
+            return func.apply(context, arguments);
+        };
+    } else {
+        return function() {
+            return func.apply(context, params);
+        };
+    }
+};
+
+/**
+ * Create a UUID
+ */
+utils.createUUID = function() {
+    return UUIDcreatePart(4) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(6);
+};
+
+/**
+ * Extends a child object from a parent object using classical inheritance
+ * pattern.
+ */
+utils.extend = (function() {
+    // proxy used to establish prototype chain
+    var F = function() {};
+    // extend Child from Parent
+    return function(Child, Parent) {
+        F.prototype = Parent.prototype;
+        Child.prototype = new F();
+        Child.__super__ = Parent.prototype;
+        Child.prototype.constructor = Child;
+    };
+}());
+
+/**
+ * Alerts a message in any available way: alert or console.log.
+ */
+utils.alert = function(msg) {
+    if (alert) {
+        alert(msg);
+    } else if (console && console.log) {
+        console.log(msg);
+    }
+};
+
+/**
+ * Formats a string and arguments following it ala sprintf()
+ *
+ * see utils.vformat() for more information
+ */
+utils.format = function(formatString /* ,... */) {
+    var args = [].slice.call(arguments, 1);
+    return utils.vformat(formatString, args);
+};
+
+/**
+ * Formats a string and arguments following it ala vsprintf()
+ *
+ * format chars:
+ *   %j - format arg as JSON
+ *   %o - format arg as JSON
+ *   %c - format arg as ''
+ *   %% - replace with '%'
+ * any other char following % will format it's
+ * arg via toString().
+ *
+ * for rationale, see FireBug's Console API:
+ *    http://getfirebug.com/wiki/index.php/Console_API
+ */
+utils.vformat = function(formatString, args) {
+    if (formatString === null || formatString === undefined) return "";
+    if (arguments.length == 1) return formatString.toString();
+    if (typeof formatString != "string") return formatString.toString();
+
+    var pattern = /(.*?)%(.)(.*)/;
+    var rest    = formatString;
+    var result  = [];
+
+    while (args.length) {
+        var arg   = args.shift();
+        var match = pattern.exec(rest);
+
+        if (!match) break;
+
+        rest = match[3];
+
+        result.push(match[1]);
+
+        if (match[2] == '%') {
+            result.push('%');
+            args.unshift(arg);
+            continue;
+        }
+
+        result.push(formatted(arg, match[2]));
+    }
+
+    result.push(rest);
+
+    return result.join('');
+};
+
+//------------------------------------------------------------------------------
+function UUIDcreatePart(length) {
+    var uuidpart = "";
+    for (var i=0; i<length; i++) {
+        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
+        if (uuidchar.length == 1) {
+            uuidchar = "0" + uuidchar;
+        }
+        uuidpart += uuidchar;
+    }
+    return uuidpart;
+}
+
+//------------------------------------------------------------------------------
+function formatted(object, formatChar) {
+
+    try {
+        switch(formatChar) {
+            case 'j':
+            case 'o': return JSON.stringify(object);
+            case 'c': return '';
+        }
+    }
+    catch (e) {
+        return "error JSON.stringify()ing argument: " + e;
+    }
+
+    if ((object === null) || (object === undefined)) {
+        return Object.prototype.toString.call(object);
+    }
+
+    return object.toString();
+}
+
+});
+
+
+window.cordova = require('cordova');
+
+// file: lib/scripts/bootstrap.js
+(function (context) {
+    var channel = require("cordova/channel"),
+        _self = {
+            boot: function () {
+                /**
+                 * Create all cordova objects once page has fully loaded and native side is ready.
+                 */
+                channel.join(function() {
+                    var builder = require('cordova/builder'),
+                        base = require('cordova/common'),
+                        platform = require('cordova/platform');
+
+                    // Drop the common globals into the window object, but be nice and don't overwrite anything.
+                    builder.build(base.objects).intoButDontClobber(window);
+
+                    // Drop the platform-specific globals into the window object
+                    // and clobber any existing object.
+                    builder.build(platform.objects).intoAndClobber(window);
+
+                    // Merge the platform-specific overrides/enhancements into
+                    // the window object.
+                    if (typeof platform.merges !== 'undefined') {
+                        builder.build(platform.merges).intoAndMerge(window);
+                    }
+
+                    // Call the platform-specific initialization
+                    platform.initialize();
+
+                    // Fire event to notify that all objects are created
+                    channel.onCordovaReady.fire();
+
+                    // Fire onDeviceReady event once all constructors have run and
+                    // cordova info has been received from native side.
+                    channel.join(function() {
+                        require('cordova').fireDocumentEvent('deviceready');
+                    }, channel.deviceReadyChannelsArray);
+
+                }, [ channel.onDOMContentLoaded, channel.onNativeReady ]);
+            }
+        };
+
+    // boot up once native side is ready
+    channel.onNativeReady.subscribeOnce(_self.boot);
+
+    // _nativeReady is global variable that the native side can set
+    // to signify that the native code is ready. It is a global since
+    // it may be called before any cordova JS is ready.
+    if (window._nativeReady) {
+        channel.onNativeReady.fire();
+    }
+
+}(window));
+
+// file: lib/scripts/bootstrap-tizen.js
+require('cordova/channel').onNativeReady.fire();
+
+
+})();
\ No newline at end of file
