diff --git a/Android/AugmentedReality-Wikitude/Documentation/Documentation.md b/Android/AugmentedReality-Wikitude/Documentation/Documentation.md new file mode 100644 index 0000000..6e4b202 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/Documentation/Documentation.md @@ -0,0 +1,116 @@ +## Wikitude PhoneGap Plugin Documentation +by ``` Wikitude GmbH ``` + + +### DESCRIPTION +*** + +This document describes all available PhoneGap bindings which exists in the Wikitude PhoneGap Plugin. + + +#### Getting information about the device + +###### isDeviceSupported +Call ``` isDeviceSupported ``` to determinate if the current device is capable of launching ARchitect Worlds. + + @param onSuccessCallback - A callback which gets called if the current device supports launching ARchitect Worlds + @param onErrorCallback - An callback which gets called if the current device does not fulfil all needs to lauch ARchitect Worlds + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(deviceSupportedCallback, deviceNotSupportedCallback, "WikitudePlugin", "isDeviceSupported", [""]); + + +#### Managing the ARchitectView + + +###### open +Call open to add the ARchitectView to your applications view hierarchy and loads the specified ARchitect World. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - a dictionary containing two pairs: + @pair apiKey : The Wikitude SDK Key provided to you after you purchased the Wikitude SDK or an empty string if you're using a trial version + @pair filePath : A filepath to a local bundle resource or to a file on e.g. your dropbox + + cordova.exec(architectWorldLaunchedCallback, architectWorldFailedLaunchingCallback, "WikitudePlugin", "open", [{ apiKey: myApiKey, filePath: worldPath}]); + +###### close +This call will remove the ARchitectView from the view hierarchy and also stops all ongoing Wikitude updates. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "close", [""]); + +###### show +This call hides the ARchitectView, but keeps it alive in memory. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "hide", [""]); + +###### hide +This call will show the ARchitectView again if it was hidden with the ``` hide ``` call. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "show", [""]); + + + +#### Interacting with the ARchitectView + +###### callJavaScript +This function will evaluate the passed JavaScript in the current ARchitect World context. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - A JavaScript array with a JavaScript string at first position + + cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "callJavascript", [js]); + +###### onUrlInvoke +This function will set an callback which gets called if you call ``` document.location = architectsdk://aRequestWithParameters?id=5&name=Poi5 ```. + + @param onSuccessCallback - A callback which gets called every time you call ` architectsdk:// ` + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(onUrlInvokeCallback, onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]); + +###### setLocation +This function allows you to set a location for your current ARchitectView + + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - A dictionary containing the new latitude, longitude, altitude, accuracy + @pair lat : The new latitude + @pair lon : The new longitude + @pair alt : The new altitude + @pair acc : The accuracy of the new locations + + cordova.exec(onUrlInvokeCallback, onWikitudeError, "WikitudePlugin", "setLocation", [""]); + + diff --git a/Android/AugmentedReality-Wikitude/Plugin/README.md b/Android/AugmentedReality-Wikitude/Plugin/README.md new file mode 100644 index 0000000..559cb20 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/Plugin/README.md @@ -0,0 +1,110 @@ +# Augmented Reality - Wikitude SDK Plugin +by Wikitude GmbH - [www.wikitude.com](http://www.wikitude.com) + +Interested in advanced usage of the plugin and need assistance? +[Register as a Wikitude developer](http://developer.wikitude.com) and get support in our forum. + +For further questions visit us on www.wikitude.com or contact us via `phonegap wikitude.com` + +#### Important: This plugin runs on latest [PhoneGap 2.x](http://docs.phonegap.com/en/2.0.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android) only + + +## DESCRIPTION + + +The Wikitude PhoneGap Plugin enables web developers to embed an Augmented Reality view into their PhoneGap project. One can create a fully featured app with advanced Augmented Reality features, including Image Recognition, purely using HTML, CSS and Javascript. + +###The Wikitude PhoneGap Plugin + +* Available for iOS and Android +* Simple and seamless native PhoneGap integration +* Fully customizable Augmented Realty view +* Includes the full feature set of the Wikitude SDK +* AR content is purely written in HTML and JavaScript + +![image](http://www.wikitude.com/wp-content/uploads/2012/09/Plugin_Phonegap.png) + +###The Augmented Reality View +From a technical point of view the SDK adds a UI component, similar to a web view. In contrast to a standard web view this AR view can render Augmented Reality content. + +Note: Content developed for this AR View is written in JavaScript and HTML. The .html and .js files for this view are different from the PhoneGap .js and .html files. The AR engine working in the background is called ARchitect Engine and is powering the SDK. + +###Further developer resources +* [Full documentation and additional tutorials](http://forum.wikitude.com/documentation) +* [Developer Forum](http://forum.wikitude.com/home) +* [Wikitude SDK Download](http://forum.wikitude.com/download) +* [Google+ Page for News](https://plus.google.com/u/0/103004921345651739447/posts) +* [Developer Newsletter](http://www.wikitude.com/developer/newsletter) + + + +##Prerequisites +* Having set-up [PhoneGap 2.x](http://docs.phonegap.com/en/2.0.0/guide_getting- + started_android_index.md.html#Getting%20Started%20with%20Android) project. +* In case you didn't set `` or higher in `AndroidManifest.xml` be aware that the Wikitude SDK runs only on Android 2.2+ devices (=Android SDK v8); you must not call the plugin on devices with lower SDK version. + +## SETUP - 'Basic' Plugin + + +1. Create a folder called `com/wikitude/phonegap` within your project's `src`- folder and copy `WikitudePlugin.java` into it + +2. Add following line to your `res/xml/config.xml` + + `` + +3. Copy `WikitudePlugin.js` in `assets/www`-folder and ensure to include it in the related HTMLs. + + +4. Download the [Wikitude SDK](http://www.wikitude.com), copy the wikitudesdk.jar in the Android-folder to your projects `libs`-folder and add it to your project's build path + +5. Visit [Wikitude Developer Site](http://developer.wikitude.com) to find Samples and license your app to get rid of the watermarking + + + +## Optional SETUP - 'Extended' Plugin (incl. Vuforia ImageRecognition) + +####In case you use ImageRecognition in your project, you need to use this Extended Plugin instead of the Basic One. + +Prerequisites: Having already set-up your [PhoneGap 2.x](http://docs.phonegap.com/en/2.0.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android) project. + +1. Create a folder called `com/wikitude/phonegap` within your project's `src/` folder and opy `WikitudePlugin.java` and `WikitudePluginVuforia.java` into it. + +2. Add following line to your `res/xml/config.xml` + +3. Copy `WikitudePlugin.js` in `assets/www`-folder and ensure to include it in the related HTMLs. + + `` +4. Download the [Wikitude SDK](http://www.wikitude.com), copy the wikitudesdk.jar in the Android-folder to your projects `libs`-folder and add it to your project's build path. Also copy the `libExtensionVuforia.so` into `libs/armeabi` + +5. Download Vuforia SDK from [Qualcomm Vuforia Website](https://ar.qualcomm.at/qdevnet/) and copy `QCAR.jar` to your projects `libs`-folder and add it to your project's build. Also copy Vuforia's `libQCAR.so` to your `libs/armeabi`-folder + +6. Visit [Wikitude Developer Site](http://developer.wikitude.com) to find Samples and license your app to get rid of the watermarking + +## JAVASCRIPT INTERFACE + +Its simple to use the Wikitude Plugin within your PhoneGap application. + +We wrapped all ``` cordova.exec ``` calls into a separate JavaScript wrapper which handles location updates and some more functionality behind the scenes. + +You will mainly work with the ``` WikitudePlugin ``` where all you have to do is to call ```Wikitude.isDeviceReady(successCallback, errorCallback)``` and in your successCallback, you can call ```WikitudePlugin.loadARchitectWorld(successCallback, errorCallback, "path/to/your/world")```. + + +If you have purchased a Wikitude SDK license, you can enter you SDK Key in the ```WikitudePlugin.js``` file at line 9. + + +## LICENSE + + Copyright 2012 [Wikitude GmbH ](http://www.wikitude.com) + + Licensed 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. + diff --git a/Android/AugmentedReality-Wikitude/Plugin/WikitudePlugin.java b/Android/AugmentedReality-Wikitude/Plugin/WikitudePlugin.java new file mode 100644 index 0000000..9082331 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/Plugin/WikitudePlugin.java @@ -0,0 +1,427 @@ +package com.wikitude.phonegap; + +import java.io.IOException; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.app.Activity; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.view.ViewManager; + +import com.phonegap.api.Plugin; +import com.phonegap.api.PluginResult; +import com.wikitude.architect.ArchitectUrlListener; +import com.wikitude.architect.ArchitectView; +import com.wikitude.architect.ArchitectView.ArchitectConfig; + + + +/** + * Basic PhoneGap Wikitude ARchitect Plugin + * + * You must add "" + * in config.xml to enable this plug-in in your project + * + * Also ensure to have wikitudesdk.jar in your libs folder + * + * Note: + * This plug-in is written under Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0.html + * + * @version 1.0.0 + * @author Wikitude GmbH; www.wikitude.com + */ +public class WikitudePlugin extends Plugin implements ArchitectUrlListener { + + /** PhoneGap-root to Android-app-assets folder ; e.g. use "assets/foo.html" as source if you want to load foo.html from your android-project's assets-folder */ + private static final String LOCAL_ASSETS_PATH_ROOT = "assets/"; + + /* various JSON-Object keys*/ + private static final String JSON_KEY_APIKEY = "sdkKey"; + private static final String JSON_KEY_FILE_PATH = "filePath"; + + private static final String JSON_KEY_LOCATION_ALTITUDE = "alt"; + private static final String JSON_KEY_LOCATION_ACCURACY = "acc"; + private static final String JSON_KEY_LOCATION_LATITUDE = "lat"; + private static final String JSON_KEY_LOCATION_LONGITUDE = "lon"; + + /* static action strings */ + + /** + * opens architect-view (add to view stack) + */ + private static final String ACTION_OPEN = "open"; + + /** + * closes architect-view (remove view stack) + */ + private static final String ACTION_CLOSE = "close"; + + /** + * set visibility of architectView to visible (of present) + */ + private static final String ACTION_SHOW = "show"; + + /** + * set visibility of architectView to invisible (of present) + */ + private static final String ACTION_HIDE = "hide"; + + /** + * inject location information + */ + private static final String ACTION_SET_LOCATION = "setLocation"; + + /** + * callback for uri-invocations + */ + private static final String ACTION_ON_URLINVOKE = "onUrlInvoke"; + + /** + * life-cycle notification for resume + */ + private static final String ACTION_ON_RESUME = "onResume"; + + /** + * life-cycle notification for pause + */ + private static final String ACTION_ON_PAUSE = "onPause"; + + /** + * check if view is on view-stack (no matter if visible or not) + */ + private static final String ACTION_STATE_ISOPEN = "isOpen"; + + /** + * opens architect-view (add to view stack) + */ + private static final String ACTION_IS_DEVICE_SUPPORTED = "isDeviceSupported"; + + /** + * check if view is on view-stack (no matter if visible or not) + */ + private static final String ACTION_CALL_JAVASCRIPT = "callJavascript"; + + /** + * the Wikitude ARchitectview + */ + private ArchitectView architectView; + + /** + * callback-Id of url-invocation method + */ + private String urlInvokeCallbackId = null; + + /** + * callback-id of "open"-action method + */ + private String openCallbackId = null; + + @Override + public PluginResult execute( final String action, final JSONArray args, final String callbackId ) { + + /* hide architect-view -> destroy and remove from activity */ + if ( WikitudePlugin.ACTION_CLOSE.equals( action ) ) { + if ( this.architectView != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + removeArchitectView(); + } + } ); + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } + else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* return success only if view is opened (no matter if visible or not) */ + if ( WikitudePlugin.ACTION_STATE_ISOPEN.equals( action ) ) { + if ( this.architectView != null ) { + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* return success only if view is opened (no matter if visible or not) */ + if ( WikitudePlugin.ACTION_IS_DEVICE_SUPPORTED.equals( action ) ) { + if ( ArchitectView.isDeviceSupported( this.cordova.getActivity() ) ) { + return new PluginResult( PluginResult.Status.OK, action + ": this device is ARchitect-ready" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": Sorry, this device is NOT ARchitect-ready" ); + } + } + + + + /* life-cycle's RESUME */ + if ( WikitudePlugin.ACTION_ON_RESUME.equals( action ) ) { + + if ( this.architectView != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + WikitudePlugin.this.architectView.onResume(); + } + } ); + + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + + /* life-cycle's PAUSE */ + if ( WikitudePlugin.ACTION_ON_PAUSE.equals( action ) ) { + if ( architectView != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + WikitudePlugin.this.architectView.onPause(); + } + } ); + + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + + /* set visibility to "visible", return error if view is null */ + if ( WikitudePlugin.ACTION_SHOW.equals( action ) ) { + + if ( this.architectView != null ) { + this.architectView.setVisibility( View.VISIBLE ); + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* set visibility to "invisible", return error if view is null */ + if ( WikitudePlugin.ACTION_HIDE.equals( action ) ) { + + if ( this.architectView != null ) { + this.architectView.setVisibility( View.INVISIBLE ); + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* define call-back for url-invocations */ + if ( WikitudePlugin.ACTION_ON_URLINVOKE.equals( action ) ) { + this.urlInvokeCallbackId = callbackId; + PluginResult result = new PluginResult( PluginResult.Status.NO_RESULT, action + ": registered callback" ); + result.setKeepCallback( true ); + return result; + } + + /* location update */ + if ( WikitudePlugin.ACTION_SET_LOCATION.equals( action ) ) { + if ( this.architectView != null ) { + try { + String arrStr = args.getString( 0 ); + JSONObject arr = new JSONObject( arrStr ); + final double lat = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_LATITUDE ); + final double lon = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_LONGITUDE ); + Object altObj = arr.get( WikitudePlugin.JSON_KEY_LOCATION_ALTITUDE ); + float alt = Float.MIN_VALUE; + + if ( altObj != null && altObj instanceof Double ) { + alt = ((Double)altObj).floatValue(); + } + + final float altitude = alt; + + final Double acc = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_ACCURACY ); + if ( this.cordova != null && this.cordova.getActivity() != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + if ( acc != null ) { + WikitudePlugin.this.architectView.setLocation( lat, lon, altitude, acc.floatValue() ); + } else { + WikitudePlugin.this.architectView.setLocation( lat, lon, altitude ); + } + } + } ); + } + + } catch ( Exception e ) { + return new PluginResult( PluginResult.Status.ERROR, action + ": exception thrown, " + e != null ? e.getMessage() : "(exception is NULL)" ); + } + return new PluginResult( PluginResult.Status.OK, action + ": updated location" ); + } + + /* return error if there is no architect-view active*/ + return new PluginResult( PluginResult.Status.ERROR, action + ": architectview is not active" ); + } + + if ( WikitudePlugin.ACTION_CALL_JAVASCRIPT.equals( action ) ) { + if ( this.architectView != null ) { + String logMsg = null; + try { + final String callJS = args.getString( 0 ); + logMsg = callJS; + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + WikitudePlugin.this.architectView.callJavascript( callJS ); + } + } ); + + } catch ( JSONException je ) { + return new PluginResult( PluginResult.Status.ERROR, action + ": exception thrown, " + je != null ? je.getMessage() : "(exception is NULL)" ); + } + return new PluginResult( PluginResult.Status.OK, action + ": called js, '" + logMsg + "'" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectview is not active" ); + } + } + + + /* initial set-up, show ArchitectView full-screen in current screen/activity */ + if ( WikitudePlugin.ACTION_OPEN.equals( action ) ) { + this.openCallbackId = callbackId; + PluginResult result = null; + String arrStr = null; + + try { + arrStr = args.getString( 0 ); + + // arrStr = arrStr.substring( 1, arrStr.length() - 1 ); + + JSONObject arr = new JSONObject( arrStr ); + + final String apiKey = arr.getString( WikitudePlugin.JSON_KEY_APIKEY ); + final String filePath = arr.getString( WikitudePlugin.JSON_KEY_FILE_PATH ); + + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + try { + WikitudePlugin.this.addArchitectView( apiKey, filePath ); + + /* call success method once architectView was added successfully */ + if ( WikitudePlugin.this.openCallbackId != null ) { + PluginResult result = new PluginResult( PluginResult.Status.OK ); + result.setKeepCallback( false ); + WikitudePlugin.this.success( result, WikitudePlugin.this.openCallbackId ); + } + } catch ( Exception e ) { + /* in case "addArchitectView" threw an exception -> notify callback method asynchronously */ + WikitudePlugin.this.error( e != null ? e.getMessage() : "Exception is 'null'", WikitudePlugin.this.openCallbackId ); + } + } + } ); + + } catch ( Exception e ) { + result = new PluginResult( PluginResult.Status.ERROR, action + ": exception thown, " + e != null ? e.getMessage() : "(exception is NULL)" ); + result.setKeepCallback( false ); + return result; + } + + /* adding architect-view is done in separate thread, ensure to setKeepCallback so one can call success-method properly later on */ + result = new PluginResult( PluginResult.Status.NO_RESULT, action + ": no result required, just registered callback-method" ); + result.setKeepCallback( true ); + + return result; + } + + /* fall-back return value */ + return new PluginResult( PluginResult.Status.ERROR, "no such action: " + action ); + } + + /** + * called when url was invoked in architectView (by e.g. calling document.location = "myprotocoll://foo"; + * @param url the invoked url (e.g. "myprotocoll://foo") + * @return true if call was handled properly + */ + @Override + public boolean urlWasInvoked( String url ) { + + /* call callback-method if set*/ + if ( this.urlInvokeCallbackId != null ) { + try { + /* pass called url as String to callback-method */ + PluginResult res = new PluginResult( PluginResult.Status.OK, url ); + res.setKeepCallback( true ); + this.success( res, this.urlInvokeCallbackId ); + return true; + } catch ( Exception e ) { + this.error( "invalid url invoked: " + url, this.urlInvokeCallbackId ); + } + } + return false; + } + + /** + * hides/removes ARchitect-View completely + * @return true if successful, false otherwise + */ + private boolean removeArchitectView() { + if ( this.architectView != null ) { + /* fake life-cycle calls, because activity is already up and running */ + this.architectView.onPause(); + this.architectView.onDestroy(); + this.architectView.setVisibility( View.INVISIBLE ); + ((ViewManager)this.architectView.getParent()).removeView( this.architectView ); + this.architectView = null; + return true; + } + return false; + } + + /** + * Architect-Configuration required for proper set-up + * @param apiKey + * @return + */ + protected ArchitectConfig getArchitectConfig( final String apiKey ) { + /* no special set-up required in default Wikitude-Plugin, further things required in advanced usage (e.g. Vuforia Image Recognition) */ + return new ArchitectConfig( apiKey ); + } + + /** + * add architectView to current screen + * @param apiKey developers's api key to use (hides watermarking/intro-animation if it matches your package-name) + * @param filePath the url (starting with http:// for online use; starting with LOCAL_ASSETS_PATH_ROOT if oyu want to load assets within your app-assets folder) + * @throws IOException might be thrown from ARchitect-SDK + */ + @SuppressWarnings("deprecation") + private void addArchitectView( final String apiKey, String filePath ) throws IOException { + if ( this.architectView == null ) { + this.architectView = new ArchitectView( (Activity)this.ctx.getContext() ); + + /* add content view and fake initial life-cycle */ + ((Activity)this.ctx.getContext()).addContentView( this.architectView, new ViewGroup.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT ) ); + + /* fake life-cycle calls, because activity is already up and running */ + this.architectView.onCreate( getArchitectConfig( apiKey ) ); + this.architectView.onPostCreate(); + + /* register self as url listener to fwd these native calls to PhoneGap */ + this.architectView.registerUrlListener( WikitudePlugin.this ); + + /* load asset from local directory if prefix is used */ + if ( filePath.startsWith( WikitudePlugin.LOCAL_ASSETS_PATH_ROOT ) ) { + filePath = filePath.substring( WikitudePlugin.LOCAL_ASSETS_PATH_ROOT.length() ); + } + this.architectView.load( filePath ); + + /* also a fake-life-cycle call (the last one before it is really shown in UI */ + this.architectView.onResume(); + } + } +} diff --git a/Android/AugmentedReality-Wikitude/Plugin/WikitudePlugin.js b/Android/AugmentedReality-Wikitude/Plugin/WikitudePlugin.js new file mode 100644 index 0000000..bd09eb2 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/Plugin/WikitudePlugin.js @@ -0,0 +1,383 @@ +var WikitudePlugin = { + + /** + * + * This is the SDK Key, provided to you after you purchased the Wikitude SDK from http://www.wikitude.com/developer/sdk + * If you're having a trial version, leave this string empty + * + */ + mySDKKey : "ENTER-YOUR-KEY-HERE", + + /** true if architectview is open */ + isOpened : false, + + /** + * + * called when user pressed back-button on Android device + * + */ + backButtonCallback : null, + + /** + * + * Change the value of this variable to modify the location update rate + * + */ + locationUpdateRate : 3000, + + /** + * + * This variable represents if the current device is capable of running the Wikitude SDK + * + */ + isDeviceSupported : false, + + /** + * + * This watchID is used to shedule location updates + * + */ + watchID : null, + + /** + * + * Callbacks to get device information if ARchitect Worlds can be launched + * + */ + onDeviceSupportedCallback : null, + onDeviceNotSupportedCallback : null, + + /** + * + * Callbacks to get notified if the ARchitect World finished launching or if something went wrong during the World launch + * + */ + onARchitectWorldLaunchedCallback : null, + onARchitectWorldFailedLaunchingCallback : null, + + /** + * + * This function gets called if PhoneGap reports that it has finished loading successfully. + * + */ + isDeviceSupported: function(successCallback, errorCallback) + { + + WikitudePlugin.onDeviceSupportedCallback = successCallback; + WikitudePlugin.onDeviceNotSupportedCallback = errorCallback; + + + // PhoneGap is running, so the first thing we do is to check if the current device is capable of running the Wikitude Plugin + cordova.exec(WikitudePlugin.deviceIsARchitectReady, WikitudePlugin.deviceIsNotARchitectReady, "WikitudePlugin", "isDeviceSupported", [""]); + + }, + + /** + * + * Declare what should happen when user pressed back-button while architect-view is opened. + * If not declared/called or null: ARchitect-View is closed + * + */ + onPressedBackButton : function(callback) + { + WikitudePlugin.backButtonCallback = callback; + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is able to start the Wikitude SDK + * + */ + deviceIsARchitectReady : function() + { + // We keep track of the device status + WikitudePlugin.isDeviceSupported = true; + + + if(WikitudePlugin.onDeviceSupportedCallback) + { + WikitudePlugin.onDeviceSupportedCallback(); + } + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is not able of starting the Wikitude SDK. + * + */ + deviceIsNotARchitectReady : function() + { + WikitudePlugin.isDeviceSupported = false; + + // In this case we notify the user that his device is not supported by the Wikitude SDK + if(WikitudePlugin.onDeviceNotSupportedCallback) + { + WikitudePlugin.onDeviceNotSupportedCallback(); + } + }, + + /* + * ============================================================================================================================= + * + * PUBLIC API + * + * ============================================================================================================================= + */ + + /* Managing ARchitect world loading */ + + /** + * + * Call this function if you want to load an ARchitect World + * + * @param {String} worldPath The path to an ARchitect world ether on the device or on e.g. your dropbox + * + */ + loadARchitectWorld : function(worldPath) + { + + // before we actually call load, we check again if the device is able to open the world + if(WikitudePlugin.isDeviceSupported) + { + + // the 'open' function of the Wikitude Plugin requires a option dictionary with two keys: + // @param {Object} options (required) + // @param {String} options.sdkKey License key for the Wikitude SDK + // @param {String} options.filePath The path to a local ARchitect world or to a ARchitect world on a server or your dropbox + + cordova.exec(WikitudePlugin.worldLaunched, WikitudePlugin.worldFailedLaunching, "WikitudePlugin", "open", [{ sdkKey: WikitudePlugin.mySDKKey, filePath: worldPath}]); + + + // We add an event listener on the resume and pause event of the application lifecycle + document.addEventListener("resume", WikitudePlugin.onResume, false); + document.addEventListener("pause", WikitudePlugin.onPause, false); + + WikitudePlugin.isOpened = true; + document.addEventListener("backbutton", WikitudePlugin.onBackButton, false); + + // After we started loading the world, we start location updates + WikitudePlugin.startLocationUpdates(); + + }else + { + // if the device is not able to start the Wikitude SDK, we notify the user again + WikitudePlugin.deviceNotARchitectReady(); + } + }, + + /* Managing the Wikitude SDK Lifecycle */ + + /** + * + * Use this function to stop the Wikitude SDK and to remove the ARchitectView from the screen + * + */ + close : function() + { + document.removeEventListener("pause", WikitudePlugin.onPause, false); + document.removeEventListener("resume", WikitudePlugin.onResume, false); + + WikitudePlugin.stopLocationUpdates(); + + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]); + WikitudePlugin.isOpened = false; + }, + + /** + * + * Use this function to only hide the Wikitude SDK. All location and rendering updates are still active + * + */ + hide : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "hide", [""]); + }, + + /** + * + * Use this function to show the Wikitude SDK if it was hidden before + * + */ + show : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "show", [""]); + }, + + /* Interacting with the Wikitude SDK */ + + /** + * + * Use this function to call javascript which will be executed in the context of your ARchitect World + * + * + * @param js The JavaScript that gets evaluated in context of the ARchitect World + * + */ + callJavaScript : function(js) + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "callJavascript", [js]); + }, + + /** + * + * Use this function to set a callback which will be invoked when the ARchitect World calls for example + * document.location = "architectsdk://opendetailpage?id=9"; + * + * + * @param onUrlInvokeCallback A function which gets called when the ARchitect World invokes a call to "document.location = architectsdk://" + */ + setOnUrlInvokeCallback : function(onUrlInvokeCallback) + { + cordova.exec(onUrlInvokeCallback, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]); + }, + + + /* + * ============================================================================================================================= + * + * Callbacks of public functions + * + * ============================================================================================================================= + */ + + /** + * + * Use this callback to get notified if the world loaded successfully + * + */ + worldLaunched : function() + { + if(WikitudePlugin.onARchitectWorldLaunchedCallback) + { + WikitudePlugin.onARchitectWorldLaunchedCallback(); + } + }, + + /** + * + * Use this callback to get notified if the Wikitude SDK wasn't able to load the ARchitect World + * + */ + worldFailedLaunching : function(err) + { + if(WikitudePlugin.onARchitectWorldFailedLaunchingCallback) + { + WikitudePlugin.onARchitectWorldFailedLaunchingCallback(err); + } + }, + + /* Lifecycle updates */ + + /** + * + * This function actually starts the PhoneGap location updates + * + */ + startLocationUpdates : function() + { + + WikitudePlugin.watchID = navigator.geolocation.watchPosition(WikitudePlugin.onReceivedLocation, WikitudePlugin.onWikitudeError, { frequency: WikitudePlugin.locationUpdateRate }); + }, + + /** + * + * This callback gets called everytime the location did update + * + */ + onReceivedLocation : function(position) + { + + // Every time that PhoneGap did received a location update, we pass the location into the Wikitude SDK + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "setLocation", [{ lat: position.coords.latitude, lon: position.coords.longitude, alt: position.coords.altitude, acc: position.coords.accuracy}]); + }, + + /** + * + * Use this function to stop location updates + * + */ + stopLocationUpdates : function() + { + + // We clear the location update watch which was responsible for updating the location in a specific time interval + navigator.geolocation.clearWatch(WikitudePlugin.watchID); + WikitudePlugin.watchID = null; + }, + + /** + * + * This function gets called every time the application did become active. + * + */ + onResume : function() + { + + // Call the Wikitude SDK that the application did become active again + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onResume", [""]); + + // And start continuing updating the user location + WikitudePlugin.startLocationUpdates(); + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onPause : function() + { + + // Call the Wikitude SDK that the application did resign active + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onPause", [""]); + + // And stop all ongoing location updates + WikitudePlugin.stopLocationUpdates(); + }, + + /** + * + * Android specific! + * This function gets called if the user presses the back button. + * You may define your own implementation by using WikitudePlugin.onPressedBackButton(method) + * + */ + onBackButton : function() + { + if (WikitudePlugin.isOpened) { + if (WikitudePlugin.backButtonCallback==null) { + WikitudePlugin.close(); + document.removeEventListener("backbutton", WikitudePlugin.onBackButton, false); + } else { + WikitudePlugin.backButtonCallback(); + } + } + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeOK : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeError : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + report: function(id) + { + console.log("app report: " + id); + } +}; diff --git a/Android/AugmentedReality-Wikitude/Plugin/WikitudePluginExtended.java b/Android/AugmentedReality-Wikitude/Plugin/WikitudePluginExtended.java new file mode 100644 index 0000000..fb62e58 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/Plugin/WikitudePluginExtended.java @@ -0,0 +1,89 @@ +package com.wikitude.phonegap; + +import android.app.Activity; + +import com.qualcomm.QCAR.QCAR; +import com.wikitude.architect.ArchitectView.ArchitectConfig; +import com.wikitude.architect.VuforiaInterface; + + + +/** + * Advanced Wikitude ARchitect Plugin (= Basic Plugin + Vuforia Image Recognition feature-set) + * + * You must add "wikitudesdk.jar" and "QCAR.lib" to your libs folder and build-path and have "libQCAR.so" in project's "libs/armeabi/" directory + * + * Also add "" + * (replace Basic-plugin entry if necessary) + * + * in config.xml to enable this plug-in in your project; Ensure your architectSDK key is Vuforia-ready + * + * Note: + * This plug-in is written under Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0.html + * + * @version 1.0.0 + * @author Wikitude GmbH; www.wikitude.com + */ +public class WikitudePluginExtended extends WikitudePlugin { + + + static { + System.loadLibrary( "QCAR" ); + } + + /** + * Architect-Configuration required for proper set-up + * @param apiKey + * @return + */ + @Override + protected ArchitectConfig getArchitectConfig( final String apiKey ) { + final ArchitectConfig config = super.getArchitectConfig( apiKey ); + + /* required for Vuforia */ + config.setVuforiaInterface( new VuforiaServiceImplementation() ); + return config; + } + + /* required for Vuforia */ + private class VuforiaServiceImplementation implements VuforiaInterface { + + @Override + public void deInit() { + QCAR.deinit(); + } + + @Override + public int init() { + return QCAR.init(); + } + + @Override + public void onPause() { + QCAR.onPause(); + } + + @Override + public void onResume() { + QCAR.onResume(); + } + + @Override + public void onSurfaceChanged( final int arg0, final int arg1 ) { + QCAR.onSurfaceChanged( arg0, arg1 ); + } + + @Override + public void onSurfaceCreated() { + QCAR.onSurfaceCreated(); + } + + @Override + public void setInitParameters( final Activity activity, final int nFlags ) { + QCAR.setInitParameters( activity, nFlags ); + } + + } + +} diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/.classpath b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/.classpath new file mode 100644 index 0000000..ce14813 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/.project b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/.project new file mode 100644 index 0000000..efb82dc --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/.project @@ -0,0 +1,33 @@ + + + HelloWorld + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/AndroidManifest.xml b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/AndroidManifest.xml new file mode 100644 index 0000000..db22048 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/AndroidManifest.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/world/HelloWorld.html b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/world/HelloWorld.html new file mode 100644 index 0000000..0b620f3 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/world/HelloWorld.html @@ -0,0 +1,52 @@ + + + + + + +My ARchitect World + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/cordova-2.0.0.js b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/cordova-2.0.0.js new file mode 100644 index 0000000..ba9e6a9 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/cordova-2.0.0.js @@ -0,0 +1,5724 @@ +// commit 114cf5304a74ff8f7c9ff1d21cf5652298af04b0 + +// File generated at :: Wed Jul 18 2012 14:44:33 GMT-0700 (PDT) + +/* + 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 0) { + var v = JSON.parse(r); + + // 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 (success) { + try { + success(v.message); + } catch (e) { + console.log("Error in success callback: " + callbackId + " = " + e); + } + + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + return v.message; + } + + // If no result + else if (v.status === cordova.callbackStatus.NO_RESULT) { + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + + // If error, then display error + else { + console.log("Error: Status="+v.status+" Message="+v.message); + + // If there is a fail callback, then call it now with returned value + if (fail) { + try { + fail(v.message); + } + catch (e1) { + console.log("Error in error callback: "+callbackId+" = "+e1); + } + + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + return null; + } + } + } catch (e2) { + console.log("Error: "+e2); + } +}; + +}); + +// file: lib/android/platform.js +define("cordova/platform", function(require, exports, module) { +module.exports = { + id: "android", + initialize:function() { + var channel = require("cordova/channel"), + cordova = require('cordova'), + callback = require('cordova/plugin/android/callback'), + polling = require('cordova/plugin/android/polling'), + exec = require('cordova/exec'); + + channel.onDestroy.subscribe(function() { + cordova.shuttingDown = true; + }); + + // Start listening for XHR callbacks + // Figure out which bridge approach will work on this Android + // device: polling or XHR-based callbacks + setTimeout(function() { + if (cordova.UsePolling) { + polling(); + } + else { + var isPolling = prompt("usePolling", "gap_callbackServer:"); + cordova.UsePolling = isPolling; + if (isPolling == "true") { + cordova.UsePolling = true; + polling(); + } else { + cordova.UsePolling = false; + callback(); + } + } + }, 1); + + // Inject a listener for the backbutton on the document. + var backButtonChannel = cordova.addDocumentEventHandler('backbutton', { + onSubscribe:function() { + // If we just attached the first handler, let native know we need to override the back button. + if (this.numHandlers === 1) { + exec(null, null, "App", "overrideBackbutton", [true]); + } + }, + onUnsubscribe:function() { + // If we just detached the last handler, let native know we no longer override the back button. + if (this.numHandlers === 0) { + exec(null, null, "App", "overrideBackbutton", [false]); + } + } + }); + + // Add hardware MENU and SEARCH button handlers + cordova.addDocumentEventHandler('menubutton'); + cordova.addDocumentEventHandler('searchbutton'); + + // Figure out if we need to shim-in localStorage and WebSQL + // support from the native side. + var storage = require('cordova/plugin/android/storage'); + + // First patch WebSQL if necessary + if (typeof window.openDatabase == 'undefined') { + // Not defined, create an openDatabase function for all to use! + window.openDatabase = storage.openDatabase; + } else { + // Defined, but some Android devices will throw a SECURITY_ERR - + // so we wrap the whole thing in a try-catch and shim in our own + // if the device has Android bug 16175. + var originalOpenDatabase = window.openDatabase; + window.openDatabase = function(name, version, desc, size) { + var db = null; + try { + db = originalOpenDatabase(name, version, desc, size); + } + catch (ex) { + if (ex.code === 18) { + db = null; + } else { + throw ex; + } + } + + if (db === null) { + return storage.openDatabase(name, version, desc, size); + } + else { + return db; + } + + }; + } + + // Patch localStorage if necessary + if (typeof window.localStorage == 'undefined' || window.localStorage === null) { + window.localStorage = new storage.CupcakeLocalStorage(); + } + + // Let native code know we are all done on the JS side. + // Native code will then un-hide the WebView. + channel.join(function() { + exec(null, null, "App", "show", []); + }, [channel.onCordovaReady]); + }, + objects: { + cordova: { + children: { + JSCallback:{ + path:"cordova/plugin/android/callback" + }, + JSCallbackPolling:{ + path:"cordova/plugin/android/polling" + } + } + }, + navigator: { + children: { + app:{ + path: "cordova/plugin/android/app" + } + } + }, + File: { // exists natively on Android WebView, override + path: "cordova/plugin/File" + }, + FileReader: { // exists natively on Android WebView, override + path: "cordova/plugin/FileReader" + }, + FileError: { //exists natively on Android WebView on Android 4.x + path: "cordova/plugin/FileError" + }, + MediaError: { // exists natively on Android WebView on Android 4.x + path: "cordova/plugin/MediaError" + } + }, + merges: { + device: { + path: 'cordova/plugin/android/device' + }, + navigator: { + children: { + notification: { + path: 'cordova/plugin/android/notification' + } + } + } + } +}; + +}); + +// 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.} phoneNumbers array of phone numbers +* @param {Array.} emails array of email addresses +* @param {Array.} addresses array of addresses +* @param {Array.} ims instant messaging user ids +* @param {Array.} organizations +* @param {DOMString} birthday contact's birthday +* @param {DOMString} note user notes about contact +* @param {Array.} photos +* @param {Array.} categories +* @param {Array.} 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][;base64], + * + * @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.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/android/plugin/android/app.js +define("cordova/plugin/android/app", function(require, exports, module) { +var exec = require('cordova/exec'); + +module.exports = { + /** + * Clear the resource cache. + */ + clearCache:function() { + exec(null, null, "App", "clearCache", []); + }, + + /** + * Load the url into the webview or into new browser instance. + * + * @param url The URL to load + * @param props Properties that can be passed in to the activity: + * wait: int => wait msec before loading URL + * loadingDialog: "Title,Message" => display a native loading dialog + * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error + * clearHistory: boolean => clear webview history (default=false) + * openExternal: boolean => open in a new browser (default=false) + * + * Example: + * navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000}); + */ + loadUrl:function(url, props) { + exec(null, null, "App", "loadUrl", [url, props]); + }, + + /** + * Cancel loadUrl that is waiting to be loaded. + */ + cancelLoadUrl:function() { + exec(null, null, "App", "cancelLoadUrl", []); + }, + + /** + * Clear web history in this web view. + * Instead of BACK button loading the previous web page, it will exit the app. + */ + clearHistory:function() { + exec(null, null, "App", "clearHistory", []); + }, + + /** + * Go to previous page displayed. + * This is the same as pressing the backbutton on Android device. + */ + backHistory:function() { + exec(null, null, "App", "backHistory", []); + }, + + /** + * Override the default behavior of the Android back button. + * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired. + * + * Note: The user should not have to call this method. Instead, when the user + * registers for the "backbutton" event, this is automatically done. + * + * @param override T=override, F=cancel override + */ + overrideBackbutton:function(override) { + exec(null, null, "App", "overrideBackbutton", [override]); + }, + + /** + * Exit and terminate the application. + */ + exitApp:function() { + return exec(null, null, "App", "exitApp", []); + } +}; +}); + +// file: lib/android/plugin/android/callback.js +define("cordova/plugin/android/callback", function(require, exports, module) { +var port = null, + token = null, + cordova = require('cordova'), + polling = require('cordova/plugin/android/polling'), + callback = function() { + // Exit if shutting down app + if (cordova.shuttingDown) { + return; + } + + // If polling flag was changed, start using polling from now on + if (cordova.UsePolling) { + polling(); + return; + } + + var xmlhttp = new XMLHttpRequest(); + + // Callback function when XMLHttpRequest is ready + xmlhttp.onreadystatechange=function(){ + if(xmlhttp.readyState === 4){ + + // Exit if shutting down app + if (cordova.shuttingDown) { + return; + } + + // If callback has JavaScript statement to execute + if (xmlhttp.status === 200) { + + // Need to url decode the response + var msg = decodeURIComponent(xmlhttp.responseText); + setTimeout(function() { + try { + var t = eval(msg); + } + catch (e) { + // If we're getting an error here, seeing the message will help in debugging + console.log("JSCallback: Message from Server: " + msg); + console.log("JSCallback Error: "+e); + } + }, 1); + setTimeout(callback, 1); + } + + // If callback ping (used to keep XHR request from timing out) + else if (xmlhttp.status === 404) { + setTimeout(callback, 10); + } + + // If security error + else if (xmlhttp.status === 403) { + console.log("JSCallback Error: Invalid token. Stopping callbacks."); + } + + // If server is stopping + else if (xmlhttp.status === 503) { + console.log("JSCallback Server Closed: Stopping callbacks."); + } + + // If request wasn't GET + else if (xmlhttp.status === 400) { + console.log("JSCallback Error: Bad request. Stopping callbacks."); + } + + // If error, revert to polling + else { + console.log("JSCallback Error: Request failed."); + cordova.UsePolling = true; + polling(); + } + } + }; + + if (port === null) { + port = prompt("getPort", "gap_callbackServer:"); + } + if (token === null) { + token = prompt("getToken", "gap_callbackServer:"); + } + xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true); + xmlhttp.send(); +}; + +module.exports = callback; +}); + +// file: lib/android/plugin/android/device.js +define("cordova/plugin/android/device", function(require, exports, module) { +var channel = require('cordova/channel'), + utils = require('cordova/utils'), + exec = require('cordova/exec'), + app = require('cordova/plugin/android/app'); + +module.exports = { + /* + * DEPRECATED + * This is only for Android. + * + * You must explicitly override the back button. + */ + overrideBackButton:function() { + console.log("Device.overrideBackButton() is deprecated. Use App.overrideBackbutton(true)."); + app.overrideBackbutton(true); + }, + + /* + * DEPRECATED + * This is only for Android. + * + * This resets the back button to the default behaviour + */ + resetBackButton:function() { + console.log("Device.resetBackButton() is deprecated. Use App.overrideBackbutton(false)."); + app.overrideBackbutton(false); + }, + + /* + * DEPRECATED + * This is only for Android. + * + * This terminates the activity! + */ + exitApp:function() { + console.log("Device.exitApp() is deprecated. Use App.exitApp()."); + app.exitApp(); + } +}; + +}); + +// file: lib/android/plugin/android/notification.js +define("cordova/plugin/android/notification", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * Provides Android enhanced notification API. + */ +module.exports = { + activityStart : function(title, message) { + // If title and message not specified then mimic Android behavior of + // using default strings. + if (typeof title === "undefined" && typeof message == "undefined") { + title = "Busy"; + message = 'Please wait...'; + } + + exec(null, null, 'Notification', 'activityStart', [ title, message ]); + }, + + /** + * Close an activity dialog + */ + activityStop : function() { + exec(null, null, 'Notification', 'activityStop', []); + }, + + /** + * Display a progress dialog with progress bar that goes from 0 to 100. + * + * @param {String} + * title Title of the progress dialog. + * @param {String} + * message Message to display in the dialog. + */ + progressStart : function(title, message) { + exec(null, null, 'Notification', 'progressStart', [ title, message ]); + }, + + /** + * Close the progress dialog. + */ + progressStop : function() { + exec(null, null, 'Notification', 'progressStop', []); + }, + + /** + * Set the progress dialog value. + * + * @param {Number} + * value 0-100 + */ + progressValue : function(value) { + exec(null, null, 'Notification', 'progressValue', [ value ]); + } +}; +}); + +// file: lib/android/plugin/android/polling.js +define("cordova/plugin/android/polling", function(require, exports, module) { +var cordova = require('cordova'), + period = 50, + polling = function() { + // Exit if shutting down app + if (cordova.shuttingDown) { + return; + } + + // If polling flag was changed, stop using polling from now on and switch to XHR server / callback + if (!cordova.UsePolling) { + require('cordova/plugin/android/callback')(); + return; + } + + var msg = prompt("", "gap_poll:"); + if (msg) { + setTimeout(function() { + try { + var t = eval(""+msg); + } + catch (e) { + console.log("JSCallbackPolling: Message from Server: " + msg); + console.log("JSCallbackPolling Error: "+e); + } + }, 1); + setTimeout(polling, 1); + } + else { + setTimeout(polling, period); + } +}; + +module.exports = polling; +}); + +// file: lib/android/plugin/android/storage.js +define("cordova/plugin/android/storage", function(require, exports, module) { +var utils = require('cordova/utils'), + exec = require('cordova/exec'), + channel = require('cordova/channel'); + +var queryQueue = {}; + +/** + * SQL result set object + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Rows = function() { + this.resultSet = []; // results array + this.length = 0; // number of rows +}; + +/** + * Get item from SQL result set + * + * @param row The row number to return + * @return The row object + */ +DroidDB_Rows.prototype.item = function(row) { + return this.resultSet[row]; +}; + +/** + * SQL result set that is returned to user. + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Result = function() { + this.rows = new DroidDB_Rows(); +}; + +/** + * Callback from native code when query is complete. + * PRIVATE METHOD + * + * @param id Query id + */ +function completeQuery(id, data) { + var query = queryQueue[id]; + if (query) { + try { + delete queryQueue[id]; + + // Get transaction + var tx = query.tx; + + // If transaction hasn't failed + // Note: We ignore all query results if previous query + // in the same transaction failed. + if (tx && tx.queryList[id]) { + + // Save query results + var r = new DroidDB_Result(); + r.rows.resultSet = data; + r.rows.length = data.length; + try { + if (typeof query.successCallback === 'function') { + query.successCallback(query.tx, r); + } + } catch (ex) { + console.log("executeSql error calling user success callback: "+ex); + } + + tx.queryComplete(id); + } + } catch (e) { + console.log("executeSql error: "+e); + } + } +} + +/** + * Callback from native code when query fails + * PRIVATE METHOD + * + * @param reason Error message + * @param id Query id + */ +function failQuery(reason, id) { + var query = queryQueue[id]; + if (query) { + try { + delete queryQueue[id]; + + // Get transaction + var tx = query.tx; + + // If transaction hasn't failed + // Note: We ignore all query results if previous query + // in the same transaction failed. + if (tx && tx.queryList[id]) { + tx.queryList = {}; + + try { + if (typeof query.errorCallback === 'function') { + query.errorCallback(query.tx, reason); + } + } catch (ex) { + console.log("executeSql error calling user error callback: "+ex); + } + + tx.queryFailed(id, reason); + } + + } catch (e) { + console.log("executeSql error: "+e); + } + } +} + +/** + * SQL query object + * PRIVATE METHOD + * + * @constructor + * @param tx The transaction object that this query belongs to + */ +var DroidDB_Query = function(tx) { + + // Set the id of the query + this.id = utils.createUUID(); + + // Add this query to the queue + queryQueue[this.id] = this; + + // Init result + this.resultSet = []; + + // Set transaction that this query belongs to + this.tx = tx; + + // Add this query to transaction list + this.tx.queryList[this.id] = this; + + // Callbacks + this.successCallback = null; + this.errorCallback = null; + +}; + +/** + * Transaction object + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Tx = function() { + + // Set the id of the transaction + this.id = utils.createUUID(); + + // Callbacks + this.successCallback = null; + this.errorCallback = null; + + // Query list + this.queryList = {}; +}; + +/** + * Mark query in transaction as complete. + * If all queries are complete, call the user's transaction success callback. + * + * @param id Query id + */ +DroidDB_Tx.prototype.queryComplete = function(id) { + delete this.queryList[id]; + + // If no more outstanding queries, then fire transaction success + if (this.successCallback) { + var count = 0; + var i; + for (i in this.queryList) { + if (this.queryList.hasOwnProperty(i)) { + count++; + } + } + if (count === 0) { + try { + this.successCallback(); + } catch(e) { + console.log("Transaction error calling user success callback: " + e); + } + } + } +}; + +/** + * Mark query in transaction as failed. + * + * @param id Query id + * @param reason Error message + */ +DroidDB_Tx.prototype.queryFailed = function(id, reason) { + + // The sql queries in this transaction have already been run, since + // we really don't have a real transaction implemented in native code. + // However, the user callbacks for the remaining sql queries in transaction + // will not be called. + this.queryList = {}; + + if (this.errorCallback) { + try { + this.errorCallback(reason); + } catch(e) { + console.log("Transaction error calling user error callback: " + e); + } + } +}; + +/** + * Execute SQL statement + * + * @param sql SQL statement to execute + * @param params Statement parameters + * @param successCallback Success callback + * @param errorCallback Error callback + */ +DroidDB_Tx.prototype.executeSql = function(sql, params, successCallback, errorCallback) { + + // Init params array + if (typeof params === 'undefined') { + params = []; + } + + // Create query and add to queue + var query = new DroidDB_Query(this); + queryQueue[query.id] = query; + + // Save callbacks + query.successCallback = successCallback; + query.errorCallback = errorCallback; + + // Call native code + exec(null, null, "Storage", "executeSql", [sql, params, query.id]); +}; + +var DatabaseShell = function() { +}; + +/** + * Start a transaction. + * Does not support rollback in event of failure. + * + * @param process {Function} The transaction function + * @param successCallback {Function} + * @param errorCallback {Function} + */ +DatabaseShell.prototype.transaction = function(process, errorCallback, successCallback) { + var tx = new DroidDB_Tx(); + tx.successCallback = successCallback; + tx.errorCallback = errorCallback; + try { + process(tx); + } catch (e) { + console.log("Transaction error: "+e); + if (tx.errorCallback) { + try { + tx.errorCallback(e); + } catch (ex) { + console.log("Transaction error calling user error callback: "+e); + } + } + } +}; + +/** + * Open database + * + * @param name Database name + * @param version Database version + * @param display_name Database display name + * @param size Database size in bytes + * @return Database object + */ +var DroidDB_openDatabase = function(name, version, display_name, size) { + exec(null, null, "Storage", "openDatabase", [name, version, display_name, size]); + var db = new DatabaseShell(); + return db; +}; + +/** + * For browsers with no localStorage we emulate it with SQLite. Follows the w3c api. + * TODO: Do similar for sessionStorage. + * @constructor + */ +var CupcakeLocalStorage = function() { + channel.waitForInitialization("cupcakeStorage"); + + try { + + this.db = openDatabase('localStorage', '1.0', 'localStorage', 2621440); + var storage = {}; + this.length = 0; + function setLength (length) { + this.length = length; + localStorage.length = length; + } + this.db.transaction( + function (transaction) { + var i; + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('SELECT * FROM storage', [], function(tx, result) { + for(var i = 0; i < result.rows.length; i++) { + storage[result.rows.item(i).id] = result.rows.item(i).body; + } + setLength(result.rows.length); + channel.initializationComplete("cupcakeStorage"); + }); + + }, + function (err) { + utils.alert(err.message); + } + ); + this.setItem = function(key, val) { + if (typeof(storage[key])=='undefined') { + this.length++; + } + storage[key] = val; + this.db.transaction( + function (transaction) { + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('REPLACE INTO storage (id, body) values(?,?)', [key,val]); + } + ); + }; + this.getItem = function(key) { + return storage[key]; + }; + this.removeItem = function(key) { + delete storage[key]; + this.length--; + this.db.transaction( + function (transaction) { + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('DELETE FROM storage where id=?', [key]); + } + ); + }; + this.clear = function() { + storage = {}; + this.length = 0; + this.db.transaction( + function (transaction) { + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('DELETE FROM storage', []); + } + ); + }; + this.key = function(index) { + var i = 0; + for (var j in storage) { + if (i==index) { + return j; + } else { + i++; + } + } + return null; + }; + + } catch(e) { + utils.alert("Database error "+e+"."); + return; + } +}; + +module.exports = { + openDatabase:DroidDB_openDatabase, + CupcakeLocalStorage:CupcakeLocalStorage, + failQuery:failQuery, + completeQuery:completeQuery +}; + +}); + +// 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 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 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/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 + + + + + + + PhoneGap and Wikitude + + + + + + + + Hello Cordova + + +
+

Apache Cordova™

+
+ + +
+
+ + + + + + diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/js/WikitudePlugin.js b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/js/WikitudePlugin.js new file mode 100644 index 0000000..bd09eb2 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/js/WikitudePlugin.js @@ -0,0 +1,383 @@ +var WikitudePlugin = { + + /** + * + * This is the SDK Key, provided to you after you purchased the Wikitude SDK from http://www.wikitude.com/developer/sdk + * If you're having a trial version, leave this string empty + * + */ + mySDKKey : "ENTER-YOUR-KEY-HERE", + + /** true if architectview is open */ + isOpened : false, + + /** + * + * called when user pressed back-button on Android device + * + */ + backButtonCallback : null, + + /** + * + * Change the value of this variable to modify the location update rate + * + */ + locationUpdateRate : 3000, + + /** + * + * This variable represents if the current device is capable of running the Wikitude SDK + * + */ + isDeviceSupported : false, + + /** + * + * This watchID is used to shedule location updates + * + */ + watchID : null, + + /** + * + * Callbacks to get device information if ARchitect Worlds can be launched + * + */ + onDeviceSupportedCallback : null, + onDeviceNotSupportedCallback : null, + + /** + * + * Callbacks to get notified if the ARchitect World finished launching or if something went wrong during the World launch + * + */ + onARchitectWorldLaunchedCallback : null, + onARchitectWorldFailedLaunchingCallback : null, + + /** + * + * This function gets called if PhoneGap reports that it has finished loading successfully. + * + */ + isDeviceSupported: function(successCallback, errorCallback) + { + + WikitudePlugin.onDeviceSupportedCallback = successCallback; + WikitudePlugin.onDeviceNotSupportedCallback = errorCallback; + + + // PhoneGap is running, so the first thing we do is to check if the current device is capable of running the Wikitude Plugin + cordova.exec(WikitudePlugin.deviceIsARchitectReady, WikitudePlugin.deviceIsNotARchitectReady, "WikitudePlugin", "isDeviceSupported", [""]); + + }, + + /** + * + * Declare what should happen when user pressed back-button while architect-view is opened. + * If not declared/called or null: ARchitect-View is closed + * + */ + onPressedBackButton : function(callback) + { + WikitudePlugin.backButtonCallback = callback; + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is able to start the Wikitude SDK + * + */ + deviceIsARchitectReady : function() + { + // We keep track of the device status + WikitudePlugin.isDeviceSupported = true; + + + if(WikitudePlugin.onDeviceSupportedCallback) + { + WikitudePlugin.onDeviceSupportedCallback(); + } + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is not able of starting the Wikitude SDK. + * + */ + deviceIsNotARchitectReady : function() + { + WikitudePlugin.isDeviceSupported = false; + + // In this case we notify the user that his device is not supported by the Wikitude SDK + if(WikitudePlugin.onDeviceNotSupportedCallback) + { + WikitudePlugin.onDeviceNotSupportedCallback(); + } + }, + + /* + * ============================================================================================================================= + * + * PUBLIC API + * + * ============================================================================================================================= + */ + + /* Managing ARchitect world loading */ + + /** + * + * Call this function if you want to load an ARchitect World + * + * @param {String} worldPath The path to an ARchitect world ether on the device or on e.g. your dropbox + * + */ + loadARchitectWorld : function(worldPath) + { + + // before we actually call load, we check again if the device is able to open the world + if(WikitudePlugin.isDeviceSupported) + { + + // the 'open' function of the Wikitude Plugin requires a option dictionary with two keys: + // @param {Object} options (required) + // @param {String} options.sdkKey License key for the Wikitude SDK + // @param {String} options.filePath The path to a local ARchitect world or to a ARchitect world on a server or your dropbox + + cordova.exec(WikitudePlugin.worldLaunched, WikitudePlugin.worldFailedLaunching, "WikitudePlugin", "open", [{ sdkKey: WikitudePlugin.mySDKKey, filePath: worldPath}]); + + + // We add an event listener on the resume and pause event of the application lifecycle + document.addEventListener("resume", WikitudePlugin.onResume, false); + document.addEventListener("pause", WikitudePlugin.onPause, false); + + WikitudePlugin.isOpened = true; + document.addEventListener("backbutton", WikitudePlugin.onBackButton, false); + + // After we started loading the world, we start location updates + WikitudePlugin.startLocationUpdates(); + + }else + { + // if the device is not able to start the Wikitude SDK, we notify the user again + WikitudePlugin.deviceNotARchitectReady(); + } + }, + + /* Managing the Wikitude SDK Lifecycle */ + + /** + * + * Use this function to stop the Wikitude SDK and to remove the ARchitectView from the screen + * + */ + close : function() + { + document.removeEventListener("pause", WikitudePlugin.onPause, false); + document.removeEventListener("resume", WikitudePlugin.onResume, false); + + WikitudePlugin.stopLocationUpdates(); + + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]); + WikitudePlugin.isOpened = false; + }, + + /** + * + * Use this function to only hide the Wikitude SDK. All location and rendering updates are still active + * + */ + hide : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "hide", [""]); + }, + + /** + * + * Use this function to show the Wikitude SDK if it was hidden before + * + */ + show : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "show", [""]); + }, + + /* Interacting with the Wikitude SDK */ + + /** + * + * Use this function to call javascript which will be executed in the context of your ARchitect World + * + * + * @param js The JavaScript that gets evaluated in context of the ARchitect World + * + */ + callJavaScript : function(js) + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "callJavascript", [js]); + }, + + /** + * + * Use this function to set a callback which will be invoked when the ARchitect World calls for example + * document.location = "architectsdk://opendetailpage?id=9"; + * + * + * @param onUrlInvokeCallback A function which gets called when the ARchitect World invokes a call to "document.location = architectsdk://" + */ + setOnUrlInvokeCallback : function(onUrlInvokeCallback) + { + cordova.exec(onUrlInvokeCallback, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]); + }, + + + /* + * ============================================================================================================================= + * + * Callbacks of public functions + * + * ============================================================================================================================= + */ + + /** + * + * Use this callback to get notified if the world loaded successfully + * + */ + worldLaunched : function() + { + if(WikitudePlugin.onARchitectWorldLaunchedCallback) + { + WikitudePlugin.onARchitectWorldLaunchedCallback(); + } + }, + + /** + * + * Use this callback to get notified if the Wikitude SDK wasn't able to load the ARchitect World + * + */ + worldFailedLaunching : function(err) + { + if(WikitudePlugin.onARchitectWorldFailedLaunchingCallback) + { + WikitudePlugin.onARchitectWorldFailedLaunchingCallback(err); + } + }, + + /* Lifecycle updates */ + + /** + * + * This function actually starts the PhoneGap location updates + * + */ + startLocationUpdates : function() + { + + WikitudePlugin.watchID = navigator.geolocation.watchPosition(WikitudePlugin.onReceivedLocation, WikitudePlugin.onWikitudeError, { frequency: WikitudePlugin.locationUpdateRate }); + }, + + /** + * + * This callback gets called everytime the location did update + * + */ + onReceivedLocation : function(position) + { + + // Every time that PhoneGap did received a location update, we pass the location into the Wikitude SDK + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "setLocation", [{ lat: position.coords.latitude, lon: position.coords.longitude, alt: position.coords.altitude, acc: position.coords.accuracy}]); + }, + + /** + * + * Use this function to stop location updates + * + */ + stopLocationUpdates : function() + { + + // We clear the location update watch which was responsible for updating the location in a specific time interval + navigator.geolocation.clearWatch(WikitudePlugin.watchID); + WikitudePlugin.watchID = null; + }, + + /** + * + * This function gets called every time the application did become active. + * + */ + onResume : function() + { + + // Call the Wikitude SDK that the application did become active again + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onResume", [""]); + + // And start continuing updating the user location + WikitudePlugin.startLocationUpdates(); + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onPause : function() + { + + // Call the Wikitude SDK that the application did resign active + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onPause", [""]); + + // And stop all ongoing location updates + WikitudePlugin.stopLocationUpdates(); + }, + + /** + * + * Android specific! + * This function gets called if the user presses the back button. + * You may define your own implementation by using WikitudePlugin.onPressedBackButton(method) + * + */ + onBackButton : function() + { + if (WikitudePlugin.isOpened) { + if (WikitudePlugin.backButtonCallback==null) { + WikitudePlugin.close(); + document.removeEventListener("backbutton", WikitudePlugin.onBackButton, false); + } else { + WikitudePlugin.backButtonCallback(); + } + } + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeOK : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeError : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + report: function(id) + { + console.log("app report: " + id); + } +}; diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/js/index.js b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/js/index.js new file mode 100644 index 0000000..412a0fe --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/js/index.js @@ -0,0 +1,116 @@ +var app = { + initialize: function() { + this.bind(); + }, + bind: function() { + document.addEventListener('deviceready', this.deviceready, false); + }, + + /** + * + * This function extracts an url parameter + * + */ + getUrlParameterForKey : function( url, requestedParam ) + { + requestedParam = requestedParam.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); + var regexS = "[\\?&]"+requestedParam+"=([^&#]*)"; + var regex = new RegExp( regexS ); + var results = regex.exec( url ); + if( results == null ) + return ""; + else + { + var result = decodeURIComponent(results[1]); + return result; + } + + }, + + /** + * + * This function gets called if you call "document.location = architectsdk://" in your ARchitect World + * + * + * @param url The url which was called in ARchitect World + * + */ + onClickInARchitectWorld : function(url) + { + + app.report("you clicked on a label with text: " + app.getUrlParameterForKey(url, 'text')); + }, + + /** + * + * This function gets called it the Wikitude SDK is able to start an ARchitect World (the current device is supported by the Wikitude SDK) + * + */ + onDeviceIsReadyCallback : function() + { + // The device is able to launch ARchitect World, so we load the 'Hello World' example + WikitudePlugin.loadARchitectWorld("assets/world/HelloWorld.html"); + + // To be able to respond on events inside the ARchitect World, we set a onURLInvoke callback + WikitudePlugin.setOnUrlInvokeCallback(app.onClickInARchitectWorld); + + // This is a example how you can interact with the ARchitect World to pass in additional information + // In this example, a JavaScript function gets called which sets a new text for a label + WikitudePlugin.callJavaScript("didReceivedNewTextForLabel('Hello World')"); + }, + + /** + * + * This function gets if the current device is not capable of running ARchitect Worlds + * + */ + onDeviceIsUnsupportedCallback : function() + { + app.report('device is not supported'); + }, + + /** + * + * This function gets if the ARchitect World finished loading + * + */ + onARchitectWorldLaunchedCallback : function() + { + app.report('ARchitect World launched'); + }, + + /** + * + * This function gets if the ARchitect failed loading + * + */ + onARchitectWorldFailedLaunchingCallback : function(err) + { + app.report('ARchitect World failed launching'); + }, + + /** + * + * This function gets called when the Wikitude SDK is ready to start an ARchitect World (the current device is supported by the Wikitude SDK) + * + */ + deviceready: function() { + // note that this is an event handler so the scope is that of the event + // so we need to call app.report(), and not this.report() + app.report('deviceready'); + + // When PhoneGap finished loading we forward this event into the Wikitude SDK wrapper. + // @param {function} A function which gets called if the device is able to launch ARchitect Worlds + // @param {function} A function which gets called if the device is not able to launch ARchitect Worlds + WikitudePlugin.isDeviceSupported(app.onDeviceIsReadyCallback, app.onDeviceIsUnsupportedCallback); + + // set a callback on the WikitudePlugin to get informed when the ARchitect World finished loading + WikitudePlugin.onARchitectWorldLaunchedCallback = app.onARchitectWorldLaunchedCallback; + + // Set a callback on the WikitudePlugin to get informed when the ARchitect World failed loading + WikitudePlugin.onARchitectWorldFailedLaunchingCallback = app.onARchitectWorldFailedLaunchingCallback; + }, + report: function(id) { + console.log("report:" + id); + } +}; diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_128.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_128.png new file mode 100644 index 0000000..3516df3 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_128.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_16.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_16.png new file mode 100644 index 0000000..54e19c5 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_16.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_24.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_24.png new file mode 100644 index 0000000..c7d43ad Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_24.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_256.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_256.png new file mode 100644 index 0000000..e1cd0e6 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_256.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_32.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_32.png new file mode 100644 index 0000000..734fffc Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_32.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_48.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_48.png new file mode 100644 index 0000000..8ad8bac Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_48.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_512.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_512.png new file mode 100644 index 0000000..c9465f3 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_512.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_64.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_64.png new file mode 100644 index 0000000..03b3849 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_64.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_36.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_36.png new file mode 100644 index 0000000..cd5032a Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_36.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_48.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_48.png new file mode 100644 index 0000000..e79c606 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_48.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_72.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_72.png new file mode 100644 index 0000000..4d27634 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_72.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_96.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_96.png new file mode 100644 index 0000000..ec7ffbf Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_android_96.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_bb_80.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_bb_80.png new file mode 100644 index 0000000..f86a27a Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_bb_80.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_114.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_114.png new file mode 100644 index 0000000..efd9c37 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_114.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_144.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_144.png new file mode 100644 index 0000000..dd819da Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_144.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_57.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_57.png new file mode 100644 index 0000000..c795fc4 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_57.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_72.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_72.png new file mode 100644 index 0000000..b1cfde7 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/icon/cordova_ios_72.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_hdpi_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_hdpi_landscape.png new file mode 100644 index 0000000..a61e2b1 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_hdpi_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_hdpi_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_hdpi_portrait.png new file mode 100644 index 0000000..5d6a28a Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_hdpi_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_ldpi_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_ldpi_landscape.png new file mode 100644 index 0000000..f3934cd Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_ldpi_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_ldpi_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_ldpi_portrait.png new file mode 100644 index 0000000..65ad163 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_ldpi_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_mdpi_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_mdpi_landscape.png new file mode 100644 index 0000000..a1b697c Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_mdpi_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_mdpi_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_mdpi_portrait.png new file mode 100644 index 0000000..ea15693 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_mdpi_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_xhdpi_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_xhdpi_landscape.png new file mode 100644 index 0000000..79f2f09 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_xhdpi_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_xhdpi_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_xhdpi_portrait.png new file mode 100644 index 0000000..c2e8042 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/android_xhdpi_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/blackberry_transparent_300.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/blackberry_transparent_300.png new file mode 100644 index 0000000..b548bdc Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/blackberry_transparent_300.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/blackberry_transparent_400.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/blackberry_transparent_400.png new file mode 100644 index 0000000..3facdf9 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/blackberry_transparent_400.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_landscape.png new file mode 100644 index 0000000..04be5ac Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_portrait.png new file mode 100644 index 0000000..41e839d Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_retina_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_retina_landscape.png new file mode 100644 index 0000000..95c542d Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_retina_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_retina_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_retina_portrait.png new file mode 100644 index 0000000..aae1862 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/ipad_retina_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_landscape.png new file mode 100644 index 0000000..d154883 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_portrait.png new file mode 100644 index 0000000..6fcba56 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_retina_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_retina_landscape.png new file mode 100644 index 0000000..0165669 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_retina_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_retina_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_retina_portrait.png new file mode 100644 index 0000000..bd24886 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/iphone_retina_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/windows_phone_portrait.jpg b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/windows_phone_portrait.jpg new file mode 100644 index 0000000..9f95387 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/res/screen/windows_phone_portrait.jpg differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/spec.html b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/spec.html new file mode 100644 index 0000000..83d7d2e --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/spec.html @@ -0,0 +1,50 @@ + + + + Jasmine Spec Runner + + + + + + + + + + + + + + + + + + + + diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/spec/helper.js b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/spec/helper.js new file mode 100644 index 0000000..9f99445 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/spec/helper.js @@ -0,0 +1,11 @@ +afterEach(function() { + document.getElementById('stage').innerHTML = ''; +}); + +var helper = { + trigger: function(obj, name) { + var e = document.createEvent('Event'); + e.initEvent(name, true, true); + obj.dispatchEvent(e); + } +}; diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/spec/index.js b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/spec/index.js new file mode 100644 index 0000000..121cf63 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/www/spec/index.js @@ -0,0 +1,49 @@ +describe('app', function() { + describe('initialize', function() { + it('should bind deviceready', function() { + runs(function() { + spyOn(app, 'deviceready'); + app.initialize(); + helper.trigger(window.document, 'deviceready'); + }); + + waitsFor(function() { + return (app.deviceready.calls.length > 0); + }, 'deviceready should be called once', 500); + + runs(function() { + expect(app.deviceready).toHaveBeenCalled(); + }); + }); + }); + + describe('deviceready', function() { + it('should report that it fired', function() { + spyOn(app, 'report'); + app.deviceready(); + expect(app.report).toHaveBeenCalledWith('deviceready'); + }); + }); + + describe('report', function() { + beforeEach(function() { + var el = document.getElementById('stage'); + el.innerHTML = ['
', + '

Pending

', + '

Complete

', + '
'].join('\n'); + }); + + it('should show the completion state', function() { + app.report('deviceready'); + var el = document.querySelector('#deviceready .complete:not(.hide)'); + expect(el).toBeTruthy(); + }); + + it('should hide the pending state', function() { + app.report('deviceready'); + var el = document.querySelector('#deviceready .pending.hide'); + expect(el).toBeTruthy(); + }); + }); +}); diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/BOOM b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/BOOM new file mode 100644 index 0000000..37c623c --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/BOOM @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) + +bash $CORDOVA_PATH/cordova BOOM diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/appinfo.jar b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/appinfo.jar new file mode 100644 index 0000000..37e00df Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/appinfo.jar differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/clean b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/clean new file mode 100644 index 0000000..daa8442 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/clean @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) + +bash $CORDOVA_PATH/cordova clean diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/cordova b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/cordova new file mode 100644 index 0000000..0bca03f --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/cordova @@ -0,0 +1,85 @@ +#!/bin/bash + +set -e + +PROJECT_PATH=$( cd "$( dirname "$0" )/.." && pwd ) + +function check_devices { + local devices=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}'` + if [ -z "$devices" ] ; then + echo "1" + else + echo "0" + fi +} + +function emulate { + declare -a avd_list=($(android list avd | grep "Name:" | cut -f 2 -d ":" | xargs)) + # we need to start adb-server + adb start-server 1>/dev/null + + # Do not launch an emulator if there is already one running or if a device is attached + if [ $(check_devices) == 0 ] ; then + echo "Device attached or emulator already running" + return + fi + + local avd_id="1000" #FIXME: hopefully user does not have 1000 AVDs + # User has no AVDs + if [ ${#avd_list[@]} == 0 ] + then + echo "You don't have any Android Virtual Devices. Please create at least one AVD." + echo "android" + fi + # User has only one AVD + if [ ${#avd_list[@]} == 1 ] + then + emulator -cpu-delay 0 -no-boot-anim -cache /tmp/cache -avd ${avd_list[0]} 1> /dev/null 2>&1 & + # User has more than 1 AVD + elif [ ${#avd_list[@]} -gt 1 ] + then + while [ -z ${avd_list[$avd_id]} ] + do + echo "Choose from one of the following Android Virtual Devices [0 to $((${#avd_list[@]}-1))]:" + for(( i = 0 ; i < ${#avd_list[@]} ; i++ )) + do + echo "$i) ${avd_list[$i]}" + done + echo -n "> " + read avd_id + done + emulator -cpu-delay 0 -no-boot-anim -cache /tmp/cache -avd ${avd_list[$avd_id]} 1> /dev/null 2>&1 & + fi + +} + +function clean { + ant clean +} +# has to be used independently and not in conjuction with other commands +function log { + adb logcat +} + +function debug { + if [ $(check_devices) == 0 ] ; then + ant debug install + else + ant debug + echo "##################################################################" + echo "# Plug in your device or launch an emulator with cordova/emulate #" + echo "##################################################################" + fi +} + +function launch { + local launch_str=$(java -jar $PROJECT_PATH/cordova/appinfo.jar $PROJECT_PATH/AndroidManifest.xml) + adb shell am start -n $launch_str +} + +function BOOM { + clean && debug && launch +} + +# TODO parse arguments +(cd $PROJECT_PATH && $1) diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/debug b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/debug new file mode 100644 index 0000000..5d63a39 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/debug @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) + +bash $CORDOVA_PATH/cordova debug diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/emulate b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/emulate new file mode 100644 index 0000000..6c4fab2 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/emulate @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) + +bash $CORDOVA_PATH/cordova emulate diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/log b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/log new file mode 100644 index 0000000..ab3622e --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/log @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +PROJECT_PATH=$( cd "$( dirname "$0" )/.." && pwd ) + +bash $PROJECT_PATH/cordova/cordova log diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/libs/cordova-2.0.0.jar b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/libs/cordova-2.0.0.jar new file mode 100644 index 0000000..e01123b Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/libs/cordova-2.0.0.jar differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/proguard-project.txt b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/proguard-project.txt new file mode 100644 index 0000000..f2fe155 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/project.properties b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/project.properties new file mode 100644 index 0000000..0840b4a --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-15 diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-hdpi/ic_launcher.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..96a442e Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-hdpi/ic_launcher.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-ldpi/ic_launcher.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-ldpi/ic_launcher.png new file mode 100644 index 0000000..9923872 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-ldpi/ic_launcher.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-mdpi/ic_launcher.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..359047d Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-mdpi/ic_launcher.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-xhdpi/ic_launcher.png b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..71c6d76 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/drawable-xhdpi/ic_launcher.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/layout/main.xml b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/layout/main.xml new file mode 100644 index 0000000..991ac56 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/layout/main.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/values/strings.xml b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/values/strings.xml new file mode 100644 index 0000000..de42976 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/values/strings.xml @@ -0,0 +1,7 @@ + + + + Hello World, PhonegapSampleActivity! + Hello World + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/xml/config.xml b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/xml/config.xml new file mode 100644 index 0000000..13694f4 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/res/xml/config.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/src/com/wikitude/phonegap/PhonegapSampleActivity.java b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/src/com/wikitude/phonegap/PhonegapSampleActivity.java new file mode 100644 index 0000000..435e9e4 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/src/com/wikitude/phonegap/PhonegapSampleActivity.java @@ -0,0 +1,17 @@ +package com.wikitude.phonegap; + +import org.apache.cordova.DroidGap; + +import android.os.Bundle; + + + +public class PhonegapSampleActivity extends DroidGap { + /** Called when the activity is first created. */ + @Override + public void onCreate( Bundle savedInstanceState ) { + super.onCreate( savedInstanceState ); + super.loadUrl( "file:///android_asset/www/index.html" ); + // super.loadUrl( "file:///android_asset/www/demo.html" ); + } +} \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/src/com/wikitude/phonegap/WikitudePlugin.java b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/src/com/wikitude/phonegap/WikitudePlugin.java new file mode 100644 index 0000000..f88af1d --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/src/com/wikitude/phonegap/WikitudePlugin.java @@ -0,0 +1,417 @@ +package com.wikitude.phonegap; + +import java.io.IOException; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.app.Activity; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.view.ViewManager; + +import com.phonegap.api.Plugin; +import com.phonegap.api.PluginResult; +import com.wikitude.architect.ArchitectUrlListener; +import com.wikitude.architect.ArchitectView; +import com.wikitude.architect.ArchitectView.ArchitectConfig; + + + +/** + * Basic PhoneGap Wikitude ARchitect Plugin + * + * @author Wikitude GmbH + */ +public class WikitudePlugin extends Plugin implements ArchitectUrlListener { + + /** PhoneGap-root to Android-App-assets folder */ + private static final String LOCAL_ASSETS_PATH_ROOT = "assets/"; + + /* various JSON-Object keys*/ + private static final String JSON_KEY_APIKEY = "sdkKey"; + private static final String JSON_KEY_FILE_PATH = "filePath"; + + private static final String JSON_KEY_LOCATION_ALTITUDE = "alt"; + private static final String JSON_KEY_LOCATION_ACCURACY = "acc"; + private static final String JSON_KEY_LOCATION_LATITUDE = "lat"; + private static final String JSON_KEY_LOCATION_LONGITUDE = "lon"; + + /* static action strings */ + + /** + * opens architect-view (add to view stack) + */ + private static final String ACTION_OPEN = "open"; + + /** + * closes architect-view (remove view stack) + */ + private static final String ACTION_CLOSE = "close"; + + /** + * set visibility of architectView to visible (of present) + */ + private static final String ACTION_SHOW = "show"; + + /** + * set visibility of architectView to invisible (of present) + */ + private static final String ACTION_HIDE = "hide"; + + /** + * inject location information + */ + private static final String ACTION_SET_LOCATION = "setLocation"; + + /** + * callback for uri-invocations + */ + private static final String ACTION_ON_URLINVOKE = "onUrlInvoke"; + + /** + * life-cycle notification for resume + */ + private static final String ACTION_ON_RESUME = "onResume"; + + /** + * life-cycle notification for pause + */ + private static final String ACTION_ON_PAUSE = "onPause"; + + /** + * check if view is on view-stack (no matter if visible or not) + */ + private static final String ACTION_STATE_ISOPEN = "isOpen"; + + /** + * opens architect-view (add to view stack) + */ + private static final String ACTION_IS_DEVICE_SUPPORTED = "isDeviceSupported"; + + /** + * check if view is on view-stack (no matter if visible or not) + */ + private static final String ACTION_CALL_JAVASCRIPT = "callJavascript"; + + /** + * the Wikitude ARchitectview + */ + private ArchitectView architectView; + + /** + * callback-Id of url-invocation method + */ + private String urlInvokeCallbackId = null; + + /** + * callback-id of "open"-action method + */ + private String openCallbackId = null; + + @Override + public PluginResult execute( final String action, final JSONArray args, final String callbackId ) { + + /* hide architect-view -> destroy and remove from activity */ + if ( WikitudePlugin.ACTION_CLOSE.equals( action ) ) { + if ( this.architectView != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + removeArchitectView(); + } + } ); + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } + else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* return success only if view is opened (no matter if visible or not) */ + if ( WikitudePlugin.ACTION_STATE_ISOPEN.equals( action ) ) { + if ( this.architectView != null ) { + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* return success only if view is opened (no matter if visible or not) */ + if ( WikitudePlugin.ACTION_IS_DEVICE_SUPPORTED.equals( action ) ) { + if ( ArchitectView.isDeviceSupported( this.cordova.getActivity() ) ) { + return new PluginResult( PluginResult.Status.OK, action + ": this device is ARchitect-ready" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": Sorry, this device is NOT ARchitect-ready" ); + } + } + + + + /* life-cycle's RESUME */ + if ( WikitudePlugin.ACTION_ON_RESUME.equals( action ) ) { + + if ( this.architectView != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + WikitudePlugin.this.architectView.onResume(); + } + } ); + + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + + /* life-cycle's PAUSE */ + if ( WikitudePlugin.ACTION_ON_PAUSE.equals( action ) ) { + if ( architectView != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + WikitudePlugin.this.architectView.onPause(); + } + } ); + + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + + /* set visibility to "visible", return error if view is null */ + if ( WikitudePlugin.ACTION_SHOW.equals( action ) ) { + + if ( this.architectView != null ) { + this.architectView.setVisibility( View.VISIBLE ); + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* set visibility to "invisible", return error if view is null */ + if ( WikitudePlugin.ACTION_HIDE.equals( action ) ) { + + if ( this.architectView != null ) { + this.architectView.setVisibility( View.INVISIBLE ); + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* define call-back for url-invocations */ + if ( WikitudePlugin.ACTION_ON_URLINVOKE.equals( action ) ) { + this.urlInvokeCallbackId = callbackId; + PluginResult result = new PluginResult( PluginResult.Status.NO_RESULT, action + ": registered callback" ); + result.setKeepCallback( true ); + return result; + } + + /* location update */ + if ( WikitudePlugin.ACTION_SET_LOCATION.equals( action ) ) { + if ( this.architectView != null ) { + try { + String arrStr = args.getString( 0 ); + JSONObject arr = new JSONObject( arrStr ); + final double lat = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_LATITUDE ); + final double lon = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_LONGITUDE ); + Object altObj = arr.get( WikitudePlugin.JSON_KEY_LOCATION_ALTITUDE ); + float alt = Float.MIN_VALUE; + + if ( altObj != null && altObj instanceof Double ) { + alt = ((Double)altObj).floatValue(); + } + + final float altitude = alt; + + final Double acc = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_ACCURACY ); + if ( this.cordova != null && this.cordova.getActivity() != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + if ( acc != null ) { + WikitudePlugin.this.architectView.setLocation( lat, lon, altitude, acc.floatValue() ); + } else { + WikitudePlugin.this.architectView.setLocation( lat, lon, altitude ); + } + } + } ); + } + + } catch ( Exception e ) { + return new PluginResult( PluginResult.Status.ERROR, action + ": exception thrown, " + e != null ? e.getMessage() : "(exception is NULL)" ); + } + return new PluginResult( PluginResult.Status.OK, action + ": updated location" ); + } + + /* return error if there is no architect-view active*/ + return new PluginResult( PluginResult.Status.ERROR, action + ": architectview is not active" ); + } + + if ( WikitudePlugin.ACTION_CALL_JAVASCRIPT.equals( action ) ) { + if ( this.architectView != null ) { + String logMsg = null; + try { + final String callJS = args.getString( 0 ); + logMsg = callJS; + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + WikitudePlugin.this.architectView.callJavascript( callJS ); + } + } ); + + } catch ( JSONException je ) { + return new PluginResult( PluginResult.Status.ERROR, action + ": exception thrown, " + je != null ? je.getMessage() : "(exception is NULL)" ); + } + return new PluginResult( PluginResult.Status.OK, action + ": called js, '" + logMsg + "'" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectview is not active" ); + } + } + + + /* initial set-up, show ArchitectView full-screen in current screen/activity */ + if ( WikitudePlugin.ACTION_OPEN.equals( action ) ) { + this.openCallbackId = callbackId; + PluginResult result = null; + String arrStr = null; + + try { + arrStr = args.getString( 0 ); + + // arrStr = arrStr.substring( 1, arrStr.length() - 1 ); + + JSONObject arr = new JSONObject( arrStr ); + + final String apiKey = arr.getString( WikitudePlugin.JSON_KEY_APIKEY ); + final String filePath = arr.getString( WikitudePlugin.JSON_KEY_FILE_PATH ); + + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + try { + WikitudePlugin.this.addArchitectView( apiKey, filePath ); + + /* call success method once architectView was added successfully */ + if ( WikitudePlugin.this.openCallbackId != null ) { + PluginResult result = new PluginResult( PluginResult.Status.OK ); + result.setKeepCallback( false ); + WikitudePlugin.this.success( result, WikitudePlugin.this.openCallbackId ); + } + } catch ( Exception e ) { + /* in case "addArchitectView" threw an exception -> notify callback method asynchronously */ + WikitudePlugin.this.error( e != null ? e.getMessage() : "Exception is 'null'", WikitudePlugin.this.openCallbackId ); + } + } + } ); + + } catch ( Exception e ) { + result = new PluginResult( PluginResult.Status.ERROR, action + ": exception thown, " + e != null ? e.getMessage() : "(exception is NULL)" ); + result.setKeepCallback( false ); + return result; + } + + /* adding architect-view is done in separate thread, ensure to setKeepCallback so one can call success-method properly later on */ + result = new PluginResult( PluginResult.Status.NO_RESULT, action + ": no result required, just registered callback-method" ); + result.setKeepCallback( true ); + + return result; + } + + /* fall-back return value */ + return new PluginResult( PluginResult.Status.ERROR, "no such action: " + action ); + } + + /** + * called when url was invoked in architectView (by e.g. calling document.location = "myprotocoll://foo"; + * @param url the invoked url (e.g. "myprotocoll://foo") + * @return true if call was handled properly + */ + @Override + public boolean urlWasInvoked( String url ) { + + /* call callback-method if set*/ + if ( this.urlInvokeCallbackId != null ) { + try { + /* pass called url as String to callback-method */ + PluginResult res = new PluginResult( PluginResult.Status.OK, url ); + res.setKeepCallback( true ); + this.success( res, this.urlInvokeCallbackId ); + return true; + } catch ( Exception e ) { + this.error( "invalid url invoked: " + url, this.urlInvokeCallbackId ); + } + } + return false; + } + + /** + * hides/removes ARchitect-View completely + * @return true if successful, false otherwise + */ + private boolean removeArchitectView() { + if ( this.architectView != null ) { + /* fake life-cycle calls, because activity is already up and running */ + this.architectView.onPause(); + this.architectView.onDestroy(); + this.architectView.setVisibility( View.INVISIBLE ); + ((ViewManager)this.architectView.getParent()).removeView( this.architectView ); + this.architectView = null; + return true; + } + return false; + } + + /** + * Architect-Configuration required for proper set-up + * @param apiKey + * @return + */ + protected ArchitectConfig getArchitectConfig( final String apiKey ) { + /* no special set-up required in default Wikitude-Plugin, further things required in advanced usage (e.g. Vuforia Image Recognition) */ + return new ArchitectConfig( apiKey ); + } + + /** + * add architectView to current screen + * @param apiKey developers's api key to use (hides watermarking/intro-animation if it matches your package-name) + * @param filePath the url (starting with http:// for online use; starting with LOCAL_ASSETS_PATH_ROOT if oyu want to load assets within your app-assets folder) + * @throws IOException might be thrown from ARchitect-SDK + */ + @SuppressWarnings("deprecation") + private void addArchitectView( final String apiKey, String filePath ) throws IOException { + if ( this.architectView == null ) { + this.architectView = new ArchitectView( (Activity)this.ctx.getContext() ); + + /* add content view and fake initial life-cycle */ + ((Activity)this.ctx.getContext()).addContentView( this.architectView, new ViewGroup.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT ) ); + + /* fake life-cycle calls, because activity is already up and running */ + this.architectView.onCreate( getArchitectConfig( apiKey ) ); + this.architectView.onPostCreate(); + + /* register self as url listener to fwd these native calls to PhoneGap */ + this.architectView.registerUrlListener( WikitudePlugin.this ); + + /* load asset from local directory if prefix is used */ + if ( filePath.startsWith( WikitudePlugin.LOCAL_ASSETS_PATH_ROOT ) ) { + filePath = filePath.substring( WikitudePlugin.LOCAL_ASSETS_PATH_ROOT.length() ); + } + this.architectView.load( filePath ); + + /* also a fake-life-cycle call (the last one before it is really shown in UI */ + this.architectView.onResume(); + } + } +} diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Basic/README.md b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/README.md new file mode 100644 index 0000000..e8ccd3a --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Basic/README.md @@ -0,0 +1,14 @@ +# Hello World +This sample dispalys Hello world in the camera +The project is a stand-alone Sample PhoneGap Android Project using the basic Wikitude PhoneGap plugin to display "Hello World" in the camera-view. Solely the wikitudesdk.jar needs to be pasted to the project and [added to build path](https://www.google.com/webhp?sourceid=chrome-instant&ie=UTF-8&ion=1#hl=de&sclient=psy-ab&q=how+to+add+library+to+build+path+in+eclipse&oq=how+to+add+library+to+build+path+in+eclipse&gs_l=serp.3...4768.4984.1.5346.3.3.0.0.0.1.116.271.2j1.3.0...0.0...1c.1.Nk4mv2tTjuA&pbx=1&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.&fp=a6ff543f77bf189e&ion=1&biw=1236&bih=661) + to get rid of the compile-time errors + +####Prerequisites: +* You need to [register as developer at Wikitude](http://developer.wikitude.com) and downloaded the SDK +# SETUP + + +* [Import it in Eclipse as Android-Project](https://www.google.com/webhp?sourceid=chrome-instant&ie=UTF-8&ion=1#hl=de&output=search&sclient=psy-ab&q=import%20android%20project%20into%20eclipse&oq=&gs_l=&pbx=1&fp=531bf0abdc9ea0e7&ion=1&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.&biw=1030&bih=550) +* Copy `wikitudesdk.jar` from the Android [WikitudeSDK](http://developer.wikitude.com) to project's `libs`-folder +* Run the application on your device / emulator + diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/.classpath b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/.classpath new file mode 100644 index 0000000..36bd4cc --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/.project b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/.project new file mode 100644 index 0000000..a0515ec --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/.project @@ -0,0 +1,33 @@ + + + HelloImageRecognition + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/AndroidManifest.xml b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/AndroidManifest.xml new file mode 100644 index 0000000..159c389 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/AndroidManifest.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/DirectionArrow.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/DirectionArrow.png new file mode 100644 index 0000000..8a0ccb6 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/DirectionArrow.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/SimpleIRWorld.html b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/SimpleIRWorld.html new file mode 100644 index 0000000..4b23026 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/SimpleIRWorld.html @@ -0,0 +1,117 @@ + + + + + + +Simple IR World + + + + + + + + + + + + +
Loading ...
+ + + + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.png new file mode 100644 index 0000000..f820ca0 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.zip b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.zip new file mode 100644 index 0000000..34db5dc Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.zip differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/overlay.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/overlay.png new file mode 100644 index 0000000..5d2dfcd Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/overlay.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/cordova-2.0.0.js b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/cordova-2.0.0.js new file mode 100644 index 0000000..ba9e6a9 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/cordova-2.0.0.js @@ -0,0 +1,5724 @@ +// commit 114cf5304a74ff8f7c9ff1d21cf5652298af04b0 + +// File generated at :: Wed Jul 18 2012 14:44:33 GMT-0700 (PDT) + +/* + 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 0) { + var v = JSON.parse(r); + + // 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 (success) { + try { + success(v.message); + } catch (e) { + console.log("Error in success callback: " + callbackId + " = " + e); + } + + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + return v.message; + } + + // If no result + else if (v.status === cordova.callbackStatus.NO_RESULT) { + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + + // If error, then display error + else { + console.log("Error: Status="+v.status+" Message="+v.message); + + // If there is a fail callback, then call it now with returned value + if (fail) { + try { + fail(v.message); + } + catch (e1) { + console.log("Error in error callback: "+callbackId+" = "+e1); + } + + // Clear callback if not expecting any more results + if (!v.keepCallback) { + delete cordova.callbacks[callbackId]; + } + } + return null; + } + } + } catch (e2) { + console.log("Error: "+e2); + } +}; + +}); + +// file: lib/android/platform.js +define("cordova/platform", function(require, exports, module) { +module.exports = { + id: "android", + initialize:function() { + var channel = require("cordova/channel"), + cordova = require('cordova'), + callback = require('cordova/plugin/android/callback'), + polling = require('cordova/plugin/android/polling'), + exec = require('cordova/exec'); + + channel.onDestroy.subscribe(function() { + cordova.shuttingDown = true; + }); + + // Start listening for XHR callbacks + // Figure out which bridge approach will work on this Android + // device: polling or XHR-based callbacks + setTimeout(function() { + if (cordova.UsePolling) { + polling(); + } + else { + var isPolling = prompt("usePolling", "gap_callbackServer:"); + cordova.UsePolling = isPolling; + if (isPolling == "true") { + cordova.UsePolling = true; + polling(); + } else { + cordova.UsePolling = false; + callback(); + } + } + }, 1); + + // Inject a listener for the backbutton on the document. + var backButtonChannel = cordova.addDocumentEventHandler('backbutton', { + onSubscribe:function() { + // If we just attached the first handler, let native know we need to override the back button. + if (this.numHandlers === 1) { + exec(null, null, "App", "overrideBackbutton", [true]); + } + }, + onUnsubscribe:function() { + // If we just detached the last handler, let native know we no longer override the back button. + if (this.numHandlers === 0) { + exec(null, null, "App", "overrideBackbutton", [false]); + } + } + }); + + // Add hardware MENU and SEARCH button handlers + cordova.addDocumentEventHandler('menubutton'); + cordova.addDocumentEventHandler('searchbutton'); + + // Figure out if we need to shim-in localStorage and WebSQL + // support from the native side. + var storage = require('cordova/plugin/android/storage'); + + // First patch WebSQL if necessary + if (typeof window.openDatabase == 'undefined') { + // Not defined, create an openDatabase function for all to use! + window.openDatabase = storage.openDatabase; + } else { + // Defined, but some Android devices will throw a SECURITY_ERR - + // so we wrap the whole thing in a try-catch and shim in our own + // if the device has Android bug 16175. + var originalOpenDatabase = window.openDatabase; + window.openDatabase = function(name, version, desc, size) { + var db = null; + try { + db = originalOpenDatabase(name, version, desc, size); + } + catch (ex) { + if (ex.code === 18) { + db = null; + } else { + throw ex; + } + } + + if (db === null) { + return storage.openDatabase(name, version, desc, size); + } + else { + return db; + } + + }; + } + + // Patch localStorage if necessary + if (typeof window.localStorage == 'undefined' || window.localStorage === null) { + window.localStorage = new storage.CupcakeLocalStorage(); + } + + // Let native code know we are all done on the JS side. + // Native code will then un-hide the WebView. + channel.join(function() { + exec(null, null, "App", "show", []); + }, [channel.onCordovaReady]); + }, + objects: { + cordova: { + children: { + JSCallback:{ + path:"cordova/plugin/android/callback" + }, + JSCallbackPolling:{ + path:"cordova/plugin/android/polling" + } + } + }, + navigator: { + children: { + app:{ + path: "cordova/plugin/android/app" + } + } + }, + File: { // exists natively on Android WebView, override + path: "cordova/plugin/File" + }, + FileReader: { // exists natively on Android WebView, override + path: "cordova/plugin/FileReader" + }, + FileError: { //exists natively on Android WebView on Android 4.x + path: "cordova/plugin/FileError" + }, + MediaError: { // exists natively on Android WebView on Android 4.x + path: "cordova/plugin/MediaError" + } + }, + merges: { + device: { + path: 'cordova/plugin/android/device' + }, + navigator: { + children: { + notification: { + path: 'cordova/plugin/android/notification' + } + } + } + } +}; + +}); + +// 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.} phoneNumbers array of phone numbers +* @param {Array.} emails array of email addresses +* @param {Array.} addresses array of addresses +* @param {Array.} ims instant messaging user ids +* @param {Array.} organizations +* @param {DOMString} birthday contact's birthday +* @param {DOMString} note user notes about contact +* @param {Array.} photos +* @param {Array.} categories +* @param {Array.} 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][;base64], + * + * @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.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/android/plugin/android/app.js +define("cordova/plugin/android/app", function(require, exports, module) { +var exec = require('cordova/exec'); + +module.exports = { + /** + * Clear the resource cache. + */ + clearCache:function() { + exec(null, null, "App", "clearCache", []); + }, + + /** + * Load the url into the webview or into new browser instance. + * + * @param url The URL to load + * @param props Properties that can be passed in to the activity: + * wait: int => wait msec before loading URL + * loadingDialog: "Title,Message" => display a native loading dialog + * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error + * clearHistory: boolean => clear webview history (default=false) + * openExternal: boolean => open in a new browser (default=false) + * + * Example: + * navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000}); + */ + loadUrl:function(url, props) { + exec(null, null, "App", "loadUrl", [url, props]); + }, + + /** + * Cancel loadUrl that is waiting to be loaded. + */ + cancelLoadUrl:function() { + exec(null, null, "App", "cancelLoadUrl", []); + }, + + /** + * Clear web history in this web view. + * Instead of BACK button loading the previous web page, it will exit the app. + */ + clearHistory:function() { + exec(null, null, "App", "clearHistory", []); + }, + + /** + * Go to previous page displayed. + * This is the same as pressing the backbutton on Android device. + */ + backHistory:function() { + exec(null, null, "App", "backHistory", []); + }, + + /** + * Override the default behavior of the Android back button. + * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired. + * + * Note: The user should not have to call this method. Instead, when the user + * registers for the "backbutton" event, this is automatically done. + * + * @param override T=override, F=cancel override + */ + overrideBackbutton:function(override) { + exec(null, null, "App", "overrideBackbutton", [override]); + }, + + /** + * Exit and terminate the application. + */ + exitApp:function() { + return exec(null, null, "App", "exitApp", []); + } +}; +}); + +// file: lib/android/plugin/android/callback.js +define("cordova/plugin/android/callback", function(require, exports, module) { +var port = null, + token = null, + cordova = require('cordova'), + polling = require('cordova/plugin/android/polling'), + callback = function() { + // Exit if shutting down app + if (cordova.shuttingDown) { + return; + } + + // If polling flag was changed, start using polling from now on + if (cordova.UsePolling) { + polling(); + return; + } + + var xmlhttp = new XMLHttpRequest(); + + // Callback function when XMLHttpRequest is ready + xmlhttp.onreadystatechange=function(){ + if(xmlhttp.readyState === 4){ + + // Exit if shutting down app + if (cordova.shuttingDown) { + return; + } + + // If callback has JavaScript statement to execute + if (xmlhttp.status === 200) { + + // Need to url decode the response + var msg = decodeURIComponent(xmlhttp.responseText); + setTimeout(function() { + try { + var t = eval(msg); + } + catch (e) { + // If we're getting an error here, seeing the message will help in debugging + console.log("JSCallback: Message from Server: " + msg); + console.log("JSCallback Error: "+e); + } + }, 1); + setTimeout(callback, 1); + } + + // If callback ping (used to keep XHR request from timing out) + else if (xmlhttp.status === 404) { + setTimeout(callback, 10); + } + + // If security error + else if (xmlhttp.status === 403) { + console.log("JSCallback Error: Invalid token. Stopping callbacks."); + } + + // If server is stopping + else if (xmlhttp.status === 503) { + console.log("JSCallback Server Closed: Stopping callbacks."); + } + + // If request wasn't GET + else if (xmlhttp.status === 400) { + console.log("JSCallback Error: Bad request. Stopping callbacks."); + } + + // If error, revert to polling + else { + console.log("JSCallback Error: Request failed."); + cordova.UsePolling = true; + polling(); + } + } + }; + + if (port === null) { + port = prompt("getPort", "gap_callbackServer:"); + } + if (token === null) { + token = prompt("getToken", "gap_callbackServer:"); + } + xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true); + xmlhttp.send(); +}; + +module.exports = callback; +}); + +// file: lib/android/plugin/android/device.js +define("cordova/plugin/android/device", function(require, exports, module) { +var channel = require('cordova/channel'), + utils = require('cordova/utils'), + exec = require('cordova/exec'), + app = require('cordova/plugin/android/app'); + +module.exports = { + /* + * DEPRECATED + * This is only for Android. + * + * You must explicitly override the back button. + */ + overrideBackButton:function() { + console.log("Device.overrideBackButton() is deprecated. Use App.overrideBackbutton(true)."); + app.overrideBackbutton(true); + }, + + /* + * DEPRECATED + * This is only for Android. + * + * This resets the back button to the default behaviour + */ + resetBackButton:function() { + console.log("Device.resetBackButton() is deprecated. Use App.overrideBackbutton(false)."); + app.overrideBackbutton(false); + }, + + /* + * DEPRECATED + * This is only for Android. + * + * This terminates the activity! + */ + exitApp:function() { + console.log("Device.exitApp() is deprecated. Use App.exitApp()."); + app.exitApp(); + } +}; + +}); + +// file: lib/android/plugin/android/notification.js +define("cordova/plugin/android/notification", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * Provides Android enhanced notification API. + */ +module.exports = { + activityStart : function(title, message) { + // If title and message not specified then mimic Android behavior of + // using default strings. + if (typeof title === "undefined" && typeof message == "undefined") { + title = "Busy"; + message = 'Please wait...'; + } + + exec(null, null, 'Notification', 'activityStart', [ title, message ]); + }, + + /** + * Close an activity dialog + */ + activityStop : function() { + exec(null, null, 'Notification', 'activityStop', []); + }, + + /** + * Display a progress dialog with progress bar that goes from 0 to 100. + * + * @param {String} + * title Title of the progress dialog. + * @param {String} + * message Message to display in the dialog. + */ + progressStart : function(title, message) { + exec(null, null, 'Notification', 'progressStart', [ title, message ]); + }, + + /** + * Close the progress dialog. + */ + progressStop : function() { + exec(null, null, 'Notification', 'progressStop', []); + }, + + /** + * Set the progress dialog value. + * + * @param {Number} + * value 0-100 + */ + progressValue : function(value) { + exec(null, null, 'Notification', 'progressValue', [ value ]); + } +}; +}); + +// file: lib/android/plugin/android/polling.js +define("cordova/plugin/android/polling", function(require, exports, module) { +var cordova = require('cordova'), + period = 50, + polling = function() { + // Exit if shutting down app + if (cordova.shuttingDown) { + return; + } + + // If polling flag was changed, stop using polling from now on and switch to XHR server / callback + if (!cordova.UsePolling) { + require('cordova/plugin/android/callback')(); + return; + } + + var msg = prompt("", "gap_poll:"); + if (msg) { + setTimeout(function() { + try { + var t = eval(""+msg); + } + catch (e) { + console.log("JSCallbackPolling: Message from Server: " + msg); + console.log("JSCallbackPolling Error: "+e); + } + }, 1); + setTimeout(polling, 1); + } + else { + setTimeout(polling, period); + } +}; + +module.exports = polling; +}); + +// file: lib/android/plugin/android/storage.js +define("cordova/plugin/android/storage", function(require, exports, module) { +var utils = require('cordova/utils'), + exec = require('cordova/exec'), + channel = require('cordova/channel'); + +var queryQueue = {}; + +/** + * SQL result set object + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Rows = function() { + this.resultSet = []; // results array + this.length = 0; // number of rows +}; + +/** + * Get item from SQL result set + * + * @param row The row number to return + * @return The row object + */ +DroidDB_Rows.prototype.item = function(row) { + return this.resultSet[row]; +}; + +/** + * SQL result set that is returned to user. + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Result = function() { + this.rows = new DroidDB_Rows(); +}; + +/** + * Callback from native code when query is complete. + * PRIVATE METHOD + * + * @param id Query id + */ +function completeQuery(id, data) { + var query = queryQueue[id]; + if (query) { + try { + delete queryQueue[id]; + + // Get transaction + var tx = query.tx; + + // If transaction hasn't failed + // Note: We ignore all query results if previous query + // in the same transaction failed. + if (tx && tx.queryList[id]) { + + // Save query results + var r = new DroidDB_Result(); + r.rows.resultSet = data; + r.rows.length = data.length; + try { + if (typeof query.successCallback === 'function') { + query.successCallback(query.tx, r); + } + } catch (ex) { + console.log("executeSql error calling user success callback: "+ex); + } + + tx.queryComplete(id); + } + } catch (e) { + console.log("executeSql error: "+e); + } + } +} + +/** + * Callback from native code when query fails + * PRIVATE METHOD + * + * @param reason Error message + * @param id Query id + */ +function failQuery(reason, id) { + var query = queryQueue[id]; + if (query) { + try { + delete queryQueue[id]; + + // Get transaction + var tx = query.tx; + + // If transaction hasn't failed + // Note: We ignore all query results if previous query + // in the same transaction failed. + if (tx && tx.queryList[id]) { + tx.queryList = {}; + + try { + if (typeof query.errorCallback === 'function') { + query.errorCallback(query.tx, reason); + } + } catch (ex) { + console.log("executeSql error calling user error callback: "+ex); + } + + tx.queryFailed(id, reason); + } + + } catch (e) { + console.log("executeSql error: "+e); + } + } +} + +/** + * SQL query object + * PRIVATE METHOD + * + * @constructor + * @param tx The transaction object that this query belongs to + */ +var DroidDB_Query = function(tx) { + + // Set the id of the query + this.id = utils.createUUID(); + + // Add this query to the queue + queryQueue[this.id] = this; + + // Init result + this.resultSet = []; + + // Set transaction that this query belongs to + this.tx = tx; + + // Add this query to transaction list + this.tx.queryList[this.id] = this; + + // Callbacks + this.successCallback = null; + this.errorCallback = null; + +}; + +/** + * Transaction object + * PRIVATE METHOD + * @constructor + */ +var DroidDB_Tx = function() { + + // Set the id of the transaction + this.id = utils.createUUID(); + + // Callbacks + this.successCallback = null; + this.errorCallback = null; + + // Query list + this.queryList = {}; +}; + +/** + * Mark query in transaction as complete. + * If all queries are complete, call the user's transaction success callback. + * + * @param id Query id + */ +DroidDB_Tx.prototype.queryComplete = function(id) { + delete this.queryList[id]; + + // If no more outstanding queries, then fire transaction success + if (this.successCallback) { + var count = 0; + var i; + for (i in this.queryList) { + if (this.queryList.hasOwnProperty(i)) { + count++; + } + } + if (count === 0) { + try { + this.successCallback(); + } catch(e) { + console.log("Transaction error calling user success callback: " + e); + } + } + } +}; + +/** + * Mark query in transaction as failed. + * + * @param id Query id + * @param reason Error message + */ +DroidDB_Tx.prototype.queryFailed = function(id, reason) { + + // The sql queries in this transaction have already been run, since + // we really don't have a real transaction implemented in native code. + // However, the user callbacks for the remaining sql queries in transaction + // will not be called. + this.queryList = {}; + + if (this.errorCallback) { + try { + this.errorCallback(reason); + } catch(e) { + console.log("Transaction error calling user error callback: " + e); + } + } +}; + +/** + * Execute SQL statement + * + * @param sql SQL statement to execute + * @param params Statement parameters + * @param successCallback Success callback + * @param errorCallback Error callback + */ +DroidDB_Tx.prototype.executeSql = function(sql, params, successCallback, errorCallback) { + + // Init params array + if (typeof params === 'undefined') { + params = []; + } + + // Create query and add to queue + var query = new DroidDB_Query(this); + queryQueue[query.id] = query; + + // Save callbacks + query.successCallback = successCallback; + query.errorCallback = errorCallback; + + // Call native code + exec(null, null, "Storage", "executeSql", [sql, params, query.id]); +}; + +var DatabaseShell = function() { +}; + +/** + * Start a transaction. + * Does not support rollback in event of failure. + * + * @param process {Function} The transaction function + * @param successCallback {Function} + * @param errorCallback {Function} + */ +DatabaseShell.prototype.transaction = function(process, errorCallback, successCallback) { + var tx = new DroidDB_Tx(); + tx.successCallback = successCallback; + tx.errorCallback = errorCallback; + try { + process(tx); + } catch (e) { + console.log("Transaction error: "+e); + if (tx.errorCallback) { + try { + tx.errorCallback(e); + } catch (ex) { + console.log("Transaction error calling user error callback: "+e); + } + } + } +}; + +/** + * Open database + * + * @param name Database name + * @param version Database version + * @param display_name Database display name + * @param size Database size in bytes + * @return Database object + */ +var DroidDB_openDatabase = function(name, version, display_name, size) { + exec(null, null, "Storage", "openDatabase", [name, version, display_name, size]); + var db = new DatabaseShell(); + return db; +}; + +/** + * For browsers with no localStorage we emulate it with SQLite. Follows the w3c api. + * TODO: Do similar for sessionStorage. + * @constructor + */ +var CupcakeLocalStorage = function() { + channel.waitForInitialization("cupcakeStorage"); + + try { + + this.db = openDatabase('localStorage', '1.0', 'localStorage', 2621440); + var storage = {}; + this.length = 0; + function setLength (length) { + this.length = length; + localStorage.length = length; + } + this.db.transaction( + function (transaction) { + var i; + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('SELECT * FROM storage', [], function(tx, result) { + for(var i = 0; i < result.rows.length; i++) { + storage[result.rows.item(i).id] = result.rows.item(i).body; + } + setLength(result.rows.length); + channel.initializationComplete("cupcakeStorage"); + }); + + }, + function (err) { + utils.alert(err.message); + } + ); + this.setItem = function(key, val) { + if (typeof(storage[key])=='undefined') { + this.length++; + } + storage[key] = val; + this.db.transaction( + function (transaction) { + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('REPLACE INTO storage (id, body) values(?,?)', [key,val]); + } + ); + }; + this.getItem = function(key) { + return storage[key]; + }; + this.removeItem = function(key) { + delete storage[key]; + this.length--; + this.db.transaction( + function (transaction) { + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('DELETE FROM storage where id=?', [key]); + } + ); + }; + this.clear = function() { + storage = {}; + this.length = 0; + this.db.transaction( + function (transaction) { + transaction.executeSql('CREATE TABLE IF NOT EXISTS storage (id NVARCHAR(40) PRIMARY KEY, body NVARCHAR(255))'); + transaction.executeSql('DELETE FROM storage', []); + } + ); + }; + this.key = function(index) { + var i = 0; + for (var j in storage) { + if (i==index) { + return j; + } else { + i++; + } + } + return null; + }; + + } catch(e) { + utils.alert("Database error "+e+"."); + return; + } +}; + +module.exports = { + openDatabase:DroidDB_openDatabase, + CupcakeLocalStorage:CupcakeLocalStorage, + failQuery:failQuery, + completeQuery:completeQuery +}; + +}); + +// 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 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 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/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 + + + + + + + PhoneGap and Wikitude + + + + + + + + Hello Cordova + + +
+

Apache Cordova™

+
+ + +
+
+ + + + + + diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/js/WikitudePlugin.js b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/js/WikitudePlugin.js new file mode 100644 index 0000000..bd09eb2 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/js/WikitudePlugin.js @@ -0,0 +1,383 @@ +var WikitudePlugin = { + + /** + * + * This is the SDK Key, provided to you after you purchased the Wikitude SDK from http://www.wikitude.com/developer/sdk + * If you're having a trial version, leave this string empty + * + */ + mySDKKey : "ENTER-YOUR-KEY-HERE", + + /** true if architectview is open */ + isOpened : false, + + /** + * + * called when user pressed back-button on Android device + * + */ + backButtonCallback : null, + + /** + * + * Change the value of this variable to modify the location update rate + * + */ + locationUpdateRate : 3000, + + /** + * + * This variable represents if the current device is capable of running the Wikitude SDK + * + */ + isDeviceSupported : false, + + /** + * + * This watchID is used to shedule location updates + * + */ + watchID : null, + + /** + * + * Callbacks to get device information if ARchitect Worlds can be launched + * + */ + onDeviceSupportedCallback : null, + onDeviceNotSupportedCallback : null, + + /** + * + * Callbacks to get notified if the ARchitect World finished launching or if something went wrong during the World launch + * + */ + onARchitectWorldLaunchedCallback : null, + onARchitectWorldFailedLaunchingCallback : null, + + /** + * + * This function gets called if PhoneGap reports that it has finished loading successfully. + * + */ + isDeviceSupported: function(successCallback, errorCallback) + { + + WikitudePlugin.onDeviceSupportedCallback = successCallback; + WikitudePlugin.onDeviceNotSupportedCallback = errorCallback; + + + // PhoneGap is running, so the first thing we do is to check if the current device is capable of running the Wikitude Plugin + cordova.exec(WikitudePlugin.deviceIsARchitectReady, WikitudePlugin.deviceIsNotARchitectReady, "WikitudePlugin", "isDeviceSupported", [""]); + + }, + + /** + * + * Declare what should happen when user pressed back-button while architect-view is opened. + * If not declared/called or null: ARchitect-View is closed + * + */ + onPressedBackButton : function(callback) + { + WikitudePlugin.backButtonCallback = callback; + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is able to start the Wikitude SDK + * + */ + deviceIsARchitectReady : function() + { + // We keep track of the device status + WikitudePlugin.isDeviceSupported = true; + + + if(WikitudePlugin.onDeviceSupportedCallback) + { + WikitudePlugin.onDeviceSupportedCallback(); + } + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is not able of starting the Wikitude SDK. + * + */ + deviceIsNotARchitectReady : function() + { + WikitudePlugin.isDeviceSupported = false; + + // In this case we notify the user that his device is not supported by the Wikitude SDK + if(WikitudePlugin.onDeviceNotSupportedCallback) + { + WikitudePlugin.onDeviceNotSupportedCallback(); + } + }, + + /* + * ============================================================================================================================= + * + * PUBLIC API + * + * ============================================================================================================================= + */ + + /* Managing ARchitect world loading */ + + /** + * + * Call this function if you want to load an ARchitect World + * + * @param {String} worldPath The path to an ARchitect world ether on the device or on e.g. your dropbox + * + */ + loadARchitectWorld : function(worldPath) + { + + // before we actually call load, we check again if the device is able to open the world + if(WikitudePlugin.isDeviceSupported) + { + + // the 'open' function of the Wikitude Plugin requires a option dictionary with two keys: + // @param {Object} options (required) + // @param {String} options.sdkKey License key for the Wikitude SDK + // @param {String} options.filePath The path to a local ARchitect world or to a ARchitect world on a server or your dropbox + + cordova.exec(WikitudePlugin.worldLaunched, WikitudePlugin.worldFailedLaunching, "WikitudePlugin", "open", [{ sdkKey: WikitudePlugin.mySDKKey, filePath: worldPath}]); + + + // We add an event listener on the resume and pause event of the application lifecycle + document.addEventListener("resume", WikitudePlugin.onResume, false); + document.addEventListener("pause", WikitudePlugin.onPause, false); + + WikitudePlugin.isOpened = true; + document.addEventListener("backbutton", WikitudePlugin.onBackButton, false); + + // After we started loading the world, we start location updates + WikitudePlugin.startLocationUpdates(); + + }else + { + // if the device is not able to start the Wikitude SDK, we notify the user again + WikitudePlugin.deviceNotARchitectReady(); + } + }, + + /* Managing the Wikitude SDK Lifecycle */ + + /** + * + * Use this function to stop the Wikitude SDK and to remove the ARchitectView from the screen + * + */ + close : function() + { + document.removeEventListener("pause", WikitudePlugin.onPause, false); + document.removeEventListener("resume", WikitudePlugin.onResume, false); + + WikitudePlugin.stopLocationUpdates(); + + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]); + WikitudePlugin.isOpened = false; + }, + + /** + * + * Use this function to only hide the Wikitude SDK. All location and rendering updates are still active + * + */ + hide : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "hide", [""]); + }, + + /** + * + * Use this function to show the Wikitude SDK if it was hidden before + * + */ + show : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "show", [""]); + }, + + /* Interacting with the Wikitude SDK */ + + /** + * + * Use this function to call javascript which will be executed in the context of your ARchitect World + * + * + * @param js The JavaScript that gets evaluated in context of the ARchitect World + * + */ + callJavaScript : function(js) + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "callJavascript", [js]); + }, + + /** + * + * Use this function to set a callback which will be invoked when the ARchitect World calls for example + * document.location = "architectsdk://opendetailpage?id=9"; + * + * + * @param onUrlInvokeCallback A function which gets called when the ARchitect World invokes a call to "document.location = architectsdk://" + */ + setOnUrlInvokeCallback : function(onUrlInvokeCallback) + { + cordova.exec(onUrlInvokeCallback, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]); + }, + + + /* + * ============================================================================================================================= + * + * Callbacks of public functions + * + * ============================================================================================================================= + */ + + /** + * + * Use this callback to get notified if the world loaded successfully + * + */ + worldLaunched : function() + { + if(WikitudePlugin.onARchitectWorldLaunchedCallback) + { + WikitudePlugin.onARchitectWorldLaunchedCallback(); + } + }, + + /** + * + * Use this callback to get notified if the Wikitude SDK wasn't able to load the ARchitect World + * + */ + worldFailedLaunching : function(err) + { + if(WikitudePlugin.onARchitectWorldFailedLaunchingCallback) + { + WikitudePlugin.onARchitectWorldFailedLaunchingCallback(err); + } + }, + + /* Lifecycle updates */ + + /** + * + * This function actually starts the PhoneGap location updates + * + */ + startLocationUpdates : function() + { + + WikitudePlugin.watchID = navigator.geolocation.watchPosition(WikitudePlugin.onReceivedLocation, WikitudePlugin.onWikitudeError, { frequency: WikitudePlugin.locationUpdateRate }); + }, + + /** + * + * This callback gets called everytime the location did update + * + */ + onReceivedLocation : function(position) + { + + // Every time that PhoneGap did received a location update, we pass the location into the Wikitude SDK + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "setLocation", [{ lat: position.coords.latitude, lon: position.coords.longitude, alt: position.coords.altitude, acc: position.coords.accuracy}]); + }, + + /** + * + * Use this function to stop location updates + * + */ + stopLocationUpdates : function() + { + + // We clear the location update watch which was responsible for updating the location in a specific time interval + navigator.geolocation.clearWatch(WikitudePlugin.watchID); + WikitudePlugin.watchID = null; + }, + + /** + * + * This function gets called every time the application did become active. + * + */ + onResume : function() + { + + // Call the Wikitude SDK that the application did become active again + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onResume", [""]); + + // And start continuing updating the user location + WikitudePlugin.startLocationUpdates(); + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onPause : function() + { + + // Call the Wikitude SDK that the application did resign active + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onPause", [""]); + + // And stop all ongoing location updates + WikitudePlugin.stopLocationUpdates(); + }, + + /** + * + * Android specific! + * This function gets called if the user presses the back button. + * You may define your own implementation by using WikitudePlugin.onPressedBackButton(method) + * + */ + onBackButton : function() + { + if (WikitudePlugin.isOpened) { + if (WikitudePlugin.backButtonCallback==null) { + WikitudePlugin.close(); + document.removeEventListener("backbutton", WikitudePlugin.onBackButton, false); + } else { + WikitudePlugin.backButtonCallback(); + } + } + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeOK : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeError : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + report: function(id) + { + console.log("app report: " + id); + } +}; diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/js/index.js b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/js/index.js new file mode 100644 index 0000000..b82a058 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/js/index.js @@ -0,0 +1,37 @@ +var app = { + initialize: function() { + this.bind(); + }, + bind: function() { + document.addEventListener('deviceready', this.deviceready, false); + }, + + // A callback which gets called if the device is able to launch ARchitect Worlds + onDeviceSupportedCallback : function() + { + // The device is able to launch ARchitect World, so lets do so :) + WikitudePlugin.loadARchitectWorld("assets/world/SimpleImageRecognition/SimpleIRWorld.html"); + }, + + // A callback which gets called if the device is not able to start ARchitect Worlds + onDeviceNotSupportedCallback : function() + { + app.report("Unable to launch ARchitect Worlds on this device"); + }, + + deviceready: function() { + // note that this is an event handler so the scope is that of the event + // so we need to call app.report(), and not this.report() + app.report('deviceready'); + + // check if the current device is able to launch ARchitect Worlds + WikitudePlugin.isDeviceSupported(app.onDeviceSupportedCallback, app.onDeviceNotSupportedCallback); + }, + report: function(id) { + console.log("report:" + id); + // hide the .pending

and show the .complete

+ document.querySelector('#' + id + ' .pending').className += ' hide'; + var completeElem = document.querySelector('#' + id + ' .complete'); + completeElem.className = completeElem.className.split('hide').join(''); + } +}; diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_128.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_128.png new file mode 100644 index 0000000..3516df3 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_128.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_16.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_16.png new file mode 100644 index 0000000..54e19c5 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_16.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_24.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_24.png new file mode 100644 index 0000000..c7d43ad Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_24.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_256.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_256.png new file mode 100644 index 0000000..e1cd0e6 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_256.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_32.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_32.png new file mode 100644 index 0000000..734fffc Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_32.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_48.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_48.png new file mode 100644 index 0000000..8ad8bac Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_48.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_512.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_512.png new file mode 100644 index 0000000..c9465f3 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_512.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_64.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_64.png new file mode 100644 index 0000000..03b3849 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_64.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_36.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_36.png new file mode 100644 index 0000000..cd5032a Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_36.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_48.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_48.png new file mode 100644 index 0000000..e79c606 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_48.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_72.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_72.png new file mode 100644 index 0000000..4d27634 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_72.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_96.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_96.png new file mode 100644 index 0000000..ec7ffbf Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_android_96.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_bb_80.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_bb_80.png new file mode 100644 index 0000000..f86a27a Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_bb_80.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_114.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_114.png new file mode 100644 index 0000000..efd9c37 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_114.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_144.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_144.png new file mode 100644 index 0000000..dd819da Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_144.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_57.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_57.png new file mode 100644 index 0000000..c795fc4 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_57.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_72.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_72.png new file mode 100644 index 0000000..b1cfde7 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/icon/cordova_ios_72.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_hdpi_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_hdpi_landscape.png new file mode 100644 index 0000000..a61e2b1 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_hdpi_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_hdpi_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_hdpi_portrait.png new file mode 100644 index 0000000..5d6a28a Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_hdpi_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_ldpi_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_ldpi_landscape.png new file mode 100644 index 0000000..f3934cd Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_ldpi_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_ldpi_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_ldpi_portrait.png new file mode 100644 index 0000000..65ad163 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_ldpi_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_mdpi_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_mdpi_landscape.png new file mode 100644 index 0000000..a1b697c Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_mdpi_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_mdpi_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_mdpi_portrait.png new file mode 100644 index 0000000..ea15693 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_mdpi_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_xhdpi_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_xhdpi_landscape.png new file mode 100644 index 0000000..79f2f09 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_xhdpi_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_xhdpi_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_xhdpi_portrait.png new file mode 100644 index 0000000..c2e8042 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/android_xhdpi_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/blackberry_transparent_300.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/blackberry_transparent_300.png new file mode 100644 index 0000000..b548bdc Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/blackberry_transparent_300.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/blackberry_transparent_400.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/blackberry_transparent_400.png new file mode 100644 index 0000000..3facdf9 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/blackberry_transparent_400.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_landscape.png new file mode 100644 index 0000000..04be5ac Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_portrait.png new file mode 100644 index 0000000..41e839d Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_retina_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_retina_landscape.png new file mode 100644 index 0000000..95c542d Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_retina_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_retina_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_retina_portrait.png new file mode 100644 index 0000000..aae1862 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/ipad_retina_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_landscape.png new file mode 100644 index 0000000..d154883 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_portrait.png new file mode 100644 index 0000000..6fcba56 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_retina_landscape.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_retina_landscape.png new file mode 100644 index 0000000..0165669 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_retina_landscape.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_retina_portrait.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_retina_portrait.png new file mode 100644 index 0000000..bd24886 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/iphone_retina_portrait.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/windows_phone_portrait.jpg b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/windows_phone_portrait.jpg new file mode 100644 index 0000000..9f95387 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/res/screen/windows_phone_portrait.jpg differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/spec.html b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/spec.html new file mode 100644 index 0000000..83d7d2e --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/spec.html @@ -0,0 +1,50 @@ + + + + Jasmine Spec Runner + + + + + + + + + + + + + + + + + +

+ + diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/spec/helper.js b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/spec/helper.js new file mode 100644 index 0000000..9f99445 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/spec/helper.js @@ -0,0 +1,11 @@ +afterEach(function() { + document.getElementById('stage').innerHTML = ''; +}); + +var helper = { + trigger: function(obj, name) { + var e = document.createEvent('Event'); + e.initEvent(name, true, true); + obj.dispatchEvent(e); + } +}; diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/spec/index.js b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/spec/index.js new file mode 100644 index 0000000..121cf63 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/www/spec/index.js @@ -0,0 +1,49 @@ +describe('app', function() { + describe('initialize', function() { + it('should bind deviceready', function() { + runs(function() { + spyOn(app, 'deviceready'); + app.initialize(); + helper.trigger(window.document, 'deviceready'); + }); + + waitsFor(function() { + return (app.deviceready.calls.length > 0); + }, 'deviceready should be called once', 500); + + runs(function() { + expect(app.deviceready).toHaveBeenCalled(); + }); + }); + }); + + describe('deviceready', function() { + it('should report that it fired', function() { + spyOn(app, 'report'); + app.deviceready(); + expect(app.report).toHaveBeenCalledWith('deviceready'); + }); + }); + + describe('report', function() { + beforeEach(function() { + var el = document.getElementById('stage'); + el.innerHTML = ['
', + '

Pending

', + '

Complete

', + '
'].join('\n'); + }); + + it('should show the completion state', function() { + app.report('deviceready'); + var el = document.querySelector('#deviceready .complete:not(.hide)'); + expect(el).toBeTruthy(); + }); + + it('should hide the pending state', function() { + app.report('deviceready'); + var el = document.querySelector('#deviceready .pending.hide'); + expect(el).toBeTruthy(); + }); + }); +}); diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/BOOM b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/BOOM new file mode 100644 index 0000000..37c623c --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/BOOM @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) + +bash $CORDOVA_PATH/cordova BOOM diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/appinfo.jar b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/appinfo.jar new file mode 100644 index 0000000..37e00df Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/appinfo.jar differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/clean b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/clean new file mode 100644 index 0000000..daa8442 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/clean @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) + +bash $CORDOVA_PATH/cordova clean diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/cordova b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/cordova new file mode 100644 index 0000000..0bca03f --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/cordova @@ -0,0 +1,85 @@ +#!/bin/bash + +set -e + +PROJECT_PATH=$( cd "$( dirname "$0" )/.." && pwd ) + +function check_devices { + local devices=`adb devices | awk '/List of devices attached/ { while(getline > 0) { print }}'` + if [ -z "$devices" ] ; then + echo "1" + else + echo "0" + fi +} + +function emulate { + declare -a avd_list=($(android list avd | grep "Name:" | cut -f 2 -d ":" | xargs)) + # we need to start adb-server + adb start-server 1>/dev/null + + # Do not launch an emulator if there is already one running or if a device is attached + if [ $(check_devices) == 0 ] ; then + echo "Device attached or emulator already running" + return + fi + + local avd_id="1000" #FIXME: hopefully user does not have 1000 AVDs + # User has no AVDs + if [ ${#avd_list[@]} == 0 ] + then + echo "You don't have any Android Virtual Devices. Please create at least one AVD." + echo "android" + fi + # User has only one AVD + if [ ${#avd_list[@]} == 1 ] + then + emulator -cpu-delay 0 -no-boot-anim -cache /tmp/cache -avd ${avd_list[0]} 1> /dev/null 2>&1 & + # User has more than 1 AVD + elif [ ${#avd_list[@]} -gt 1 ] + then + while [ -z ${avd_list[$avd_id]} ] + do + echo "Choose from one of the following Android Virtual Devices [0 to $((${#avd_list[@]}-1))]:" + for(( i = 0 ; i < ${#avd_list[@]} ; i++ )) + do + echo "$i) ${avd_list[$i]}" + done + echo -n "> " + read avd_id + done + emulator -cpu-delay 0 -no-boot-anim -cache /tmp/cache -avd ${avd_list[$avd_id]} 1> /dev/null 2>&1 & + fi + +} + +function clean { + ant clean +} +# has to be used independently and not in conjuction with other commands +function log { + adb logcat +} + +function debug { + if [ $(check_devices) == 0 ] ; then + ant debug install + else + ant debug + echo "##################################################################" + echo "# Plug in your device or launch an emulator with cordova/emulate #" + echo "##################################################################" + fi +} + +function launch { + local launch_str=$(java -jar $PROJECT_PATH/cordova/appinfo.jar $PROJECT_PATH/AndroidManifest.xml) + adb shell am start -n $launch_str +} + +function BOOM { + clean && debug && launch +} + +# TODO parse arguments +(cd $PROJECT_PATH && $1) diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/debug b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/debug new file mode 100644 index 0000000..5d63a39 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/debug @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) + +bash $CORDOVA_PATH/cordova debug diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/emulate b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/emulate new file mode 100644 index 0000000..6c4fab2 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/emulate @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) + +bash $CORDOVA_PATH/cordova emulate diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/log b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/log new file mode 100644 index 0000000..ab3622e --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/log @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +PROJECT_PATH=$( cd "$( dirname "$0" )/.." && pwd ) + +bash $PROJECT_PATH/cordova/cordova log diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/libs/cordova-2.0.0.jar b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/libs/cordova-2.0.0.jar new file mode 100644 index 0000000..e01123b Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/libs/cordova-2.0.0.jar differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/proguard-project.txt b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/proguard-project.txt new file mode 100644 index 0000000..f2fe155 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/project.properties b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/project.properties new file mode 100644 index 0000000..0840b4a --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-15 diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-hdpi/ic_launcher.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..96a442e Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-hdpi/ic_launcher.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-ldpi/ic_launcher.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-ldpi/ic_launcher.png new file mode 100644 index 0000000..9923872 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-ldpi/ic_launcher.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-mdpi/ic_launcher.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..359047d Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-mdpi/ic_launcher.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-xhdpi/ic_launcher.png b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..71c6d76 Binary files /dev/null and b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/drawable-xhdpi/ic_launcher.png differ diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/layout/main.xml b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/layout/main.xml new file mode 100644 index 0000000..991ac56 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/layout/main.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/values/strings.xml b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/values/strings.xml new file mode 100644 index 0000000..3c5860a --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/values/strings.xml @@ -0,0 +1,7 @@ + + + + Hello World, PhonegapSampleActivity! + Hello IR + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/xml/config.xml b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/xml/config.xml new file mode 100644 index 0000000..4682e93 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/res/xml/config.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/src/com/wikitude/phonegap/PhonegapSampleActivity.java b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/src/com/wikitude/phonegap/PhonegapSampleActivity.java new file mode 100644 index 0000000..435e9e4 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/src/com/wikitude/phonegap/PhonegapSampleActivity.java @@ -0,0 +1,17 @@ +package com.wikitude.phonegap; + +import org.apache.cordova.DroidGap; + +import android.os.Bundle; + + + +public class PhonegapSampleActivity extends DroidGap { + /** Called when the activity is first created. */ + @Override + public void onCreate( Bundle savedInstanceState ) { + super.onCreate( savedInstanceState ); + super.loadUrl( "file:///android_asset/www/index.html" ); + // super.loadUrl( "file:///android_asset/www/demo.html" ); + } +} \ No newline at end of file diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/src/com/wikitude/phonegap/WikitudePlugin.java b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/src/com/wikitude/phonegap/WikitudePlugin.java new file mode 100644 index 0000000..f88af1d --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/src/com/wikitude/phonegap/WikitudePlugin.java @@ -0,0 +1,417 @@ +package com.wikitude.phonegap; + +import java.io.IOException; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.app.Activity; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.view.ViewManager; + +import com.phonegap.api.Plugin; +import com.phonegap.api.PluginResult; +import com.wikitude.architect.ArchitectUrlListener; +import com.wikitude.architect.ArchitectView; +import com.wikitude.architect.ArchitectView.ArchitectConfig; + + + +/** + * Basic PhoneGap Wikitude ARchitect Plugin + * + * @author Wikitude GmbH + */ +public class WikitudePlugin extends Plugin implements ArchitectUrlListener { + + /** PhoneGap-root to Android-App-assets folder */ + private static final String LOCAL_ASSETS_PATH_ROOT = "assets/"; + + /* various JSON-Object keys*/ + private static final String JSON_KEY_APIKEY = "sdkKey"; + private static final String JSON_KEY_FILE_PATH = "filePath"; + + private static final String JSON_KEY_LOCATION_ALTITUDE = "alt"; + private static final String JSON_KEY_LOCATION_ACCURACY = "acc"; + private static final String JSON_KEY_LOCATION_LATITUDE = "lat"; + private static final String JSON_KEY_LOCATION_LONGITUDE = "lon"; + + /* static action strings */ + + /** + * opens architect-view (add to view stack) + */ + private static final String ACTION_OPEN = "open"; + + /** + * closes architect-view (remove view stack) + */ + private static final String ACTION_CLOSE = "close"; + + /** + * set visibility of architectView to visible (of present) + */ + private static final String ACTION_SHOW = "show"; + + /** + * set visibility of architectView to invisible (of present) + */ + private static final String ACTION_HIDE = "hide"; + + /** + * inject location information + */ + private static final String ACTION_SET_LOCATION = "setLocation"; + + /** + * callback for uri-invocations + */ + private static final String ACTION_ON_URLINVOKE = "onUrlInvoke"; + + /** + * life-cycle notification for resume + */ + private static final String ACTION_ON_RESUME = "onResume"; + + /** + * life-cycle notification for pause + */ + private static final String ACTION_ON_PAUSE = "onPause"; + + /** + * check if view is on view-stack (no matter if visible or not) + */ + private static final String ACTION_STATE_ISOPEN = "isOpen"; + + /** + * opens architect-view (add to view stack) + */ + private static final String ACTION_IS_DEVICE_SUPPORTED = "isDeviceSupported"; + + /** + * check if view is on view-stack (no matter if visible or not) + */ + private static final String ACTION_CALL_JAVASCRIPT = "callJavascript"; + + /** + * the Wikitude ARchitectview + */ + private ArchitectView architectView; + + /** + * callback-Id of url-invocation method + */ + private String urlInvokeCallbackId = null; + + /** + * callback-id of "open"-action method + */ + private String openCallbackId = null; + + @Override + public PluginResult execute( final String action, final JSONArray args, final String callbackId ) { + + /* hide architect-view -> destroy and remove from activity */ + if ( WikitudePlugin.ACTION_CLOSE.equals( action ) ) { + if ( this.architectView != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + removeArchitectView(); + } + } ); + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } + else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* return success only if view is opened (no matter if visible or not) */ + if ( WikitudePlugin.ACTION_STATE_ISOPEN.equals( action ) ) { + if ( this.architectView != null ) { + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* return success only if view is opened (no matter if visible or not) */ + if ( WikitudePlugin.ACTION_IS_DEVICE_SUPPORTED.equals( action ) ) { + if ( ArchitectView.isDeviceSupported( this.cordova.getActivity() ) ) { + return new PluginResult( PluginResult.Status.OK, action + ": this device is ARchitect-ready" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": Sorry, this device is NOT ARchitect-ready" ); + } + } + + + + /* life-cycle's RESUME */ + if ( WikitudePlugin.ACTION_ON_RESUME.equals( action ) ) { + + if ( this.architectView != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + WikitudePlugin.this.architectView.onResume(); + } + } ); + + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + + /* life-cycle's PAUSE */ + if ( WikitudePlugin.ACTION_ON_PAUSE.equals( action ) ) { + if ( architectView != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + WikitudePlugin.this.architectView.onPause(); + } + } ); + + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + + /* set visibility to "visible", return error if view is null */ + if ( WikitudePlugin.ACTION_SHOW.equals( action ) ) { + + if ( this.architectView != null ) { + this.architectView.setVisibility( View.VISIBLE ); + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* set visibility to "invisible", return error if view is null */ + if ( WikitudePlugin.ACTION_HIDE.equals( action ) ) { + + if ( this.architectView != null ) { + this.architectView.setVisibility( View.INVISIBLE ); + return new PluginResult( PluginResult.Status.OK, action + ": architectView is present" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectView is not present" ); + } + } + + /* define call-back for url-invocations */ + if ( WikitudePlugin.ACTION_ON_URLINVOKE.equals( action ) ) { + this.urlInvokeCallbackId = callbackId; + PluginResult result = new PluginResult( PluginResult.Status.NO_RESULT, action + ": registered callback" ); + result.setKeepCallback( true ); + return result; + } + + /* location update */ + if ( WikitudePlugin.ACTION_SET_LOCATION.equals( action ) ) { + if ( this.architectView != null ) { + try { + String arrStr = args.getString( 0 ); + JSONObject arr = new JSONObject( arrStr ); + final double lat = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_LATITUDE ); + final double lon = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_LONGITUDE ); + Object altObj = arr.get( WikitudePlugin.JSON_KEY_LOCATION_ALTITUDE ); + float alt = Float.MIN_VALUE; + + if ( altObj != null && altObj instanceof Double ) { + alt = ((Double)altObj).floatValue(); + } + + final float altitude = alt; + + final Double acc = arr.getDouble( WikitudePlugin.JSON_KEY_LOCATION_ACCURACY ); + if ( this.cordova != null && this.cordova.getActivity() != null ) { + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + if ( acc != null ) { + WikitudePlugin.this.architectView.setLocation( lat, lon, altitude, acc.floatValue() ); + } else { + WikitudePlugin.this.architectView.setLocation( lat, lon, altitude ); + } + } + } ); + } + + } catch ( Exception e ) { + return new PluginResult( PluginResult.Status.ERROR, action + ": exception thrown, " + e != null ? e.getMessage() : "(exception is NULL)" ); + } + return new PluginResult( PluginResult.Status.OK, action + ": updated location" ); + } + + /* return error if there is no architect-view active*/ + return new PluginResult( PluginResult.Status.ERROR, action + ": architectview is not active" ); + } + + if ( WikitudePlugin.ACTION_CALL_JAVASCRIPT.equals( action ) ) { + if ( this.architectView != null ) { + String logMsg = null; + try { + final String callJS = args.getString( 0 ); + logMsg = callJS; + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + WikitudePlugin.this.architectView.callJavascript( callJS ); + } + } ); + + } catch ( JSONException je ) { + return new PluginResult( PluginResult.Status.ERROR, action + ": exception thrown, " + je != null ? je.getMessage() : "(exception is NULL)" ); + } + return new PluginResult( PluginResult.Status.OK, action + ": called js, '" + logMsg + "'" ); + } else { + return new PluginResult( PluginResult.Status.ERROR, action + ": architectview is not active" ); + } + } + + + /* initial set-up, show ArchitectView full-screen in current screen/activity */ + if ( WikitudePlugin.ACTION_OPEN.equals( action ) ) { + this.openCallbackId = callbackId; + PluginResult result = null; + String arrStr = null; + + try { + arrStr = args.getString( 0 ); + + // arrStr = arrStr.substring( 1, arrStr.length() - 1 ); + + JSONObject arr = new JSONObject( arrStr ); + + final String apiKey = arr.getString( WikitudePlugin.JSON_KEY_APIKEY ); + final String filePath = arr.getString( WikitudePlugin.JSON_KEY_FILE_PATH ); + + this.cordova.getActivity().runOnUiThread( new Runnable() { + + @Override + public void run() { + try { + WikitudePlugin.this.addArchitectView( apiKey, filePath ); + + /* call success method once architectView was added successfully */ + if ( WikitudePlugin.this.openCallbackId != null ) { + PluginResult result = new PluginResult( PluginResult.Status.OK ); + result.setKeepCallback( false ); + WikitudePlugin.this.success( result, WikitudePlugin.this.openCallbackId ); + } + } catch ( Exception e ) { + /* in case "addArchitectView" threw an exception -> notify callback method asynchronously */ + WikitudePlugin.this.error( e != null ? e.getMessage() : "Exception is 'null'", WikitudePlugin.this.openCallbackId ); + } + } + } ); + + } catch ( Exception e ) { + result = new PluginResult( PluginResult.Status.ERROR, action + ": exception thown, " + e != null ? e.getMessage() : "(exception is NULL)" ); + result.setKeepCallback( false ); + return result; + } + + /* adding architect-view is done in separate thread, ensure to setKeepCallback so one can call success-method properly later on */ + result = new PluginResult( PluginResult.Status.NO_RESULT, action + ": no result required, just registered callback-method" ); + result.setKeepCallback( true ); + + return result; + } + + /* fall-back return value */ + return new PluginResult( PluginResult.Status.ERROR, "no such action: " + action ); + } + + /** + * called when url was invoked in architectView (by e.g. calling document.location = "myprotocoll://foo"; + * @param url the invoked url (e.g. "myprotocoll://foo") + * @return true if call was handled properly + */ + @Override + public boolean urlWasInvoked( String url ) { + + /* call callback-method if set*/ + if ( this.urlInvokeCallbackId != null ) { + try { + /* pass called url as String to callback-method */ + PluginResult res = new PluginResult( PluginResult.Status.OK, url ); + res.setKeepCallback( true ); + this.success( res, this.urlInvokeCallbackId ); + return true; + } catch ( Exception e ) { + this.error( "invalid url invoked: " + url, this.urlInvokeCallbackId ); + } + } + return false; + } + + /** + * hides/removes ARchitect-View completely + * @return true if successful, false otherwise + */ + private boolean removeArchitectView() { + if ( this.architectView != null ) { + /* fake life-cycle calls, because activity is already up and running */ + this.architectView.onPause(); + this.architectView.onDestroy(); + this.architectView.setVisibility( View.INVISIBLE ); + ((ViewManager)this.architectView.getParent()).removeView( this.architectView ); + this.architectView = null; + return true; + } + return false; + } + + /** + * Architect-Configuration required for proper set-up + * @param apiKey + * @return + */ + protected ArchitectConfig getArchitectConfig( final String apiKey ) { + /* no special set-up required in default Wikitude-Plugin, further things required in advanced usage (e.g. Vuforia Image Recognition) */ + return new ArchitectConfig( apiKey ); + } + + /** + * add architectView to current screen + * @param apiKey developers's api key to use (hides watermarking/intro-animation if it matches your package-name) + * @param filePath the url (starting with http:// for online use; starting with LOCAL_ASSETS_PATH_ROOT if oyu want to load assets within your app-assets folder) + * @throws IOException might be thrown from ARchitect-SDK + */ + @SuppressWarnings("deprecation") + private void addArchitectView( final String apiKey, String filePath ) throws IOException { + if ( this.architectView == null ) { + this.architectView = new ArchitectView( (Activity)this.ctx.getContext() ); + + /* add content view and fake initial life-cycle */ + ((Activity)this.ctx.getContext()).addContentView( this.architectView, new ViewGroup.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT ) ); + + /* fake life-cycle calls, because activity is already up and running */ + this.architectView.onCreate( getArchitectConfig( apiKey ) ); + this.architectView.onPostCreate(); + + /* register self as url listener to fwd these native calls to PhoneGap */ + this.architectView.registerUrlListener( WikitudePlugin.this ); + + /* load asset from local directory if prefix is used */ + if ( filePath.startsWith( WikitudePlugin.LOCAL_ASSETS_PATH_ROOT ) ) { + filePath = filePath.substring( WikitudePlugin.LOCAL_ASSETS_PATH_ROOT.length() ); + } + this.architectView.load( filePath ); + + /* also a fake-life-cycle call (the last one before it is really shown in UI */ + this.architectView.onResume(); + } + } +} diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/src/com/wikitude/phonegap/WikitudePluginExtended.java b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/src/com/wikitude/phonegap/WikitudePluginExtended.java new file mode 100644 index 0000000..fb62e58 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/src/com/wikitude/phonegap/WikitudePluginExtended.java @@ -0,0 +1,89 @@ +package com.wikitude.phonegap; + +import android.app.Activity; + +import com.qualcomm.QCAR.QCAR; +import com.wikitude.architect.ArchitectView.ArchitectConfig; +import com.wikitude.architect.VuforiaInterface; + + + +/** + * Advanced Wikitude ARchitect Plugin (= Basic Plugin + Vuforia Image Recognition feature-set) + * + * You must add "wikitudesdk.jar" and "QCAR.lib" to your libs folder and build-path and have "libQCAR.so" in project's "libs/armeabi/" directory + * + * Also add "" + * (replace Basic-plugin entry if necessary) + * + * in config.xml to enable this plug-in in your project; Ensure your architectSDK key is Vuforia-ready + * + * Note: + * This plug-in is written under Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0.html + * + * @version 1.0.0 + * @author Wikitude GmbH; www.wikitude.com + */ +public class WikitudePluginExtended extends WikitudePlugin { + + + static { + System.loadLibrary( "QCAR" ); + } + + /** + * Architect-Configuration required for proper set-up + * @param apiKey + * @return + */ + @Override + protected ArchitectConfig getArchitectConfig( final String apiKey ) { + final ArchitectConfig config = super.getArchitectConfig( apiKey ); + + /* required for Vuforia */ + config.setVuforiaInterface( new VuforiaServiceImplementation() ); + return config; + } + + /* required for Vuforia */ + private class VuforiaServiceImplementation implements VuforiaInterface { + + @Override + public void deInit() { + QCAR.deinit(); + } + + @Override + public int init() { + return QCAR.init(); + } + + @Override + public void onPause() { + QCAR.onPause(); + } + + @Override + public void onResume() { + QCAR.onResume(); + } + + @Override + public void onSurfaceChanged( final int arg0, final int arg1 ) { + QCAR.onSurfaceChanged( arg0, arg1 ); + } + + @Override + public void onSurfaceCreated() { + QCAR.onSurfaceCreated(); + } + + @Override + public void setInitParameters( final Activity activity, final int nFlags ) { + QCAR.setInitParameters( activity, nFlags ); + } + + } + +} diff --git a/Android/AugmentedReality-Wikitude/SampleProjects/Extended/README.md b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/README.md new file mode 100644 index 0000000..be5b0d5 --- /dev/null +++ b/Android/AugmentedReality-Wikitude/SampleProjects/Extended/README.md @@ -0,0 +1,22 @@ + +# Hello Image Recognition Android + +This document describes all necessary steps to get the sample running. +Once set up, the app augments the [Wikitude Logo](http://www.flickr.com/photos/wikitude/5571196416/) in your camera. + + +####Prerequisites: +* You need to [register as developer at Wikitude](http://developer.wikitude.com) and downloaded the SDK, two files from the SDK's Android-folder are required, as described below. + +* Download the Vuforia Framework from [Qualcomm](https://ar.qualcomm.at/sdk/android) (You need to register yourself as a Qualcomm developer) + + +# SETUP + + +* [Import HelloImageRecognition-project in Eclipse as Android-Project](https://www.google.com/webhp?sourceid=chrome-instant&ie=UTF-8&ion=1#hl=de&output=search&sclient=psy-ab&q=import%20android%20project%20into%20eclipse&oq=&gs_l=&pbx=1&fp=531bf0abdc9ea0e7&ion=1&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.&biw=1030&bih=550) +* Copy `wikitudesdk.jar` from the Android [WikitudeSDK](http://developer.wikitude.com) to project's `libs`-folder + +* Copy `libExtensionVuforia.so` from the Android [WikitudeSDK](http://developer.wikitude.com) to `libs/armeabi`-folder (create subfolder if necessary) + +* From [Qualcomm's Vuforia SDK](https://ar.qualcomm.at/sdk/android): Copy `QCAR.jar` to your projects `libs`-folder and add it to your project's build. Also copy Vuforia's `libQCAR.so` to your `libs/armeabi`-folder \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/Documentation/Documentation.md b/iOS/AugmentedReality-Wikitude/Documentation/Documentation.md new file mode 100644 index 0000000..6e4b202 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/Documentation/Documentation.md @@ -0,0 +1,116 @@ +## Wikitude PhoneGap Plugin Documentation +by ``` Wikitude GmbH ``` + + +### DESCRIPTION +*** + +This document describes all available PhoneGap bindings which exists in the Wikitude PhoneGap Plugin. + + +#### Getting information about the device + +###### isDeviceSupported +Call ``` isDeviceSupported ``` to determinate if the current device is capable of launching ARchitect Worlds. + + @param onSuccessCallback - A callback which gets called if the current device supports launching ARchitect Worlds + @param onErrorCallback - An callback which gets called if the current device does not fulfil all needs to lauch ARchitect Worlds + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(deviceSupportedCallback, deviceNotSupportedCallback, "WikitudePlugin", "isDeviceSupported", [""]); + + +#### Managing the ARchitectView + + +###### open +Call open to add the ARchitectView to your applications view hierarchy and loads the specified ARchitect World. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - a dictionary containing two pairs: + @pair apiKey : The Wikitude SDK Key provided to you after you purchased the Wikitude SDK or an empty string if you're using a trial version + @pair filePath : A filepath to a local bundle resource or to a file on e.g. your dropbox + + cordova.exec(architectWorldLaunchedCallback, architectWorldFailedLaunchingCallback, "WikitudePlugin", "open", [{ apiKey: myApiKey, filePath: worldPath}]); + +###### close +This call will remove the ARchitectView from the view hierarchy and also stops all ongoing Wikitude updates. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "close", [""]); + +###### show +This call hides the ARchitectView, but keeps it alive in memory. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "hide", [""]); + +###### hide +This call will show the ARchitectView again if it was hidden with the ``` hide ``` call. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "show", [""]); + + + +#### Interacting with the ARchitectView + +###### callJavaScript +This function will evaluate the passed JavaScript in the current ARchitect World context. + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - A JavaScript array with a JavaScript string at first position + + cordova.exec(onWikitudeOK, onWikitudeError, "WikitudePlugin", "callJavascript", [js]); + +###### onUrlInvoke +This function will set an callback which gets called if you call ``` document.location = architectsdk://aRequestWithParameters?id=5&name=Poi5 ```. + + @param onSuccessCallback - A callback which gets called every time you call ` architectsdk:// ` + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - No options + + cordova.exec(onUrlInvokeCallback, onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]); + +###### setLocation +This function allows you to set a location for your current ARchitectView + + + @param onSuccessCallback - A success callback + @param onErrorCallback - An error callback + @param Plugin name - The name of the plugin you want to call a function + @param Plugin function - The name of the function you want to call on the plugin + @param options - A dictionary containing the new latitude, longitude, altitude, accuracy + @pair lat : The new latitude + @pair lon : The new longitude + @pair alt : The new altitude + @pair acc : The accuracy of the new locations + + cordova.exec(onUrlInvokeCallback, onWikitudeError, "WikitudePlugin", "setLocation", [""]); + + diff --git a/iOS/AugmentedReality-Wikitude/Plugin/README.md b/iOS/AugmentedReality-Wikitude/Plugin/README.md new file mode 100644 index 0000000..161b7c8 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/Plugin/README.md @@ -0,0 +1,111 @@ +# Augmented Reality - Wikitude SDK Plugin +by Wikitude GmbH - [www.wikitude.com](http://www.wikitude.com) + +Interested in advanced usage of the plugin and need assistance? +[Register as a Wikitude developer](http://developer.wikitude.com) and get support in our forum. + +For further questions visit us on www.wikitude.com or contact us via `phonegap wikitude.com` + +#### Important: This plugin runs on latest [PhoneGap 2.x](http://docs.phonegap.com/en/2.0.0/guide_getting-started_android_index.md.html#Getting%20Started%20with%20Android) only + + +## DESCRIPTION + + +The Wikitude PhoneGap Plugin enables web developers to embed an Augmented Reality view into their PhoneGap project. One can create a fully featured app with advanced Augmented Reality features, including Image Recognition, purely using HTML, CSS and Javascript. + +###The Wikitude PhoneGap Plugin + +* Available for iOS and Android +* Simple and seamless native PhoneGap integration +* Fully customizable Augmented Realty view +* Includes the full feature set of the Wikitude SDK +* AR content is purely written in HTML and JavaScript + +![image](http://www.wikitude.com/wp-content/uploads/2012/09/Plugin_Phonegap.png) + +###The Augmented Reality View +From a technical point of view the SDK adds a UI component, similar to a web view. In contrast to a standard web view this AR view can render Augmented Reality content. + +Note: Content developed for this AR View is written in JavaScript and HTML. The .html and .js files for this view are different from the PhoneGap .js and .html files. The AR engine working in the background is called ARchitect Engine and is powering the SDK. + +###Further developer resources +* [Full documentation and additional tutorials](http://forum.wikitude.com/documentation) +* [Developer Forum](http://forum.wikitude.com/home) +* [Wikitude SDK Download](http://forum.wikitude.com/download) +* [Google+ Page for News](https://plus.google.com/u/0/103004921345651739447/posts) +* [Developer Newsletter](http://www.wikitude.com/developer/newsletter) + + + +## SETUP + +* Create a new PhoneGap project with the command line tool provided by PhoneGap. +* After your created the project, switch to Finder and copy the WikitudePlugin.h and .m file into the Plugins folder of your PhoneGap project. Afterwards, you have to add the files to the Plugins Group in your Xcode project. +* Add a new entry with key ``` WikitudePlugin ``` and value ``` WTWikitudePlugin ``` to ``` Plugins ``` in ``` Cordova.plist ``` +* Copy the Wikitude SDK for iOS (which you can downloaded from [our website](http://www.wikitude.com/developer/sdk)) into a folder like ```[ProjectFolder/"AppName"/WikitudeSDK] ```in your Xcode project. Make sure that you not only copy the files into the correct destination but that you also add the files to the Xcode project. + + * if you want to use Image Recognition within your App, you need to copy the Vuforia SDK folder into a folder like ```[ProjectFolder/"AppName"/Vuforia]```. Also dont forget to add the files to your Xcode project. You can download the Vuforia SDK from [Qualcomm](https://ar.qualcomm.at/sdk/ios). + + +* Add the Following Frameworks to your project: + + * CoreMotion.framework + + * CoreVideo.framework + + * libz.dylib + + * libsqlite3.dylib + + * OpenGLES.framework + + * Security.framework + +* You need to change one linker flag in order to run your App with the WikitudeSDK. Go to your project settings and change the other linker flag ```'-all_load'``` to ```'-force_load $(BUILT_PRODUCTS_DIR)/libCordova.a'```. After that, please add the following linker flag: ```-lstdc++```. + +* If you want to test your application on the iPhone Simulator, you'll need to change an additional Library Serach Path in your Xcode project settings. + + Change ```"$(SRCROOT)/HelloWorld/WikitudeSDK/SDK/lib/Release-iphoneos" ``` + To ```"$(SRCROOT)/HelloWorld/WikitudeSDK/SDK/lib/Release$(EFFECTIVE_PLATFORM_NAME)"``` + + And delete ```"$(SRCROOT)/HelloWorld/WikitudeSDK/SDK/lib/Release-iphonesimulator"``` + + +* The last step is to edit the whitelist entries. Open the Cordova.plist and add a new entry to the 'ExternalHosts' Array: * (single Asterisk) + + +## JAVASCRIPT INTERFACE + +Its simple to use the Wikitude Plugin within your PhoneGap application. + +We wrapped all ``` cordova.exec ``` calls into a separate JavaScript wrapper which handles location updates and some more functionality behind the scenes. + +You will mainly work with the ``` WikitudePlugin ``` where all you have to do is to call ```Wikitude.isDeviceReady(successCallback, errorCallback)``` and in your successCallback, you can call ```WikitudePlugin.loadARchitectWorld(successCallback, errorCallback, "path/to/your/world")```. + +If you want to communicate directly via the ```cordova.exec``` JavaScript calls, have a look at the ```Documentation``` folder which includes more information about that. + + +## Getting STARTED + +To get started, we prepared two sample projects. You can read through this samples to understand how to use the JavaScript wrapper and how you add your ARchitect World into the project. There is also a ReadMe for both projects which explain you what you have to do to get them running. + +Note: +If you have purchased a Wikitude SDK license, you can enter you SDK Key in the ```WikitudePlugin.js``` file at line 9. + + +## LICENSE + + Copyright 2012 [Wikitude GmbH ](http://www.wikitude.com) + + Licensed 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. \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/Plugin/WTWikitudePlugin.h b/iOS/AugmentedReality-Wikitude/Plugin/WTWikitudePlugin.h new file mode 100644 index 0000000..0a71316 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/Plugin/WTWikitudePlugin.h @@ -0,0 +1,14 @@ +// +// WTWikitudeSDK.h +// HelloWorld +// +// Created by Andreas Schacherbauer on 8/24/12. +// +// + + +#import + +@interface WTWikitudePlugin : CDVPlugin + +@end diff --git a/iOS/AugmentedReality-Wikitude/Plugin/WTWikitudePlugin.m b/iOS/AugmentedReality-Wikitude/Plugin/WTWikitudePlugin.m new file mode 100644 index 0000000..3e54f35 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/Plugin/WTWikitudePlugin.m @@ -0,0 +1,402 @@ +// +// WTWikitudeSDK.m +// HelloWorld +// +// Created by Andreas Schacherbauer on 8/24/12. +// +// + +#import "WTWikitudePlugin.h" + +// Wikitude SDK +#import "WTArchitectView.h" + + + + +@interface WTWikitudePlugin () + +@property (nonatomic, strong) WTArchitectView *architectView; + +@property (nonatomic, strong) NSString *currentARchitectViewCallbackID; +@property (nonatomic, strong) NSString *currentPlugInErrorCallback; + +@property (nonatomic, assign) BOOL isUsingInjectedLocation; + +@end + + +@implementation WTWikitudePlugin +@synthesize architectView=_architectView; + + +#pragma mark - View Lifecycle +/* View Lifecycle */ +- (void)isDeviceSupported:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + BOOL isDeviceSupported = [WTArchitectView isDeviceSupported]; + + if (isDeviceSupported) { + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:isDeviceSupported]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + } else { + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:isDeviceSupported]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + + +- (void)open:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { +// NSString* echo = [arguments objectAtIndex:1]; + + + BOOL success = [WTArchitectView isDeviceSupported]; + if ( success ) { + + NSString *sdkKey = [options objectForKey:@"apiKey"]; + NSString *architectWorldFilePath = [options objectForKey:@"filePath"]; + + // First, lets check if we need to init a new sdk view + if ( !_architectView ) { + self.architectView = [[WTArchitectView alloc] initWithFrame:self.viewController.view.bounds]; + self.architectView.delegate = self; + [self.architectView initializeWithKey:sdkKey motionManager:nil]; + } + + // then add the view in its own navController to the ui. we need a own navController to have a backButton which can be used to dismiss the view + UIViewController *viewController = [[UIViewController alloc] init]; + viewController.view = self.architectView; + + UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; + navController.navigationBar.tintColor = [UIColor blackColor]; + navController.navigationBar.topItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissARchitectView)]; + [self.viewController presentViewController:navController animated:NO completion:^{ + // completion code + }]; + + + + // and finaly load the architect world, specified in the open function in js + if (architectWorldFilePath) { + + NSString *worldName = [architectWorldFilePath lastPathComponent]; + worldName = [worldName stringByDeletingPathExtension]; + NSString *worldNameExtension = [architectWorldFilePath pathExtension]; + + NSString *architectWorldDirectoryPath = [architectWorldFilePath stringByDeletingLastPathComponent]; + + NSString *loadablePath = [[NSBundle mainBundle] pathForResource:worldName ofType:worldNameExtension inDirectory:architectWorldDirectoryPath]; + [self.architectView loadArchitectWorldFromUrl:loadablePath]; + } + } + + // start the sdk view updates + [self.architectView start]; + + + if ( success ) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } else { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)close:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { +// NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + + [self.architectView stop]; +// [self.architectView removeFromSuperview]; + } + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)show:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { +// NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + self.architectView.hidden = NO; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)hide:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + self.architectView.hidden = YES; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)onResume:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + [self.architectView start]; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)onPause:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + [self.architectView stop]; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +#pragma mark - Location Handling + +- (void)setLocation:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + + float latitude = [[options objectForKey:@"lat"] floatValue]; + float longitude = [[options objectForKey:@"lon"] floatValue]; + float altitude = [[options objectForKey:@"alt"] floatValue]; + float accuracy = [[options objectForKey:@"acc"] floatValue]; + + if (!self.isUsingInjectedLocation) { + [self.architectView setUseInjectedLocation:YES]; + self.isUsingInjectedLocation = YES; + } + + [self.architectView injectLocationWithLatitude:latitude longitude:longitude altitude:altitude accuracy:accuracy]; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + + +#pragma mark - Javascript + +- (void)callJavascript:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + + @try { + + if (arguments.count >= 1) { + + NSMutableString *javascriptToCall = [[arguments objectAtIndex:1] mutableCopy]; + for (NSUInteger i = 2; i < arguments.count; i++) { + [javascriptToCall appendString:[arguments objectAtIndex:i]]; + } + + if (self.architectView) { + [self.architectView callJavaScript:javascriptToCall]; + } + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + }else + { + // return error no javascript to call found + } + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + + +- (void)onUrlInvoke:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + + + self.currentARchitectViewCallbackID = callbackId; + self.currentPlugInErrorCallback = callbackId; + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; + [pluginResult setKeepCallbackAsBool:YES]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +#pragma mark - WTArchitectView Delegate +- (void)urlWasInvoked:(NSString *)url +{ + + CDVPluginResult *pluginResult = nil; + NSString *javaScriptResult = nil; + + + if (url && self.currentARchitectViewCallbackID) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:url]; + [pluginResult setKeepCallbackAsBool:YES]; + javaScriptResult = [pluginResult toSuccessCallbackString:self.currentARchitectViewCallbackID]; + + + }else + { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; + javaScriptResult = [pluginResult toSuccessCallbackString:self.currentPlugInErrorCallback]; + } + + [self writeJavascript:javaScriptResult]; +} + +- (void)dismissARchitectView +{ + [self.viewController dismissModalViewControllerAnimated:NO]; + [self.architectView stop]; +} + +@end diff --git a/iOS/AugmentedReality-Wikitude/Plugin/WikitudePlugin.js b/iOS/AugmentedReality-Wikitude/Plugin/WikitudePlugin.js new file mode 100644 index 0000000..bd09eb2 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/Plugin/WikitudePlugin.js @@ -0,0 +1,383 @@ +var WikitudePlugin = { + + /** + * + * This is the SDK Key, provided to you after you purchased the Wikitude SDK from http://www.wikitude.com/developer/sdk + * If you're having a trial version, leave this string empty + * + */ + mySDKKey : "ENTER-YOUR-KEY-HERE", + + /** true if architectview is open */ + isOpened : false, + + /** + * + * called when user pressed back-button on Android device + * + */ + backButtonCallback : null, + + /** + * + * Change the value of this variable to modify the location update rate + * + */ + locationUpdateRate : 3000, + + /** + * + * This variable represents if the current device is capable of running the Wikitude SDK + * + */ + isDeviceSupported : false, + + /** + * + * This watchID is used to shedule location updates + * + */ + watchID : null, + + /** + * + * Callbacks to get device information if ARchitect Worlds can be launched + * + */ + onDeviceSupportedCallback : null, + onDeviceNotSupportedCallback : null, + + /** + * + * Callbacks to get notified if the ARchitect World finished launching or if something went wrong during the World launch + * + */ + onARchitectWorldLaunchedCallback : null, + onARchitectWorldFailedLaunchingCallback : null, + + /** + * + * This function gets called if PhoneGap reports that it has finished loading successfully. + * + */ + isDeviceSupported: function(successCallback, errorCallback) + { + + WikitudePlugin.onDeviceSupportedCallback = successCallback; + WikitudePlugin.onDeviceNotSupportedCallback = errorCallback; + + + // PhoneGap is running, so the first thing we do is to check if the current device is capable of running the Wikitude Plugin + cordova.exec(WikitudePlugin.deviceIsARchitectReady, WikitudePlugin.deviceIsNotARchitectReady, "WikitudePlugin", "isDeviceSupported", [""]); + + }, + + /** + * + * Declare what should happen when user pressed back-button while architect-view is opened. + * If not declared/called or null: ARchitect-View is closed + * + */ + onPressedBackButton : function(callback) + { + WikitudePlugin.backButtonCallback = callback; + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is able to start the Wikitude SDK + * + */ + deviceIsARchitectReady : function() + { + // We keep track of the device status + WikitudePlugin.isDeviceSupported = true; + + + if(WikitudePlugin.onDeviceSupportedCallback) + { + WikitudePlugin.onDeviceSupportedCallback(); + } + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is not able of starting the Wikitude SDK. + * + */ + deviceIsNotARchitectReady : function() + { + WikitudePlugin.isDeviceSupported = false; + + // In this case we notify the user that his device is not supported by the Wikitude SDK + if(WikitudePlugin.onDeviceNotSupportedCallback) + { + WikitudePlugin.onDeviceNotSupportedCallback(); + } + }, + + /* + * ============================================================================================================================= + * + * PUBLIC API + * + * ============================================================================================================================= + */ + + /* Managing ARchitect world loading */ + + /** + * + * Call this function if you want to load an ARchitect World + * + * @param {String} worldPath The path to an ARchitect world ether on the device or on e.g. your dropbox + * + */ + loadARchitectWorld : function(worldPath) + { + + // before we actually call load, we check again if the device is able to open the world + if(WikitudePlugin.isDeviceSupported) + { + + // the 'open' function of the Wikitude Plugin requires a option dictionary with two keys: + // @param {Object} options (required) + // @param {String} options.sdkKey License key for the Wikitude SDK + // @param {String} options.filePath The path to a local ARchitect world or to a ARchitect world on a server or your dropbox + + cordova.exec(WikitudePlugin.worldLaunched, WikitudePlugin.worldFailedLaunching, "WikitudePlugin", "open", [{ sdkKey: WikitudePlugin.mySDKKey, filePath: worldPath}]); + + + // We add an event listener on the resume and pause event of the application lifecycle + document.addEventListener("resume", WikitudePlugin.onResume, false); + document.addEventListener("pause", WikitudePlugin.onPause, false); + + WikitudePlugin.isOpened = true; + document.addEventListener("backbutton", WikitudePlugin.onBackButton, false); + + // After we started loading the world, we start location updates + WikitudePlugin.startLocationUpdates(); + + }else + { + // if the device is not able to start the Wikitude SDK, we notify the user again + WikitudePlugin.deviceNotARchitectReady(); + } + }, + + /* Managing the Wikitude SDK Lifecycle */ + + /** + * + * Use this function to stop the Wikitude SDK and to remove the ARchitectView from the screen + * + */ + close : function() + { + document.removeEventListener("pause", WikitudePlugin.onPause, false); + document.removeEventListener("resume", WikitudePlugin.onResume, false); + + WikitudePlugin.stopLocationUpdates(); + + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]); + WikitudePlugin.isOpened = false; + }, + + /** + * + * Use this function to only hide the Wikitude SDK. All location and rendering updates are still active + * + */ + hide : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "hide", [""]); + }, + + /** + * + * Use this function to show the Wikitude SDK if it was hidden before + * + */ + show : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "show", [""]); + }, + + /* Interacting with the Wikitude SDK */ + + /** + * + * Use this function to call javascript which will be executed in the context of your ARchitect World + * + * + * @param js The JavaScript that gets evaluated in context of the ARchitect World + * + */ + callJavaScript : function(js) + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "callJavascript", [js]); + }, + + /** + * + * Use this function to set a callback which will be invoked when the ARchitect World calls for example + * document.location = "architectsdk://opendetailpage?id=9"; + * + * + * @param onUrlInvokeCallback A function which gets called when the ARchitect World invokes a call to "document.location = architectsdk://" + */ + setOnUrlInvokeCallback : function(onUrlInvokeCallback) + { + cordova.exec(onUrlInvokeCallback, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]); + }, + + + /* + * ============================================================================================================================= + * + * Callbacks of public functions + * + * ============================================================================================================================= + */ + + /** + * + * Use this callback to get notified if the world loaded successfully + * + */ + worldLaunched : function() + { + if(WikitudePlugin.onARchitectWorldLaunchedCallback) + { + WikitudePlugin.onARchitectWorldLaunchedCallback(); + } + }, + + /** + * + * Use this callback to get notified if the Wikitude SDK wasn't able to load the ARchitect World + * + */ + worldFailedLaunching : function(err) + { + if(WikitudePlugin.onARchitectWorldFailedLaunchingCallback) + { + WikitudePlugin.onARchitectWorldFailedLaunchingCallback(err); + } + }, + + /* Lifecycle updates */ + + /** + * + * This function actually starts the PhoneGap location updates + * + */ + startLocationUpdates : function() + { + + WikitudePlugin.watchID = navigator.geolocation.watchPosition(WikitudePlugin.onReceivedLocation, WikitudePlugin.onWikitudeError, { frequency: WikitudePlugin.locationUpdateRate }); + }, + + /** + * + * This callback gets called everytime the location did update + * + */ + onReceivedLocation : function(position) + { + + // Every time that PhoneGap did received a location update, we pass the location into the Wikitude SDK + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "setLocation", [{ lat: position.coords.latitude, lon: position.coords.longitude, alt: position.coords.altitude, acc: position.coords.accuracy}]); + }, + + /** + * + * Use this function to stop location updates + * + */ + stopLocationUpdates : function() + { + + // We clear the location update watch which was responsible for updating the location in a specific time interval + navigator.geolocation.clearWatch(WikitudePlugin.watchID); + WikitudePlugin.watchID = null; + }, + + /** + * + * This function gets called every time the application did become active. + * + */ + onResume : function() + { + + // Call the Wikitude SDK that the application did become active again + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onResume", [""]); + + // And start continuing updating the user location + WikitudePlugin.startLocationUpdates(); + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onPause : function() + { + + // Call the Wikitude SDK that the application did resign active + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onPause", [""]); + + // And stop all ongoing location updates + WikitudePlugin.stopLocationUpdates(); + }, + + /** + * + * Android specific! + * This function gets called if the user presses the back button. + * You may define your own implementation by using WikitudePlugin.onPressedBackButton(method) + * + */ + onBackButton : function() + { + if (WikitudePlugin.isOpened) { + if (WikitudePlugin.backButtonCallback==null) { + WikitudePlugin.close(); + document.removeEventListener("backbutton", WikitudePlugin.onBackButton, false); + } else { + WikitudePlugin.backButtonCallback(); + } + } + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeOK : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeError : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + report: function(id) + { + console.log("app report: " + id); + } +}; diff --git a/iOS/AugmentedReality-Wikitude/README.md b/iOS/AugmentedReality-Wikitude/README.md deleted file mode 100644 index 92cf6d7..0000000 --- a/iOS/AugmentedReality-Wikitude/README.md +++ /dev/null @@ -1 +0,0 @@ -# Wikitude SDK PhoneGap Plugin - Coming very soon! diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/TemplateIcon.icns b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000..47f85e5 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/TemplateIcon.icns differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/TemplateInfo.plist b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/TemplateInfo.plist new file mode 100644 index 0000000..6e6b271 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/TemplateInfo.plist @@ -0,0 +1,28 @@ + + + + + + Description + This template provides a starting point for a Cordova based application. Just modify the www folder contents with your HTML, CSS and Javascript. + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/project.pbxproj b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/project.pbxproj new file mode 100644 index 0000000..a0fab64 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/project.pbxproj @@ -0,0 +1,732 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 1F766FE113BBADB100FB74C0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1F766FDC13BBADB100FB74C0 /* Localizable.strings */; }; + 1F766FE213BBADB100FB74C0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1F766FDF13BBADB100FB74C0 /* Localizable.strings */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 301BF552109A68D80062928A /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF535109A57CC0062928A /* libCordova.a */; }; + 301BF570109A69640062928A /* www in Resources */ = {isa = PBXBuildFile; fileRef = 301BF56E109A69640062928A /* www */; }; + 301BF5B5109A6A2B0062928A /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5B4109A6A2B0062928A /* AddressBook.framework */; }; + 301BF5B7109A6A2B0062928A /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5B6109A6A2B0062928A /* AddressBookUI.framework */; }; + 301BF5B9109A6A2B0062928A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5B8109A6A2B0062928A /* AudioToolbox.framework */; }; + 301BF5BB109A6A2B0062928A /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5BA109A6A2B0062928A /* AVFoundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 301BF5BD109A6A2B0062928A /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5BC109A6A2B0062928A /* CFNetwork.framework */; }; + 301BF5BF109A6A2B0062928A /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5BE109A6A2B0062928A /* CoreLocation.framework */; }; + 301BF5C1109A6A2B0062928A /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5C0109A6A2B0062928A /* MediaPlayer.framework */; }; + 301BF5C3109A6A2B0062928A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5C2109A6A2B0062928A /* QuartzCore.framework */; }; + 301BF5C5109A6A2B0062928A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5C4109A6A2B0062928A /* SystemConfiguration.framework */; }; + 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 302D95EF14D2391D003F00A1 /* MainViewController.m */; }; + 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 302D95F014D2391D003F00A1 /* MainViewController.xib */; }; + 3053AC6F109B7857006FCFE7 /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 3053AC6E109B7857006FCFE7 /* VERSION */; }; + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */; }; + 3072F99713A8081B00425683 /* Capture.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 3072F99613A8081B00425683 /* Capture.bundle */; }; + 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */; }; + 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */; }; + 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */; }; + 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */; }; + 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */; }; + 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBC154F3926009F9C59 /* Default~iphone.png */; }; + 308D05371370CCF300D202BF /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052E1370CCF300D202BF /* icon-72.png */; }; + 308D05381370CCF300D202BF /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052F1370CCF300D202BF /* icon.png */; }; + 308D05391370CCF300D202BF /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05301370CCF300D202BF /* icon@2x.png */; }; + 30A0434814DC770100060A13 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30A0434314DC770100060A13 /* Localizable.strings */; }; + 30A0434914DC770100060A13 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30A0434614DC770100060A13 /* Localizable.strings */; }; + 30E1352710E2C1420031B30D /* Cordova.plist in Resources */ = {isa = PBXBuildFile; fileRef = 30E1352610E2C1420031B30D /* Cordova.plist */; }; + 30E5649213A7FCAF007403D8 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30E5649113A7FCAF007403D8 /* CoreMedia.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + A93EDE2C16022ECD00FF615F /* assets in Resources */ = {isa = PBXBuildFile; fileRef = A93EDE2B16022ECD00FF615F /* assets */; }; + A93EDE301602307200FF615F /* WTWikitudePlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = A93EDE2F1602307200FF615F /* WTWikitudePlugin.m */; }; + A93EDE501602315500FF615F /* libWikitudeSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A93EDE4C1602315500FF615F /* libWikitudeSDK.a */; }; + A93EDE511602315600FF615F /* libWikitudeSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A93EDE4E1602315500FF615F /* libWikitudeSDK.a */; }; + A93EDE7D1602348700FF615F /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93EDE771602348700FF615F /* CoreMotion.framework */; }; + A93EDE7E1602348700FF615F /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93EDE781602348700FF615F /* CoreVideo.framework */; }; + A93EDE7F1602348700FF615F /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A93EDE791602348700FF615F /* libsqlite3.dylib */; }; + A93EDE801602348700FF615F /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A93EDE7A1602348700FF615F /* libz.dylib */; }; + A93EDE811602348700FF615F /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93EDE7B1602348700FF615F /* OpenGLES.framework */; }; + A93EDE821602348700FF615F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93EDE7C1602348700FF615F /* Security.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 301BF534109A57CC0062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC07E0554694100DB518D; + remoteInfo = CordovaLib; + }; + 301BF550109A68C00062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = CordovaLib; + }; + 302D95EB14D23909003F00A1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 686357A9141002F100DF4CF2; + remoteInfo = CordovaLibTests; + }; + 3088BBB4154F38EF009F9C59 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 303A4068152124BB00182201; + remoteInfo = CordovaLibApp; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 1F766FDD13BBADB100FB74C0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = ""; }; + 1F766FE013BBADB100FB74C0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Localizable.strings; sourceTree = ""; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = CordovaLib.xcodeproj; sourceTree = CORDOVALIB; }; + 301BF56E109A69640062928A /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = SOURCE_ROOT; }; + 301BF5B4109A6A2B0062928A /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; }; + 301BF5B6109A6A2B0062928A /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; }; + 301BF5B8109A6A2B0062928A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 301BF5BA109A6A2B0062928A /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 301BF5BC109A6A2B0062928A /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 301BF5BE109A6A2B0062928A /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + 301BF5C0109A6A2B0062928A /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; + 301BF5C2109A6A2B0062928A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 301BF5C4109A6A2B0062928A /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 302D95EE14D2391D003F00A1 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 302D95EF14D2391D003F00A1 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 302D95F014D2391D003F00A1 /* MainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainViewController.xib; sourceTree = ""; }; + 3053AC6E109B7857006FCFE7 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = CORDOVALIB; }; + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; + 3072F99613A8081B00425683 /* Capture.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Capture.bundle; sourceTree = ""; }; + 307D28A1123043350040C0FA /* CordovaBuildSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CordovaBuildSettings.xcconfig; path = ../CordovaBuildSettings.xcconfig; sourceTree = ""; }; + 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x~ipad.png"; sourceTree = ""; }; + 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = ""; }; + 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = ""; }; + 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = ""; }; + 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x~iphone.png"; sourceTree = ""; }; + 3088BBBC154F3926009F9C59 /* Default~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default~iphone.png"; sourceTree = ""; }; + 308D052E1370CCF300D202BF /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72.png"; sourceTree = ""; }; + 308D052F1370CCF300D202BF /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; + 308D05301370CCF300D202BF /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = ""; }; + 30A0434414DC770100060A13 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Localizable.strings; sourceTree = ""; }; + 30A0434714DC770100060A13 /* se */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = se; path = Localizable.strings; sourceTree = ""; }; + 30E1352610E2C1420031B30D /* Cordova.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Cordova.plist; path = ../Cordova.plist; sourceTree = ""; }; + 30E5649113A7FCAF007403D8 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; + 32CA4F630368D1EE00C91783 /* HelloWorld-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HelloWorld-Prefix.pch"; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* HelloWorld-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "HelloWorld-Info.plist"; path = "../HelloWorld-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + A93EDE2B16022ECD00FF615F /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = ""; }; + A93EDE2E1602307200FF615F /* WTWikitudePlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTWikitudePlugin.h; sourceTree = ""; }; + A93EDE2F1602307200FF615F /* WTWikitudePlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WTWikitudePlugin.m; sourceTree = ""; }; + A93EDE491602315500FF615F /* WTArchitectView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTArchitectView.h; sourceTree = ""; }; + A93EDE4C1602315500FF615F /* libWikitudeSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWikitudeSDK.a; sourceTree = ""; }; + A93EDE4E1602315500FF615F /* libWikitudeSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWikitudeSDK.a; sourceTree = ""; }; + A93EDE771602348700FF615F /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; + A93EDE781602348700FF615F /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; + A93EDE791602348700FF615F /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; + A93EDE7A1602348700FF615F /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + A93EDE7B1602348700FF615F /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + A93EDE7C1602348700FF615F /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A93EDE7D1602348700FF615F /* CoreMotion.framework in Frameworks */, + A93EDE7E1602348700FF615F /* CoreVideo.framework in Frameworks */, + A93EDE7F1602348700FF615F /* libsqlite3.dylib in Frameworks */, + A93EDE801602348700FF615F /* libz.dylib in Frameworks */, + A93EDE811602348700FF615F /* OpenGLES.framework in Frameworks */, + A93EDE821602348700FF615F /* Security.framework in Frameworks */, + 301BF552109A68D80062928A /* libCordova.a in Frameworks */, + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 301BF5B5109A6A2B0062928A /* AddressBook.framework in Frameworks */, + 301BF5B7109A6A2B0062928A /* AddressBookUI.framework in Frameworks */, + 301BF5B9109A6A2B0062928A /* AudioToolbox.framework in Frameworks */, + 301BF5BB109A6A2B0062928A /* AVFoundation.framework in Frameworks */, + 301BF5BD109A6A2B0062928A /* CFNetwork.framework in Frameworks */, + 301BF5BF109A6A2B0062928A /* CoreLocation.framework in Frameworks */, + 301BF5C1109A6A2B0062928A /* MediaPlayer.framework in Frameworks */, + 301BF5C3109A6A2B0062928A /* QuartzCore.framework in Frameworks */, + 301BF5C5109A6A2B0062928A /* SystemConfiguration.framework in Frameworks */, + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */, + 30E5649213A7FCAF007403D8 /* CoreMedia.framework in Frameworks */, + A93EDE501602315500FF615F /* libWikitudeSDK.a in Frameworks */, + A93EDE511602315600FF615F /* libWikitudeSDK.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 302D95EE14D2391D003F00A1 /* MainViewController.h */, + 302D95EF14D2391D003F00A1 /* MainViewController.m */, + 302D95F014D2391D003F00A1 /* MainViewController.xib */, + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + ); + name = Classes; + path = HelloWorld/Classes; + sourceTree = SOURCE_ROOT; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* HelloWorld.app */, + ); + name = Products; + sourceTree = ""; + }; + 1F766FDB13BBADB100FB74C0 /* en.lproj */ = { + isa = PBXGroup; + children = ( + 1F766FDC13BBADB100FB74C0 /* Localizable.strings */, + ); + path = en.lproj; + sourceTree = ""; + }; + 1F766FDE13BBADB100FB74C0 /* es.lproj */ = { + isa = PBXGroup; + children = ( + 1F766FDF13BBADB100FB74C0 /* Localizable.strings */, + ); + path = es.lproj; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + A93EDE2B16022ECD00FF615F /* assets */, + 301BF56E109A69640062928A /* www */, + 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */, + A93EDE421602315500FF615F /* WikitudeSDK */, + 080E96DDFE201D6D7F000001 /* Classes */, + 307C750510C5A3420062BCA9 /* Plugins */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* HelloWorld-Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + path = HelloWorld; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 30A0434214DC770100060A13 /* de.lproj */, + 30A0434514DC770100060A13 /* se.lproj */, + 1F766FDB13BBADB100FB74C0 /* en.lproj */, + 1F766FDE13BBADB100FB74C0 /* es.lproj */, + 3072F99613A8081B00425683 /* Capture.bundle */, + 308D052D1370CCF300D202BF /* icons */, + 308D05311370CCF300D202BF /* splash */, + 30E1352610E2C1420031B30D /* Cordova.plist */, + 3053AC6E109B7857006FCFE7 /* VERSION */, + 8D1107310486CEB800E47090 /* HelloWorld-Info.plist */, + 307D28A1123043350040C0FA /* CordovaBuildSettings.xcconfig */, + ); + name = Resources; + path = HelloWorld/Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + A93EDE771602348700FF615F /* CoreMotion.framework */, + A93EDE781602348700FF615F /* CoreVideo.framework */, + A93EDE791602348700FF615F /* libsqlite3.dylib */, + A93EDE7A1602348700FF615F /* libz.dylib */, + A93EDE7B1602348700FF615F /* OpenGLES.framework */, + A93EDE7C1602348700FF615F /* Security.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + 301BF5B4109A6A2B0062928A /* AddressBook.framework */, + 301BF5B6109A6A2B0062928A /* AddressBookUI.framework */, + 301BF5B8109A6A2B0062928A /* AudioToolbox.framework */, + 301BF5BA109A6A2B0062928A /* AVFoundation.framework */, + 301BF5BC109A6A2B0062928A /* CFNetwork.framework */, + 301BF5BE109A6A2B0062928A /* CoreLocation.framework */, + 301BF5C0109A6A2B0062928A /* MediaPlayer.framework */, + 301BF5C2109A6A2B0062928A /* QuartzCore.framework */, + 301BF5C4109A6A2B0062928A /* SystemConfiguration.framework */, + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */, + 30E5649113A7FCAF007403D8 /* CoreMedia.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 301BF52E109A57CC0062928A /* Products */ = { + isa = PBXGroup; + children = ( + 301BF535109A57CC0062928A /* libCordova.a */, + 302D95EC14D23909003F00A1 /* CordovaLibTests.octest */, + 3088BBB5154F38EF009F9C59 /* CordovaLibApp.app */, + ); + name = Products; + sourceTree = ""; + }; + 307C750510C5A3420062BCA9 /* Plugins */ = { + isa = PBXGroup; + children = ( + A93EDE2D1602307200FF615F /* Wikitude */, + ); + name = Plugins; + path = HelloWorld/Plugins; + sourceTree = SOURCE_ROOT; + }; + 308D052D1370CCF300D202BF /* icons */ = { + isa = PBXGroup; + children = ( + 308D052E1370CCF300D202BF /* icon-72.png */, + 308D052F1370CCF300D202BF /* icon.png */, + 308D05301370CCF300D202BF /* icon@2x.png */, + ); + path = icons; + sourceTree = ""; + }; + 308D05311370CCF300D202BF /* splash */ = { + isa = PBXGroup; + children = ( + 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */, + 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */, + 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */, + 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */, + 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */, + 3088BBBC154F3926009F9C59 /* Default~iphone.png */, + ); + path = splash; + sourceTree = ""; + }; + 30A0434214DC770100060A13 /* de.lproj */ = { + isa = PBXGroup; + children = ( + 30A0434314DC770100060A13 /* Localizable.strings */, + ); + path = de.lproj; + sourceTree = ""; + }; + 30A0434514DC770100060A13 /* se.lproj */ = { + isa = PBXGroup; + children = ( + 30A0434614DC770100060A13 /* Localizable.strings */, + ); + path = se.lproj; + sourceTree = ""; + }; + A93EDE2D1602307200FF615F /* Wikitude */ = { + isa = PBXGroup; + children = ( + A93EDE2E1602307200FF615F /* WTWikitudePlugin.h */, + A93EDE2F1602307200FF615F /* WTWikitudePlugin.m */, + ); + path = Wikitude; + sourceTree = ""; + }; + A93EDE421602315500FF615F /* WikitudeSDK */ = { + isa = PBXGroup; + children = ( + A93EDE471602315500FF615F /* SDK */, + ); + name = WikitudeSDK; + path = HelloWorld/WikitudeSDK; + sourceTree = ""; + }; + A93EDE471602315500FF615F /* SDK */ = { + isa = PBXGroup; + children = ( + A93EDE481602315500FF615F /* inc */, + A93EDE4A1602315500FF615F /* lib */, + ); + path = SDK; + sourceTree = ""; + }; + A93EDE481602315500FF615F /* inc */ = { + isa = PBXGroup; + children = ( + A93EDE491602315500FF615F /* WTArchitectView.h */, + ); + path = inc; + sourceTree = ""; + }; + A93EDE4A1602315500FF615F /* lib */ = { + isa = PBXGroup; + children = ( + A93EDE4B1602315500FF615F /* Release-iphoneos */, + A93EDE4D1602315500FF615F /* Release-iphonesimulator */, + ); + path = lib; + sourceTree = ""; + }; + A93EDE4B1602315500FF615F /* Release-iphoneos */ = { + isa = PBXGroup; + children = ( + A93EDE4C1602315500FF615F /* libWikitudeSDK.a */, + ); + path = "Release-iphoneos"; + sourceTree = ""; + }; + A93EDE4D1602315500FF615F /* Release-iphonesimulator */ = { + isa = PBXGroup; + children = ( + A93EDE4E1602315500FF615F /* libWikitudeSDK.a */, + ); + path = "Release-iphonesimulator"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* HelloWorld */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloWorld" */; + buildPhases = ( + 304B58A110DAC018002A0835 /* Touch www folder */, + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 301BF551109A68C00062928A /* PBXTargetDependency */, + ); + name = HelloWorld; + productName = HelloWorld; + productReference = 1D6058910D05DD3D006BFB54 /* HelloWorld.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0420; + }; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HelloWorld" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + es, + de, + se, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 301BF52E109A57CC0062928A /* Products */; + ProjectRef = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* HelloWorld */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 301BF535109A57CC0062928A /* libCordova.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libCordova.a; + remoteRef = 301BF534109A57CC0062928A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 302D95EC14D23909003F00A1 /* CordovaLibTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CordovaLibTests.octest; + remoteRef = 302D95EB14D23909003F00A1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3088BBB5154F38EF009F9C59 /* CordovaLibApp.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = CordovaLibApp.app; + remoteRef = 3088BBB4154F38EF009F9C59 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 301BF570109A69640062928A /* www in Resources */, + 3053AC6F109B7857006FCFE7 /* VERSION in Resources */, + 30E1352710E2C1420031B30D /* Cordova.plist in Resources */, + 308D05371370CCF300D202BF /* icon-72.png in Resources */, + 308D05381370CCF300D202BF /* icon.png in Resources */, + 308D05391370CCF300D202BF /* icon@2x.png in Resources */, + 3072F99713A8081B00425683 /* Capture.bundle in Resources */, + 1F766FE113BBADB100FB74C0 /* Localizable.strings in Resources */, + 1F766FE213BBADB100FB74C0 /* Localizable.strings in Resources */, + 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */, + 30A0434814DC770100060A13 /* Localizable.strings in Resources */, + 30A0434914DC770100060A13 /* Localizable.strings in Resources */, + 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */, + 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */, + 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */, + 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */, + 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */, + 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */, + A93EDE2C16022ECD00FF615F /* assets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 304B58A110DAC018002A0835 /* Touch www folder */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Touch www folder"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "touch -cm ${PROJECT_DIR}/www"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */, + A93EDE301602307200FF615F /* WTWikitudePlugin.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 301BF551109A68C00062928A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CordovaLib; + targetProxy = 301BF550109A68C00062928A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 1F766FDC13BBADB100FB74C0 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 1F766FDD13BBADB100FB74C0 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 1F766FDF13BBADB100FB74C0 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 1F766FE013BBADB100FB74C0 /* es */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 30A0434314DC770100060A13 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 30A0434414DC770100060A13 /* de */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 30A0434614DC770100060A13 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 30A0434714DC770100060A13 /* se */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "HelloWorld/HelloWorld-Prefix.pch"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "HelloWorld/HelloWorld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 4.2; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/HelloWorld/WikitudeSDK/SDK/lib/Release$(EFFECTIVE_PLATFORM_NAME)\"", + ); + PRODUCT_NAME = HelloWorld; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "HelloWorld/HelloWorld-Prefix.pch"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "HelloWorld/HelloWorld-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 4.2; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/HelloWorld/WikitudeSDK/SDK/lib/Release$(EFFECTIVE_PLATFORM_NAME)\"", + ); + PRODUCT_NAME = HelloWorld; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 307D28A1123043350040C0FA /* CordovaBuildSettings.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", + ); + IPHONEOS_DEPLOYMENT_TARGET = 4.2; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-force_load", + "$(BUILT_PRODUCTS_DIR)/libCordova.a", + "-ObjC", + "-lstdc++", + ); + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 307D28A1123043350040C0FA /* CordovaBuildSettings.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", + ); + IPHONEOS_DEPLOYMENT_TARGET = 4.2; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-force_load$(BUILT_PRODUCTS_DIR)/libCordova.a)", + "-Obj-C", + "-lstdc++", + ); + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloWorld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HelloWorld" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..174a04e --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/project.xcworkspace/xcuserdata/Andi.xcuserdatad/UserInterfaceState.xcuserstate b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/project.xcworkspace/xcuserdata/Andi.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..280a3dd Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/project.xcworkspace/xcuserdata/Andi.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/HelloWorld.xcscheme b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/HelloWorld.xcscheme new file mode 100644 index 0000000..ab518cf --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/HelloWorld.xcscheme @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/xcschememanagement.plist b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..14dd04a --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + HelloWorld.xcscheme + + orderHint + 2 + + + SuppressBuildableAutocreation + + 1D6058900D05DD3D006BFB54 + + primary + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/.gitignore b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/.gitignore new file mode 100644 index 0000000..d30c0b0 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/.gitignore @@ -0,0 +1,6 @@ +*.mode1v3 +*.perspectivev3 +*.pbxuser +.DS_Store +build +www/phonegap.js diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/AppDelegate.h b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/AppDelegate.h new file mode 100644 index 0000000..2ffeb08 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/AppDelegate.h @@ -0,0 +1,45 @@ +/* + 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. + */ + +// +// AppDelegate.h +// HelloWorld +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import + +#import + +@interface AppDelegate : NSObject < UIApplicationDelegate > { + +} + +// invoke string is passed to your app on launch, this is only valid if you +// edit HelloWorld-Info.plist to add a protocol +// a simple tutorial can be found here : +// http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html + +@property (nonatomic, retain) IBOutlet UIWindow* window; +@property (nonatomic, retain) IBOutlet CDVViewController* viewController; + +@end + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/AppDelegate.m b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/AppDelegate.m new file mode 100644 index 0000000..141e0b3 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/AppDelegate.m @@ -0,0 +1,135 @@ +/* + 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. + */ + +// +// AppDelegate.m +// HelloWorld +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "AppDelegate.h" +#import "MainViewController.h" + +#import +#import + + +@implementation AppDelegate + +@synthesize window, viewController; + +- (id) init +{ + /** If you need to do any extra app-specific initialization, you can do it here + * -jm + **/ + NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + [cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; + + [CDVURLProtocol registerURLProtocol]; + + return [super init]; +} + +#pragma UIApplicationDelegate implementation + +/** + * This is main kick off after the app inits, the views and Settings are setup here. (preferred - iOS4 and up) + */ +- (BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions +{ + NSURL* url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey]; + NSString* invokeString = nil; + + if (url && [url isKindOfClass:[NSURL class]]) { + invokeString = [url absoluteString]; + NSLog(@"HelloWorld launchOptions = %@", url); + } + + CGRect screenBounds = [[UIScreen mainScreen] bounds]; + self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease]; + self.window.autoresizesSubviews = YES; + + CGRect viewBounds = [[UIScreen mainScreen] applicationFrame]; + + self.viewController = [[[MainViewController alloc] init] autorelease]; + self.viewController.useSplashScreen = YES; + self.viewController.wwwFolderName = @"www"; + self.viewController.startPage = @"index.html"; + self.viewController.invokeString = invokeString; + self.viewController.view.frame = viewBounds; + + // check whether the current orientation is supported: if it is, keep it, rather than forcing a rotation + BOOL forceStartupRotation = YES; + UIDeviceOrientation curDevOrientation = [[UIDevice currentDevice] orientation]; + + if (UIDeviceOrientationUnknown == curDevOrientation) { + // UIDevice isn't firing orientation notifications yet… go look at the status bar + curDevOrientation = (UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation]; + } + + if (UIDeviceOrientationIsValidInterfaceOrientation(curDevOrientation)) { + for (NSNumber *orient in self.viewController.supportedOrientations) { + if ([orient intValue] == curDevOrientation) { + forceStartupRotation = NO; + break; + } + } + } + + if (forceStartupRotation) { + NSLog(@"supportedOrientations: %@", self.viewController.supportedOrientations); + // The first item in the supportedOrientations array is the start orientation (guaranteed to be at least Portrait) + UIInterfaceOrientation newOrient = [[self.viewController.supportedOrientations objectAtIndex:0] intValue]; + NSLog(@"AppDelegate forcing status bar to: %d from: %d", newOrient, curDevOrientation); + [[UIApplication sharedApplication] setStatusBarOrientation:newOrient]; + } + + [self.window addSubview:self.viewController.view]; + [self.window makeKeyAndVisible]; + + return YES; +} + +// this happens while we are running ( in the background, or from within our own app ) +// only valid if HelloWorld-Info.plist specifies a protocol to handle +- (BOOL) application:(UIApplication*)application handleOpenURL:(NSURL*)url +{ + if (!url) { + return NO; + } + + // calls into javascript global function 'handleOpenURL' + NSString* jsString = [NSString stringWithFormat:@"handleOpenURL(\"%@\");", url]; + [self.viewController.webView stringByEvaluatingJavaScriptFromString:jsString]; + + // all plugins will get the notification, and their handlers will be called + [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]]; + + return YES; +} + +- (void) dealloc +{ + [super dealloc]; +} + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/MainViewController.h b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/MainViewController.h new file mode 100644 index 0000000..0f5577c --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/MainViewController.h @@ -0,0 +1,32 @@ +/* + 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. + */ + +// +// MainViewController.h +// HelloWorld +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import + +@interface MainViewController : CDVViewController + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/MainViewController.m b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/MainViewController.m new file mode 100644 index 0000000..86497c3 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/MainViewController.m @@ -0,0 +1,141 @@ +/* + 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. + */ + +// +// MainViewController.h +// HelloWorld +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "MainViewController.h" + +@implementation MainViewController + +- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return self; +} + +- (void) didReceiveMemoryWarning +{ + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +#pragma mark - View lifecycle + +- (void) viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view from its nib. +} + +- (void) viewDidUnload +{ + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + +- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + // Return YES for supported orientations + return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation]; +} + +/* Comment out the block below to over-ride */ +/* +- (CDVCordovaView*) newCordovaViewWithFrame:(CGRect)bounds +{ + return[super newCordovaViewWithFrame:bounds]; +} +*/ + +/* Comment out the block below to over-ride */ +/* +#pragma CDVCommandDelegate implementation + +- (id) getCommandInstance:(NSString*)className +{ + return [super getCommandInstance:className]; +} + +- (BOOL) execute:(CDVInvokedUrlCommand*)command +{ + return [super execute:command]; +} + +- (NSString*) pathForResource:(NSString*)resourcepath; +{ + return [super pathForResource:resourcepath]; +} + +- (void) registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className +{ + return [super registerPlugin:plugin withClassName:className]; +} +*/ + +#pragma UIWebDelegate implementation + +- (void) webViewDidFinishLoad:(UIWebView*) theWebView +{ + // only valid if ___PROJECTNAME__-Info.plist specifies a protocol to handle + if (self.invokeString) + { + // this is passed before the deviceready event is fired, so you can access it in js when you receive deviceready + NSLog(@"DEPRECATED: window.invokeString - use the window.handleOpenURL(url) function instead, which is always called when the app is launched through a custom scheme url."); + NSString* jsString = [NSString stringWithFormat:@"var invokeString = \"%@\";", self.invokeString]; + [theWebView stringByEvaluatingJavaScriptFromString:jsString]; + } + + // Black base color for background matches the native apps + theWebView.backgroundColor = [UIColor blackColor]; + + return [super webViewDidFinishLoad:theWebView]; +} + +/* Comment out the block below to over-ride */ +/* + +- (void) webViewDidStartLoad:(UIWebView*)theWebView +{ + return [super webViewDidStartLoad:theWebView]; +} + +- (void) webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error +{ + return [super webView:theWebView didFailLoadWithError:error]; +} + +- (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType +{ + return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType]; +} +*/ + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/MainViewController.xib b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/MainViewController.xib new file mode 100644 index 0000000..e45d65c --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Classes/MainViewController.xib @@ -0,0 +1,138 @@ + + + + + 1280 + 11C25 + 1919 + 1138.11 + 566.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 916 + + + IBProxyObject + IBUIView + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + {{0, 20}, {320, 460}} + + + + 3 + MQA + + 2 + + + + IBCocoaTouchFramework + + + + + + + view + + + + 3 + + + + + + 0 + + + + + + 1 + + + + + -1 + + + File's Owner + + + -2 + + + + + + + MainViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 3 + + + + + MainViewController + UIViewController + + IBProjectSource + ./Classes/MainViewController.h + + + + + 0 + IBCocoaTouchFramework + YES + 3 + 916 + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Cordova.plist b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Cordova.plist new file mode 100644 index 0000000..01a59d6 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Cordova.plist @@ -0,0 +1,67 @@ + + + + + UIWebViewBounce + + TopActivityIndicator + gray + EnableLocation + + EnableViewportScale + + AutoHideSplashScreen + + ShowSplashScreenSpinner + + MediaPlaybackRequiresUserAction + + AllowInlineMediaPlayback + + OpenAllWhitelistURLsInWebView + + BackupWebStorage + + ExternalHosts + + * + + Plugins + + WikitudePlugin + WTWikitudePlugin + Device + CDVDevice + Logger + CDVLogger + Compass + CDVLocation + Accelerometer + CDVAccelerometer + Camera + CDVCamera + NetworkStatus + CDVConnection + Contacts + CDVContacts + Debug Console + CDVDebugConsole + File + CDVFile + FileTransfer + CDVFileTransfer + Geolocation + CDVLocation + Notification + CDVNotification + Media + CDVSound + Capture + CDVCapture + SplashScreen + CDVSplashScreen + Battery + CDVBattery + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/CordovaBuildSettings.xcconfig b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/CordovaBuildSettings.xcconfig new file mode 100644 index 0000000..c70086c --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/CordovaBuildSettings.xcconfig @@ -0,0 +1,26 @@ +// +// 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. +// + +// Cordova.xcconfig +// __TESTING__ +// + +// Override this to use your project specific CORDOVALIB. +// You can base it off the current project path, $(PROJECT_DIR) +CORDOVALIB = $(CORDOVALIB) diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/HelloWorld-Info.plist b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/HelloWorld-Info.plist new file mode 100644 index 0000000..ef7c161 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/HelloWorld-Info.plist @@ -0,0 +1,58 @@ + + + + + CFBundleIcons + + CFBundlePrimaryIcon + + CFBundleIconFiles + + icon.png + icon@2x.png + icon-72.png + icon-72@2x.png + + UIPrerenderedIcon + + + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + icon.png + CFBundleIdentifier + com.wikitude.phonegapsamplehelloworld + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + + NSMainNibFile~ipad + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/HelloWorld-Prefix.pch b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/HelloWorld-Prefix.pch new file mode 100644 index 0000000..4105f6a --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/HelloWorld-Prefix.pch @@ -0,0 +1,26 @@ +/* + 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. + */ +// +// Prefix header for all source files of the 'HelloWorld' target in the 'HelloWorld' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Plugins/README b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Plugins/README new file mode 100644 index 0000000..f6e19d7 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Plugins/README @@ -0,0 +1,20 @@ +# +# 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. +# + +Put the .h and .m files of your plugin here. The .js files of your plugin belong in the www folder. \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Plugins/Wikitude/WTWikitudePlugin.h b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Plugins/Wikitude/WTWikitudePlugin.h new file mode 100644 index 0000000..0a71316 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Plugins/Wikitude/WTWikitudePlugin.h @@ -0,0 +1,14 @@ +// +// WTWikitudeSDK.h +// HelloWorld +// +// Created by Andreas Schacherbauer on 8/24/12. +// +// + + +#import + +@interface WTWikitudePlugin : CDVPlugin + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Plugins/Wikitude/WTWikitudePlugin.m b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Plugins/Wikitude/WTWikitudePlugin.m new file mode 100644 index 0000000..3e54f35 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Plugins/Wikitude/WTWikitudePlugin.m @@ -0,0 +1,402 @@ +// +// WTWikitudeSDK.m +// HelloWorld +// +// Created by Andreas Schacherbauer on 8/24/12. +// +// + +#import "WTWikitudePlugin.h" + +// Wikitude SDK +#import "WTArchitectView.h" + + + + +@interface WTWikitudePlugin () + +@property (nonatomic, strong) WTArchitectView *architectView; + +@property (nonatomic, strong) NSString *currentARchitectViewCallbackID; +@property (nonatomic, strong) NSString *currentPlugInErrorCallback; + +@property (nonatomic, assign) BOOL isUsingInjectedLocation; + +@end + + +@implementation WTWikitudePlugin +@synthesize architectView=_architectView; + + +#pragma mark - View Lifecycle +/* View Lifecycle */ +- (void)isDeviceSupported:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + BOOL isDeviceSupported = [WTArchitectView isDeviceSupported]; + + if (isDeviceSupported) { + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:isDeviceSupported]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + } else { + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:isDeviceSupported]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + + +- (void)open:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { +// NSString* echo = [arguments objectAtIndex:1]; + + + BOOL success = [WTArchitectView isDeviceSupported]; + if ( success ) { + + NSString *sdkKey = [options objectForKey:@"apiKey"]; + NSString *architectWorldFilePath = [options objectForKey:@"filePath"]; + + // First, lets check if we need to init a new sdk view + if ( !_architectView ) { + self.architectView = [[WTArchitectView alloc] initWithFrame:self.viewController.view.bounds]; + self.architectView.delegate = self; + [self.architectView initializeWithKey:sdkKey motionManager:nil]; + } + + // then add the view in its own navController to the ui. we need a own navController to have a backButton which can be used to dismiss the view + UIViewController *viewController = [[UIViewController alloc] init]; + viewController.view = self.architectView; + + UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; + navController.navigationBar.tintColor = [UIColor blackColor]; + navController.navigationBar.topItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissARchitectView)]; + [self.viewController presentViewController:navController animated:NO completion:^{ + // completion code + }]; + + + + // and finaly load the architect world, specified in the open function in js + if (architectWorldFilePath) { + + NSString *worldName = [architectWorldFilePath lastPathComponent]; + worldName = [worldName stringByDeletingPathExtension]; + NSString *worldNameExtension = [architectWorldFilePath pathExtension]; + + NSString *architectWorldDirectoryPath = [architectWorldFilePath stringByDeletingLastPathComponent]; + + NSString *loadablePath = [[NSBundle mainBundle] pathForResource:worldName ofType:worldNameExtension inDirectory:architectWorldDirectoryPath]; + [self.architectView loadArchitectWorldFromUrl:loadablePath]; + } + } + + // start the sdk view updates + [self.architectView start]; + + + if ( success ) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } else { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)close:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { +// NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + + [self.architectView stop]; +// [self.architectView removeFromSuperview]; + } + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)show:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { +// NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + self.architectView.hidden = NO; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)hide:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + self.architectView.hidden = YES; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)onResume:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + [self.architectView start]; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)onPause:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + [self.architectView stop]; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +#pragma mark - Location Handling + +- (void)setLocation:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + + float latitude = [[options objectForKey:@"lat"] floatValue]; + float longitude = [[options objectForKey:@"lon"] floatValue]; + float altitude = [[options objectForKey:@"alt"] floatValue]; + float accuracy = [[options objectForKey:@"acc"] floatValue]; + + if (!self.isUsingInjectedLocation) { + [self.architectView setUseInjectedLocation:YES]; + self.isUsingInjectedLocation = YES; + } + + [self.architectView injectLocationWithLatitude:latitude longitude:longitude altitude:altitude accuracy:accuracy]; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + + +#pragma mark - Javascript + +- (void)callJavascript:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + + @try { + + if (arguments.count >= 1) { + + NSMutableString *javascriptToCall = [[arguments objectAtIndex:1] mutableCopy]; + for (NSUInteger i = 2; i < arguments.count; i++) { + [javascriptToCall appendString:[arguments objectAtIndex:i]]; + } + + if (self.architectView) { + [self.architectView callJavaScript:javascriptToCall]; + } + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + }else + { + // return error no javascript to call found + } + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + + +- (void)onUrlInvoke:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + + + self.currentARchitectViewCallbackID = callbackId; + self.currentPlugInErrorCallback = callbackId; + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; + [pluginResult setKeepCallbackAsBool:YES]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +#pragma mark - WTArchitectView Delegate +- (void)urlWasInvoked:(NSString *)url +{ + + CDVPluginResult *pluginResult = nil; + NSString *javaScriptResult = nil; + + + if (url && self.currentARchitectViewCallbackID) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:url]; + [pluginResult setKeepCallbackAsBool:YES]; + javaScriptResult = [pluginResult toSuccessCallbackString:self.currentARchitectViewCallbackID]; + + + }else + { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; + javaScriptResult = [pluginResult toSuccessCallbackString:self.currentPlugInErrorCallback]; + } + + [self writeJavascript:javaScriptResult]; +} + +- (void)dismissARchitectView +{ + [self.viewController dismissModalViewControllerAnimated:NO]; + [self.architectView stop]; +} + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg.png new file mode 100644 index 0000000..784e9c7 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg@2x.png new file mode 100644 index 0000000..1e28c6d Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg@2x~ipad.png new file mode 100644 index 0000000..d4e3483 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg~ipad.png new file mode 100644 index 0000000..efbef8a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/controls_bg~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone.png new file mode 100644 index 0000000..155b88c Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone@2x.png new file mode 100644 index 0000000..79ef16b Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone@2x~ipad.png new file mode 100644 index 0000000..af1bbb2 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone~ipad.png new file mode 100644 index 0000000..ef1c472 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/microphone~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button.png new file mode 100644 index 0000000..ceb9589 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button@2x.png new file mode 100644 index 0000000..d6ce302 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button@2x~ipad.png new file mode 100644 index 0000000..0ac2e67 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button~ipad.png new file mode 100644 index 0000000..d8e24a4 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/record_button~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg.png new file mode 100644 index 0000000..bafc087 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg@2x.png new file mode 100644 index 0000000..798490b Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg@2x~ipad.png new file mode 100644 index 0000000..a1b7208 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg~ipad.png new file mode 100644 index 0000000..3b467f6 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/recording_bg~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button.png new file mode 100644 index 0000000..9c31838 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button@2x.png new file mode 100644 index 0000000..8cf657e Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button@2x~ipad.png new file mode 100644 index 0000000..88b606c Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button~ipad.png new file mode 100644 index 0000000..59bb7a5 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/Capture.bundle/stop_button~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/de.lproj/Localizable.strings b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/de.lproj/Localizable.strings new file mode 100644 index 0000000..f1cdb42 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/de.lproj/Localizable.strings @@ -0,0 +1,26 @@ +/* + 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. + */ + + +// accessibility label for recording button +"toggle audio recording" = "starten/beenden der Tonaufnahme"; +// notification spoken by VoiceOver when timed recording finishes +"timed recording complete" = "programmierte Aufnahme beendet"; +// accessibility hint for display of recorded elapsed time +"recorded time in minutes and seconds" = "aufgenommene Zeit in Minuten und Sekunden"; \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/en.lproj/Localizable.strings b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/en.lproj/Localizable.strings new file mode 100644 index 0000000..8972684 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/en.lproj/Localizable.strings @@ -0,0 +1,25 @@ +/* + 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. + */ + +// accessibility label for recording button +"toggle audio recording" = "toggle audio recording"; +// notification spoken by VoiceOver when timed recording finishes +"timed recording complete" = "timed recording complete"; +// accessibility hint for display of recorded elapsed time +"recorded time in minutes and seconds" = "recorded time in minutes and seconds"; \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/es.lproj/Localizable.strings b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/es.lproj/Localizable.strings new file mode 100644 index 0000000..23831e6 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/es.lproj/Localizable.strings @@ -0,0 +1,25 @@ +/* + 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. + */ + +// accessibility label for recording button +"toggle audio recording" = "grabación de audio cambiar"; +// notification spoken by VoiceOver when timed recording finishes +"timed recording complete" = "tiempo de grabación completo"; +// accessibility hint for display of recorded elapsed time +"recorded time in minutes and seconds" = "tiempo registrado en minutos y segundos"; \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon-72.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon-72.png new file mode 100644 index 0000000..8c6e5df Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon-72.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon-72@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon-72@2x.png new file mode 100644 index 0000000..dd819da Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon-72@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon.png new file mode 100644 index 0000000..b2571a7 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon@2x.png new file mode 100644 index 0000000..d75098f Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/icons/icon@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/se.lproj/Localizable.strings b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/se.lproj/Localizable.strings new file mode 100644 index 0000000..0af9646 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/se.lproj/Localizable.strings @@ -0,0 +1,26 @@ +/* + 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. + */ + + +// accessibility label for recording button +"toggle audio recording" = "börja/avsluta inspelning"; +// notification spoken by VoiceOver when timed recording finishes +"timed recording complete" = "inspelning har avslutad"; +// accessibility hint for display of recorded elapsed time +"recorded time in minutes and seconds" = "inspelad tid in minuter och sekund"; \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Landscape@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Landscape@2x~ipad.png new file mode 100644 index 0000000..95c542d Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Landscape@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Landscape~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Landscape~ipad.png new file mode 100644 index 0000000..f8e2b52 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Landscape~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Portrait@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Portrait@2x~ipad.png new file mode 100644 index 0000000..aae1862 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Portrait@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Portrait~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Portrait~ipad.png new file mode 100644 index 0000000..af9158a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default-Portrait~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default@2x~iphone.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default@2x~iphone.png new file mode 100644 index 0000000..bd24886 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default@2x~iphone.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default~iphone.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default~iphone.png new file mode 100644 index 0000000..6fcba56 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/Resources/splash/Default~iphone.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/main.m b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/main.m new file mode 100644 index 0000000..25e83db --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/HelloWorld/main.m @@ -0,0 +1,35 @@ +/* + 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. + */ +// +// main.m +// HelloWorld +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate"); + [pool release]; + return retVal; +} diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/world/HelloWorld.html b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/world/HelloWorld.html new file mode 100644 index 0000000..3ae6442 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/assets/world/HelloWorld.html @@ -0,0 +1,52 @@ + + + + + + +My ARchitect World + + + + + + + + + + + + + + \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/debug b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/debug new file mode 100755 index 0000000..37b0d63 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/debug @@ -0,0 +1,47 @@ +#!/bin/bash + +# +# 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. +# + +# +# compile and launch a Cordova/iOS project to the simulator +# + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) +PROJECT_PATH=$CORDOVA_PATH/.. + +for file in $PROJECT_PATH/*.xcodeproj; do + PROJECT_NAME=$(basename "$file" .xcodeproj) +done; + +cd $PROJECT_PATH + +APP=build/$PROJECT_NAME.app +SDK=`xcodebuild -showsdks | grep Sim | tail -1 | awk '{print $6}'` + +xcodebuild -project $PROJECT_NAME.xcodeproj -arch i386 -target $PROJECT_NAME -configuration Debug -sdk $SDK clean build VALID_ARCHS="i386" CONFIGURATION_BUILD_DIR=$PROJECT_PATH/build + +# launch using emulate + +$CORDOVA_PATH/emulate $PROJECT_PATH/$APP + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/emulate b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/emulate new file mode 100755 index 0000000..3822121 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/emulate @@ -0,0 +1,58 @@ +#! /bin/sh +# +# 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. +# + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) +PROJECT_PATH=$CORDOVA_PATH/.. + +function getAppPath() { + for file in $PROJECT_PATH/*.xcodeproj; do + PROJECT_NAME=$(basename "$file" .xcodeproj) + done; + APP=build/$PROJECT_NAME.app + APP_PATH=$PROJECT_PATH/$APP +} + +APP_PATH=$1 + +if [ $# -lt 1 ]; then + getAppPath +fi + +if [ ! -d "$APP_PATH" ]; then + read -p "Project '$APP_PATH' is not built. Build? [y/n]: " REPLY + if [ "$REPLY" == "y" ]; then + $CORDOVA_PATH/debug + exit 0 + else + echo "$APP_PATH not found to emulate." + exit 1 + fi +fi + +# launch using ios-sim + +if which ios-sim >/dev/null; then + ios-sim launch $APP_PATH --stderr console.log --stdout console.log & +else + echo -e '\033[31mError: ios-sim was not found. Please download, build and install version 1.4 or greater from https://github.com/phonegap/ios-sim into your path. Or "brew install ios-sim" using homebrew: http://mxcl.github.com/homebrew/\033[m'; exit 1; +fi + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/log b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/log new file mode 100755 index 0000000..fd1261c --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/cordova/log @@ -0,0 +1,26 @@ +#! /bin/sh +# +# 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. +# + +# +# USAGE +# +# ./log [path] +# +tail -f ${1:-".."}/console.log diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/config.xml b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/config.xml new file mode 100644 index 0000000..a7e35db --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/config.xml @@ -0,0 +1,47 @@ + + + Hello Cordova + + + A sample Apache Cordova application that responds to the deviceready event. + + + + Apache Cordova Team + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/cordova-2.0.0.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/cordova-2.0.0.js new file mode 100644 index 0000000..c2caa2f --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/cordova-2.0.0.js @@ -0,0 +1,5240 @@ +// commit 114cf5304a74ff8f7c9ff1d21cf5652298af04b0 + +// File generated at :: Wed Jul 18 2012 16:47:25 GMT-0700 (PDT) + +/* + 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} phoneNumbers array of phone numbers +* @param {Array.} emails array of email addresses +* @param {Array.} addresses array of addresses +* @param {Array.} ims instant messaging user ids +* @param {Array.} organizations +* @param {DOMString} birthday contact's birthday +* @param {DOMString} note user notes about contact +* @param {Array.} photos +* @param {Array.} categories +* @param {Array.} 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][;base64], + * + * @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.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/ios/plugin/ios/Contact.js +define("cordova/plugin/ios/Contact", function(require, exports, module) { +var exec = require('cordova/exec'), + ContactError = require('cordova/plugin/ContactError'); + +/** + * Provides iOS Contact.display API. + */ +module.exports = { + display : function(errorCB, options) { + /* + * Display a contact using the iOS Contact Picker UI + * NOT part of W3C spec so no official documentation + * + * @param errorCB error callback + * @param options object + * allowsEditing: boolean AS STRING + * "true" to allow editing the contact + * "false" (default) display contact + */ + + if (this.id === null) { + if (typeof errorCB === "function") { + var errorObj = new ContactError(ContactError.UNKNOWN_ERROR); + errorCB(errorObj); + } + } + else { + exec(null, errorCB, "Contacts","displayContact", [this.id, options]); + } + } +}; +}); + +// file: lib/ios/plugin/ios/Entry.js +define("cordova/plugin/ios/Entry", function(require, exports, module) { +module.exports = { + toURL:function() { + // TODO: refactor path in a cross-platform way so we can eliminate + // these kinds of platform-specific hacks. + return "file://localhost" + this.fullPath; + }, + toURI: function() { + console.log("DEPRECATED: Update your code to use 'toURL'"); + return "file://localhost" + this.fullPath; + } +}; +}); + +// file: lib/ios/plugin/ios/FileReader.js +define("cordova/plugin/ios/FileReader", function(require, exports, module) { +var exec = require('cordova/exec'), + FileError = require('cordova/plugin/FileError'), + FileReader = require('cordova/plugin/FileReader'), + ProgressEvent = require('cordova/plugin/ProgressEvent'); + +module.exports = { + 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 = decodeURIComponent(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]); + } +}; +}); + +// file: lib/ios/plugin/ios/console.js +define("cordova/plugin/ios/console", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * This class provides access to the debugging console. + * @constructor + */ +var DebugConsole = function() { + this.winConsole = window.console; + this.logLevel = DebugConsole.INFO_LEVEL; +}; + +// from most verbose, to least verbose +DebugConsole.ALL_LEVEL = 1; // same as first level +DebugConsole.INFO_LEVEL = 1; +DebugConsole.WARN_LEVEL = 2; +DebugConsole.ERROR_LEVEL = 4; +DebugConsole.NONE_LEVEL = 8; + +DebugConsole.prototype.setLevel = function(level) { + this.logLevel = level; +}; + +var stringify = function(message) { + try { + if (typeof message === "object" && JSON && JSON.stringify) { + try { + return JSON.stringify(message); + } + catch (e) { + return "error JSON.stringify()ing argument: " + e; + } + } else { + return message.toString(); + } + } catch (e) { + return e.toString(); + } +}; + +/** + * Print a normal log message to the console + * @param {Object|String} message Message or object to print to the console + */ +DebugConsole.prototype.log = function(message) { + if (this.logLevel <= DebugConsole.INFO_LEVEL) { + exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'INFO' } ]); + } + else if (this.winConsole && this.winConsole.log) { + this.winConsole.log(message); + } +}; + +/** + * Print a warning message to the console + * @param {Object|String} message Message or object to print to the console + */ +DebugConsole.prototype.warn = function(message) { + if (this.logLevel <= DebugConsole.WARN_LEVEL) { + exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'WARN' } ]); + } + else if (this.winConsole && this.winConsole.warn) { + this.winConsole.warn(message); + } +}; + +/** + * Print an error message to the console + * @param {Object|String} message Message or object to print to the console + */ +DebugConsole.prototype.error = function(message) { + if (this.logLevel <= DebugConsole.ERROR_LEVEL) { + exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'ERROR' } ]); + } + else if (this.winConsole && this.winConsole.error){ + this.winConsole.error(message); + } +}; + +module.exports = new DebugConsole(); +}); + +// file: lib/ios/plugin/ios/contacts.js +define("cordova/plugin/ios/contacts", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * Provides iOS enhanced contacts API. + */ +module.exports = { + newContactUI : function(successCallback) { + /* + * Create a contact using the iOS Contact Picker UI + * NOT part of W3C spec so no official documentation + * + * returns: the id of the created contact as param to successCallback + */ + exec(successCallback, null, "Contacts","newContact", []); + }, + chooseContact : function(successCallback, options) { + /* + * Select a contact using the iOS Contact Picker UI + * NOT part of W3C spec so no official documentation + * + * @param errorCB error callback + * @param options object + * allowsEditing: boolean AS STRING + * "true" to allow editing the contact + * "false" (default) display contact + * + * returns: the id of the selected contact as param to successCallback + */ + exec(successCallback, null, "Contacts","chooseContact", [options]); + } +}; +}); + +// file: lib/ios/plugin/ios/nativecomm.js +define("cordova/plugin/ios/nativecomm", function(require, exports, module) { +var cordova = require('cordova'); + +/** + * Called by native code to retrieve all queued commands and clear the queue. + */ +module.exports = function() { + var json = JSON.stringify(cordova.commandQueue); + cordova.commandQueue = []; + return json; +}; +}); + +// file: lib/ios/plugin/ios/notification.js +define("cordova/plugin/ios/notification", function(require, exports, module) { +var Media = require('cordova/plugin/Media'); + +module.exports = { + beep:function(count) { + (new Media('beep.wav')).play(); + } +}; +}); + +// 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 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 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/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 + + + + + + + + Hello Cordova + + +
+

Apache Cordova™

+
+ + +
+
+ + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/js/WikitudePlugin.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/js/WikitudePlugin.js new file mode 100644 index 0000000..997558e --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/js/WikitudePlugin.js @@ -0,0 +1,353 @@ +var WikitudePlugin = { + + /** + * + * This is the SDK Key, provided to you after you purchased the Wikitude SDK from http://www.wikitude.com/developer/sdk + * If you're having a trial version, leave this string empty + * + */ + mySDKKey : "ENTER-YOUR-KEY-HERE", + + /** + * + * Change the value of this variable to modify the location update rate + * + */ + locationUpdateRate : 3000, + + /** + * + * This variable represents if the current device is capable of running the Wikitude SDK + * + */ + isDeviceSupported : false, + + /** + * + * This watchID is used to shedule location updates + * + */ + watchID : null, + + /** + * + * Callbacks to get device information if ARchitect Worlds can be launched + * + */ + onDeviceSupportedCallback : null, + onDeviceNotSupportedCallback : null, + + /** + * + * Callbacks to get notified if the ARchitect World finished launching or if something went wrong during the World launch + * + */ + onARchitectWorldLaunchedCallback : null, + onARchitectWorldFailedLaunchingCallback : null, + + /** + * + * This function gets called if PhoneGap reports that it has finished loading successfully. + * + */ + isDeviceSupported: function(successCallback, errorCallback) + { + + WikitudePlugin.onDeviceSupportedCallback = successCallback; + WikitudePlugin.onDeviceNotSupportedCallback = errorCallback; + + + // PhoneGap is running, so the first thing we do is to check if the current device is capable of running the Wikitude Plugin + cordova.exec(WikitudePlugin.deviceIsARchitectReady, WikitudePlugin.deviceIsNotARchitectReady, "WikitudePlugin", "isDeviceSupported", [""]); + + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is able to start the Wikitude SDK + * + */ + deviceIsARchitectReady : function() + { + // We keep track of the device status + WikitudePlugin.isDeviceSupported = true; + + + if(WikitudePlugin.onDeviceSupportedCallback) + { + WikitudePlugin.onDeviceSupportedCallback(); + } + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is not able of starting the Wikitude SDK. + * + */ + deviceIsNotARchitectReady : function() + { + WikitudePlugin.isDeviceSupported = false; + + // In this case we notify the user that his device is not supported by the Wikitude SDK + if(WikitudePlugin.onDeviceNotSupportedCallback) + { + WikitudePlugin.onDeviceNotSupportedCallback(); + } + }, + + + /* + * ============================================================================================================================= + * + * PUBLIC API + * + * ============================================================================================================================= + */ + + /* Managing ARchitect world loading */ + + /** + * + * Call this function if you want to load an ARchitect World + * + * @param {String} worldPath The path to an ARchitect world ether on the device or on e.g. your dropbox + * + */ + loadARchitectWorld : function(worldPath) + { + + // before we actually call load, we check again if the device is able to open the world + if(WikitudePlugin.isDeviceSupported) + { + + // the 'open' function of the Wikitude Plugin requires a option dictionary with two keys: + // @param {Object} options (required) + // @param {String} options.sdkKey License key for the Wikitude SDK + // @param {String} options.filePath The path to a local ARchitect world or to a ARchitect world on a server or your dropbox + + cordova.exec(WikitudePlugin.worldLaunched, WikitudePlugin.worldFailedLaunching, "WikitudePlugin", "open", [{ sdkKey: WikitudePlugin.mySDKKey, filePath: worldPath}]); + + + // We add an event listener on the resume and pause event of the application lifecycle + document.addEventListener("resume", WikitudePlugin.onResume, false); + document.addEventListener("pause", WikitudePlugin.onPause, false); + + // After we started loading the world, we start location updates + WikitudePlugin.startLocationUpdates(); + + }else + { + // if the device is not able to start the Wikitude SDK, we notify the user again + WikitudePlugin.deviceNotARchitectReady(); + } + }, + + /* Managing the Wikitude SDK Lifecycle */ + + /** + * + * Use this function to stop the Wikitude SDK and to remove the ARchitectView from the screen + * + */ + close : function() + { + document.removeEventListener("pause", WikitudePlugin.onPause, false); + document.removeEventListener("resume", WikitudePlugin.onResume, false); + + WikitudePlugin.stopLocationUpdates(); + + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]); + }, + + /** + * + * Use this function to only hide the Wikitude SDK. All location and rendering updates are still active + * + */ + hide : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "hide", [""]); + }, + + /** + * + * Use this function to show the Wikitude SDK if it was hidden before + * + */ + show : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "show", [""]); + }, + + /* Interacting with the Wikitude SDK */ + + /** + * + * Use this function to call javascript which will be executed in the context of your ARchitect World + * + * + * @param js The JavaScript that gets evaluated in context of the ARchitect World + * + */ + callJavaScript : function(js) + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "callJavascript", [js]); + }, + + /** + * + * Use this function to set a callback which will be invoked when the ARchitect World calls for example + * document.location = "architectsdk://opendetailpage?id=9"; + * + * + * @param onUrlInvokeCallback A function which gets called when the ARchitect World invokes a call to "document.location = architectsdk://" + */ + setOnUrlInvokeCallback : function(onUrlInvokeCallback) + { + cordova.exec(onUrlInvokeCallback, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]); + }, + + + /* + * ============================================================================================================================= + * + * Callbacks of public functions + * + * ============================================================================================================================= + */ + + /** + * + * Use this callback to get notified if the world loaded successfully + * + */ + worldLaunched : function() + { + if(WikitudePlugin.onARchitectWorldLaunchedCallback) + { + WikitudePlugin.onARchitectWorldLaunchedCallback(); + } + }, + + /** + * + * Use this callback to get notified if the Wikitude SDK wasn't able to load the ARchitect World + * + */ + worldFailedLaunching : function(err) + { + if(WikitudePlugin.onARchitectWorldFailedLaunchingCallback) + { + WikitudePlugin.onARchitectWorldFailedLaunchingCallback(err); + } + }, + + /* Lifecycle updates */ + + /** + * + * This function actually starts the PhoneGap location updates + * + */ + startLocationUpdates : function() + { + + WikitudePlugin.watchID = navigator.geolocation.watchPosition(WikitudePlugin.onReceivedLocation, WikitudePlugin.onWikitudeError, { frequency: WikitudePlugin.locationUpdateRate }); + }, + + /** + * + * This callback gets called everytime the location did update + * + */ + onReceivedLocation : function(position) + { + + // Every time that PhoneGap did received a location update, we pass the location into the Wikitude SDK + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "setLocation", [{ lat: position.coords.latitude, lon: position.coords.longitude, alt: position.coords.altitude, acc: position.coords.accuracy}]); + }, + + /** + * + * Use this function to stop location updates + * + */ + stopLocationUpdates : function() + { + + // We clear the location update watch which was responsible for updating the location in a specific time interval + navigator.geolocation.clearWatch(WikitudePlugin.watchID); + WikitudePlugin.watchID = null; + }, + + /** + * + * This function gets called every time the application did become active. + * + */ + onResume : function() + { + + // Call the Wikitude SDK that the application did become active again + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onResume", [""]); + + // And start continuing updating the user location + WikitudePlugin.startLocationUpdates(); + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onPause : function() + { + + // Call the Wikitude SDK that the application did resign active + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onPause", [""]); + + // And stop all ongoing location updates + WikitudePlugin.stopLocationUpdates(); + }, + + /** + * + * Android specific! + * This function gets called if the user presses the back button + * + */ + onBackButton : function() + { + + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]); + WikitudePlugin.stopLocationUpdates(); + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeOK : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeError : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + report: function(id) + { + console.log("app report: " + id); + } +}; diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/js/index.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/js/index.js new file mode 100644 index 0000000..412a0fe --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/js/index.js @@ -0,0 +1,116 @@ +var app = { + initialize: function() { + this.bind(); + }, + bind: function() { + document.addEventListener('deviceready', this.deviceready, false); + }, + + /** + * + * This function extracts an url parameter + * + */ + getUrlParameterForKey : function( url, requestedParam ) + { + requestedParam = requestedParam.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); + var regexS = "[\\?&]"+requestedParam+"=([^&#]*)"; + var regex = new RegExp( regexS ); + var results = regex.exec( url ); + if( results == null ) + return ""; + else + { + var result = decodeURIComponent(results[1]); + return result; + } + + }, + + /** + * + * This function gets called if you call "document.location = architectsdk://" in your ARchitect World + * + * + * @param url The url which was called in ARchitect World + * + */ + onClickInARchitectWorld : function(url) + { + + app.report("you clicked on a label with text: " + app.getUrlParameterForKey(url, 'text')); + }, + + /** + * + * This function gets called it the Wikitude SDK is able to start an ARchitect World (the current device is supported by the Wikitude SDK) + * + */ + onDeviceIsReadyCallback : function() + { + // The device is able to launch ARchitect World, so we load the 'Hello World' example + WikitudePlugin.loadARchitectWorld("assets/world/HelloWorld.html"); + + // To be able to respond on events inside the ARchitect World, we set a onURLInvoke callback + WikitudePlugin.setOnUrlInvokeCallback(app.onClickInARchitectWorld); + + // This is a example how you can interact with the ARchitect World to pass in additional information + // In this example, a JavaScript function gets called which sets a new text for a label + WikitudePlugin.callJavaScript("didReceivedNewTextForLabel('Hello World')"); + }, + + /** + * + * This function gets if the current device is not capable of running ARchitect Worlds + * + */ + onDeviceIsUnsupportedCallback : function() + { + app.report('device is not supported'); + }, + + /** + * + * This function gets if the ARchitect World finished loading + * + */ + onARchitectWorldLaunchedCallback : function() + { + app.report('ARchitect World launched'); + }, + + /** + * + * This function gets if the ARchitect failed loading + * + */ + onARchitectWorldFailedLaunchingCallback : function(err) + { + app.report('ARchitect World failed launching'); + }, + + /** + * + * This function gets called when the Wikitude SDK is ready to start an ARchitect World (the current device is supported by the Wikitude SDK) + * + */ + deviceready: function() { + // note that this is an event handler so the scope is that of the event + // so we need to call app.report(), and not this.report() + app.report('deviceready'); + + // When PhoneGap finished loading we forward this event into the Wikitude SDK wrapper. + // @param {function} A function which gets called if the device is able to launch ARchitect Worlds + // @param {function} A function which gets called if the device is not able to launch ARchitect Worlds + WikitudePlugin.isDeviceSupported(app.onDeviceIsReadyCallback, app.onDeviceIsUnsupportedCallback); + + // set a callback on the WikitudePlugin to get informed when the ARchitect World finished loading + WikitudePlugin.onARchitectWorldLaunchedCallback = app.onARchitectWorldLaunchedCallback; + + // Set a callback on the WikitudePlugin to get informed when the ARchitect World failed loading + WikitudePlugin.onARchitectWorldFailedLaunchingCallback = app.onARchitectWorldFailedLaunchingCallback; + }, + report: function(id) { + console.log("report:" + id); + } +}; diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_128.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_128.png new file mode 100644 index 0000000..3516df3 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_128.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_16.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_16.png new file mode 100644 index 0000000..54e19c5 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_16.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_24.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_24.png new file mode 100644 index 0000000..c7d43ad Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_24.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_256.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_256.png new file mode 100644 index 0000000..e1cd0e6 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_256.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_32.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_32.png new file mode 100644 index 0000000..734fffc Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_32.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_48.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_48.png new file mode 100644 index 0000000..8ad8bac Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_48.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_512.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_512.png new file mode 100644 index 0000000..c9465f3 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_512.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_64.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_64.png new file mode 100644 index 0000000..03b3849 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_64.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_36.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_36.png new file mode 100644 index 0000000..cd5032a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_36.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_48.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_48.png new file mode 100644 index 0000000..e79c606 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_48.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_72.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_72.png new file mode 100644 index 0000000..4d27634 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_72.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_96.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_96.png new file mode 100644 index 0000000..ec7ffbf Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_android_96.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_bb_80.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_bb_80.png new file mode 100644 index 0000000..f86a27a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_bb_80.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_114.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_114.png new file mode 100644 index 0000000..efd9c37 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_114.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_144.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_144.png new file mode 100644 index 0000000..dd819da Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_144.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_57.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_57.png new file mode 100644 index 0000000..c795fc4 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_57.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_72.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_72.png new file mode 100644 index 0000000..b1cfde7 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/icon/cordova_ios_72.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_hdpi_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_hdpi_landscape.png new file mode 100644 index 0000000..a61e2b1 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_hdpi_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_hdpi_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_hdpi_portrait.png new file mode 100644 index 0000000..5d6a28a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_hdpi_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_ldpi_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_ldpi_landscape.png new file mode 100644 index 0000000..f3934cd Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_ldpi_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_ldpi_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_ldpi_portrait.png new file mode 100644 index 0000000..65ad163 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_ldpi_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_mdpi_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_mdpi_landscape.png new file mode 100644 index 0000000..a1b697c Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_mdpi_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_mdpi_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_mdpi_portrait.png new file mode 100644 index 0000000..ea15693 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_mdpi_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_xhdpi_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_xhdpi_landscape.png new file mode 100644 index 0000000..79f2f09 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_xhdpi_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_xhdpi_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_xhdpi_portrait.png new file mode 100644 index 0000000..c2e8042 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/android_xhdpi_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/blackberry_transparent_300.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/blackberry_transparent_300.png new file mode 100644 index 0000000..b548bdc Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/blackberry_transparent_300.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/blackberry_transparent_400.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/blackberry_transparent_400.png new file mode 100644 index 0000000..3facdf9 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/blackberry_transparent_400.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_landscape.png new file mode 100644 index 0000000..04be5ac Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_portrait.png new file mode 100644 index 0000000..41e839d Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_retina_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_retina_landscape.png new file mode 100644 index 0000000..95c542d Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_retina_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_retina_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_retina_portrait.png new file mode 100644 index 0000000..aae1862 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/ipad_retina_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_landscape.png new file mode 100644 index 0000000..d154883 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_portrait.png new file mode 100644 index 0000000..6fcba56 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_retina_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_retina_landscape.png new file mode 100644 index 0000000..0165669 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_retina_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_retina_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_retina_portrait.png new file mode 100644 index 0000000..bd24886 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/iphone_retina_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/windows_phone_portrait.jpg b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/windows_phone_portrait.jpg new file mode 100644 index 0000000..9f95387 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/res/screen/windows_phone_portrait.jpg differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/spec.html b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/spec.html new file mode 100644 index 0000000..83d7d2e --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/spec.html @@ -0,0 +1,50 @@ + + + + Jasmine Spec Runner + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/spec/helper.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/spec/helper.js new file mode 100644 index 0000000..9f99445 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/spec/helper.js @@ -0,0 +1,11 @@ +afterEach(function() { + document.getElementById('stage').innerHTML = ''; +}); + +var helper = { + trigger: function(obj, name) { + var e = document.createEvent('Event'); + e.initEvent(name, true, true); + obj.dispatchEvent(e); + } +}; diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/spec/index.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/spec/index.js new file mode 100644 index 0000000..121cf63 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/HelloWorld/www/spec/index.js @@ -0,0 +1,49 @@ +describe('app', function() { + describe('initialize', function() { + it('should bind deviceready', function() { + runs(function() { + spyOn(app, 'deviceready'); + app.initialize(); + helper.trigger(window.document, 'deviceready'); + }); + + waitsFor(function() { + return (app.deviceready.calls.length > 0); + }, 'deviceready should be called once', 500); + + runs(function() { + expect(app.deviceready).toHaveBeenCalled(); + }); + }); + }); + + describe('deviceready', function() { + it('should report that it fired', function() { + spyOn(app, 'report'); + app.deviceready(); + expect(app.report).toHaveBeenCalledWith('deviceready'); + }); + }); + + describe('report', function() { + beforeEach(function() { + var el = document.getElementById('stage'); + el.innerHTML = ['
', + '

Pending

', + '

Complete

', + '
'].join('\n'); + }); + + it('should show the completion state', function() { + app.report('deviceready'); + var el = document.querySelector('#deviceready .complete:not(.hide)'); + expect(el).toBeTruthy(); + }); + + it('should hide the pending state', function() { + app.report('deviceready'); + var el = document.querySelector('#deviceready .pending.hide'); + expect(el).toBeTruthy(); + }); + }); +}); diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/README.md b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/README.md new file mode 100644 index 0000000..985ec76 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Basic/README.md @@ -0,0 +1,13 @@ +# Hello World iOS + +This document describes all necessary steps to get the sample running. + + +###Setup +*** + + +* Download the Wikitude SDK from [our website](http://www.wikitude.com/developer/sdk) (You need to register yourself as a Wikitude developer) + +* Copy the SDK folder from ``` [DownloadedSDKRoot/iOS/SDK/SDK] ``` into ``` [ProjectFolder/"AppName"/WikitudeSDK] ``` + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/TemplateIcon.icns b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/TemplateIcon.icns new file mode 100644 index 0000000..47f85e5 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/TemplateIcon.icns differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/TemplateInfo.plist b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/TemplateInfo.plist new file mode 100644 index 0000000..6e6b271 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/TemplateInfo.plist @@ -0,0 +1,28 @@ + + + + + + Description + This template provides a starting point for a Cordova based application. Just modify the www folder contents with your HTML, CSS and Javascript. + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/project.pbxproj b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/project.pbxproj new file mode 100644 index 0000000..fcfa7c8 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/project.pbxproj @@ -0,0 +1,870 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 1F766FE113BBADB100FB74C0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1F766FDC13BBADB100FB74C0 /* Localizable.strings */; }; + 1F766FE213BBADB100FB74C0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1F766FDF13BBADB100FB74C0 /* Localizable.strings */; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 301BF552109A68D80062928A /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF535109A57CC0062928A /* libCordova.a */; }; + 301BF570109A69640062928A /* www in Resources */ = {isa = PBXBuildFile; fileRef = 301BF56E109A69640062928A /* www */; }; + 301BF5B5109A6A2B0062928A /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5B4109A6A2B0062928A /* AddressBook.framework */; }; + 301BF5B7109A6A2B0062928A /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5B6109A6A2B0062928A /* AddressBookUI.framework */; }; + 301BF5B9109A6A2B0062928A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5B8109A6A2B0062928A /* AudioToolbox.framework */; }; + 301BF5BB109A6A2B0062928A /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5BA109A6A2B0062928A /* AVFoundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 301BF5BD109A6A2B0062928A /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5BC109A6A2B0062928A /* CFNetwork.framework */; }; + 301BF5BF109A6A2B0062928A /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5BE109A6A2B0062928A /* CoreLocation.framework */; }; + 301BF5C1109A6A2B0062928A /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5C0109A6A2B0062928A /* MediaPlayer.framework */; }; + 301BF5C3109A6A2B0062928A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5C2109A6A2B0062928A /* QuartzCore.framework */; }; + 301BF5C5109A6A2B0062928A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5C4109A6A2B0062928A /* SystemConfiguration.framework */; }; + 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 302D95EF14D2391D003F00A1 /* MainViewController.m */; }; + 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 302D95F014D2391D003F00A1 /* MainViewController.xib */; }; + 3053AC6F109B7857006FCFE7 /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 3053AC6E109B7857006FCFE7 /* VERSION */; }; + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */; }; + 3072F99713A8081B00425683 /* Capture.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 3072F99613A8081B00425683 /* Capture.bundle */; }; + 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */; }; + 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */; }; + 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */; }; + 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */; }; + 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */; }; + 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 3088BBBC154F3926009F9C59 /* Default~iphone.png */; }; + 308D05371370CCF300D202BF /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052E1370CCF300D202BF /* icon-72.png */; }; + 308D05381370CCF300D202BF /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052F1370CCF300D202BF /* icon.png */; }; + 308D05391370CCF300D202BF /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05301370CCF300D202BF /* icon@2x.png */; }; + 30A0434814DC770100060A13 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30A0434314DC770100060A13 /* Localizable.strings */; }; + 30A0434914DC770100060A13 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30A0434614DC770100060A13 /* Localizable.strings */; }; + 30E1352710E2C1420031B30D /* Cordova.plist in Resources */ = {isa = PBXBuildFile; fileRef = 30E1352610E2C1420031B30D /* Cordova.plist */; }; + 30E5649213A7FCAF007403D8 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30E5649113A7FCAF007403D8 /* CoreMedia.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + A93E85C516034FEE0004D29A /* WTWikitudePlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = A93E85C416034FEE0004D29A /* WTWikitudePlugin.m */; }; + A93E85F7160351690004D29A /* libQCAR.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E85E9160351690004D29A /* libQCAR.a */; }; + A93E85F8160351690004D29A /* libExtensionVuforia.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E85EE160351690004D29A /* libExtensionVuforia.a */; }; + A93E85F9160351690004D29A /* libWikitudeSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E85F4160351690004D29A /* libWikitudeSDK.a */; }; + A93E85FA1603516A0004D29A /* libWikitudeSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E85F6160351690004D29A /* libWikitudeSDK.a */; }; + A93E8601160352820004D29A /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E85FB160352820004D29A /* CoreMotion.framework */; }; + A93E8602160352820004D29A /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E85FC160352820004D29A /* CoreVideo.framework */; }; + A93E8603160352820004D29A /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E85FD160352820004D29A /* libsqlite3.dylib */; }; + A93E8604160352820004D29A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E85FE160352820004D29A /* libz.dylib */; }; + A93E8605160352820004D29A /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E85FF160352820004D29A /* OpenGLES.framework */; }; + A93E8606160352820004D29A /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E8600160352820004D29A /* Security.framework */; }; + A93E8608160352BE0004D29A /* assets in Resources */ = {isa = PBXBuildFile; fileRef = A93E8607160352BE0004D29A /* assets */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 301BF534109A57CC0062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC07E0554694100DB518D; + remoteInfo = CordovaLib; + }; + 301BF550109A68C00062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = CordovaLib; + }; + 302D95EB14D23909003F00A1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 686357A9141002F100DF4CF2; + remoteInfo = CordovaLibTests; + }; + 3088BBB4154F38EF009F9C59 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 303A4068152124BB00182201; + remoteInfo = CordovaLibApp; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* HelloImageRecognition.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloImageRecognition.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 1F766FDD13BBADB100FB74C0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = ""; }; + 1F766FE013BBADB100FB74C0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Localizable.strings; sourceTree = ""; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = CordovaLib.xcodeproj; sourceTree = CORDOVALIB; }; + 301BF56E109A69640062928A /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; path = www; sourceTree = SOURCE_ROOT; }; + 301BF5B4109A6A2B0062928A /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; }; + 301BF5B6109A6A2B0062928A /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; }; + 301BF5B8109A6A2B0062928A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 301BF5BA109A6A2B0062928A /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 301BF5BC109A6A2B0062928A /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 301BF5BE109A6A2B0062928A /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + 301BF5C0109A6A2B0062928A /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; + 301BF5C2109A6A2B0062928A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 301BF5C4109A6A2B0062928A /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 302D95EE14D2391D003F00A1 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 302D95EF14D2391D003F00A1 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + 302D95F014D2391D003F00A1 /* MainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainViewController.xib; sourceTree = ""; }; + 3053AC6E109B7857006FCFE7 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = CORDOVALIB; }; + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; + 3072F99613A8081B00425683 /* Capture.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Capture.bundle; sourceTree = ""; }; + 307D28A1123043350040C0FA /* CordovaBuildSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CordovaBuildSettings.xcconfig; path = ../CordovaBuildSettings.xcconfig; sourceTree = ""; }; + 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape@2x~ipad.png"; sourceTree = ""; }; + 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = ""; }; + 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = ""; }; + 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = ""; }; + 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x~iphone.png"; sourceTree = ""; }; + 3088BBBC154F3926009F9C59 /* Default~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default~iphone.png"; sourceTree = ""; }; + 308D052E1370CCF300D202BF /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72.png"; sourceTree = ""; }; + 308D052F1370CCF300D202BF /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; + 308D05301370CCF300D202BF /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = ""; }; + 30A0434414DC770100060A13 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Localizable.strings; sourceTree = ""; }; + 30A0434714DC770100060A13 /* se */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = se; path = Localizable.strings; sourceTree = ""; }; + 30E1352610E2C1420031B30D /* Cordova.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Cordova.plist; path = ../Cordova.plist; sourceTree = ""; }; + 30E5649113A7FCAF007403D8 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; + 32CA4F630368D1EE00C91783 /* HelloImageRecognition-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "HelloImageRecognition-Prefix.pch"; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* HelloImageRecognition-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "HelloImageRecognition-Info.plist"; path = "../HelloImageRecognition-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + A93E85C316034FEE0004D29A /* WTWikitudePlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTWikitudePlugin.h; sourceTree = ""; }; + A93E85C416034FEE0004D29A /* WTWikitudePlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WTWikitudePlugin.m; sourceTree = ""; }; + A93E85C9160351690004D29A /* Area.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Area.h; sourceTree = ""; }; + A93E85CA160351690004D29A /* CameraCalibration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CameraCalibration.h; sourceTree = ""; }; + A93E85CB160351690004D29A /* CameraDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CameraDevice.h; sourceTree = ""; }; + A93E85CC160351690004D29A /* DataSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSet.h; sourceTree = ""; }; + A93E85CD160351690004D29A /* Frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Frame.h; sourceTree = ""; }; + A93E85CE160351690004D29A /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = ""; }; + A93E85CF160351690004D29A /* ImageTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageTarget.h; sourceTree = ""; }; + A93E85D0160351690004D29A /* ImageTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageTracker.h; sourceTree = ""; }; + A93E85D1160351690004D29A /* Marker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Marker.h; sourceTree = ""; }; + A93E85D2160351690004D29A /* MarkerTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkerTracker.h; sourceTree = ""; }; + A93E85D3160351690004D29A /* Matrices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Matrices.h; sourceTree = ""; }; + A93E85D4160351690004D29A /* MultiTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultiTarget.h; sourceTree = ""; }; + A93E85D5160351690004D29A /* NonCopyable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NonCopyable.h; sourceTree = ""; }; + A93E85D6160351690004D29A /* QCAR.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QCAR.h; sourceTree = ""; }; + A93E85D7160351690004D29A /* QCAR_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QCAR_iOS.h; sourceTree = ""; }; + A93E85D8160351690004D29A /* Rectangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Rectangle.h; sourceTree = ""; }; + A93E85D9160351690004D29A /* Renderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Renderer.h; sourceTree = ""; }; + A93E85DA160351690004D29A /* State.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = State.h; sourceTree = ""; }; + A93E85DB160351690004D29A /* System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = System.h; sourceTree = ""; }; + A93E85DC160351690004D29A /* Tool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tool.h; sourceTree = ""; }; + A93E85DD160351690004D29A /* Trackable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Trackable.h; sourceTree = ""; }; + A93E85DE160351690004D29A /* Tracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tracker.h; sourceTree = ""; }; + A93E85DF160351690004D29A /* TrackerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackerManager.h; sourceTree = ""; }; + A93E85E0160351690004D29A /* UIGLViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIGLViewProtocol.h; sourceTree = ""; }; + A93E85E1160351690004D29A /* UpdateCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpdateCallback.h; sourceTree = ""; }; + A93E85E2160351690004D29A /* Vectors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vectors.h; sourceTree = ""; }; + A93E85E3160351690004D29A /* VideoBackgroundConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoBackgroundConfig.h; sourceTree = ""; }; + A93E85E4160351690004D29A /* VideoBackgroundTextureInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoBackgroundTextureInfo.h; sourceTree = ""; }; + A93E85E5160351690004D29A /* VideoMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoMode.h; sourceTree = ""; }; + A93E85E6160351690004D29A /* VirtualButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualButton.h; sourceTree = ""; }; + A93E85E9160351690004D29A /* libQCAR.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libQCAR.a; sourceTree = ""; }; + A93E85EE160351690004D29A /* libExtensionVuforia.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libExtensionVuforia.a; sourceTree = ""; }; + A93E85F1160351690004D29A /* WTArchitectView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTArchitectView.h; sourceTree = ""; }; + A93E85F4160351690004D29A /* libWikitudeSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWikitudeSDK.a; sourceTree = ""; }; + A93E85F6160351690004D29A /* libWikitudeSDK.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWikitudeSDK.a; sourceTree = ""; }; + A93E85FB160352820004D29A /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; + A93E85FC160352820004D29A /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; + A93E85FD160352820004D29A /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; + A93E85FE160352820004D29A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + A93E85FF160352820004D29A /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + A93E8600160352820004D29A /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; + A93E8607160352BE0004D29A /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A93E8601160352820004D29A /* CoreMotion.framework in Frameworks */, + A93E8602160352820004D29A /* CoreVideo.framework in Frameworks */, + A93E8603160352820004D29A /* libsqlite3.dylib in Frameworks */, + A93E8604160352820004D29A /* libz.dylib in Frameworks */, + A93E8605160352820004D29A /* OpenGLES.framework in Frameworks */, + A93E8606160352820004D29A /* Security.framework in Frameworks */, + 301BF552109A68D80062928A /* libCordova.a in Frameworks */, + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 301BF5B5109A6A2B0062928A /* AddressBook.framework in Frameworks */, + 301BF5B7109A6A2B0062928A /* AddressBookUI.framework in Frameworks */, + 301BF5B9109A6A2B0062928A /* AudioToolbox.framework in Frameworks */, + 301BF5BB109A6A2B0062928A /* AVFoundation.framework in Frameworks */, + 301BF5BD109A6A2B0062928A /* CFNetwork.framework in Frameworks */, + 301BF5BF109A6A2B0062928A /* CoreLocation.framework in Frameworks */, + 301BF5C1109A6A2B0062928A /* MediaPlayer.framework in Frameworks */, + 301BF5C3109A6A2B0062928A /* QuartzCore.framework in Frameworks */, + 301BF5C5109A6A2B0062928A /* SystemConfiguration.framework in Frameworks */, + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */, + 30E5649213A7FCAF007403D8 /* CoreMedia.framework in Frameworks */, + A93E85F7160351690004D29A /* libQCAR.a in Frameworks */, + A93E85F8160351690004D29A /* libExtensionVuforia.a in Frameworks */, + A93E85F9160351690004D29A /* libWikitudeSDK.a in Frameworks */, + A93E85FA1603516A0004D29A /* libWikitudeSDK.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 302D95EE14D2391D003F00A1 /* MainViewController.h */, + 302D95EF14D2391D003F00A1 /* MainViewController.m */, + 302D95F014D2391D003F00A1 /* MainViewController.xib */, + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + ); + name = Classes; + path = HelloImageRecognition/Classes; + sourceTree = SOURCE_ROOT; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* HelloImageRecognition.app */, + ); + name = Products; + sourceTree = ""; + }; + 1F766FDB13BBADB100FB74C0 /* en.lproj */ = { + isa = PBXGroup; + children = ( + 1F766FDC13BBADB100FB74C0 /* Localizable.strings */, + ); + path = en.lproj; + sourceTree = ""; + }; + 1F766FDE13BBADB100FB74C0 /* es.lproj */ = { + isa = PBXGroup; + children = ( + 1F766FDF13BBADB100FB74C0 /* Localizable.strings */, + ); + path = es.lproj; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + A93E8607160352BE0004D29A /* assets */, + 301BF56E109A69640062928A /* www */, + 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */, + A93E85C6160351690004D29A /* Vuforia */, + A93E85EA160351690004D29A /* WikitudeSDK */, + 080E96DDFE201D6D7F000001 /* Classes */, + 307C750510C5A3420062BCA9 /* Plugins */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* HelloImageRecognition-Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + path = HelloImageRecognition; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 30A0434214DC770100060A13 /* de.lproj */, + 30A0434514DC770100060A13 /* se.lproj */, + 1F766FDB13BBADB100FB74C0 /* en.lproj */, + 1F766FDE13BBADB100FB74C0 /* es.lproj */, + 3072F99613A8081B00425683 /* Capture.bundle */, + 308D052D1370CCF300D202BF /* icons */, + 308D05311370CCF300D202BF /* splash */, + 30E1352610E2C1420031B30D /* Cordova.plist */, + 3053AC6E109B7857006FCFE7 /* VERSION */, + 8D1107310486CEB800E47090 /* HelloImageRecognition-Info.plist */, + 307D28A1123043350040C0FA /* CordovaBuildSettings.xcconfig */, + ); + name = Resources; + path = HelloImageRecognition/Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + A93E85FB160352820004D29A /* CoreMotion.framework */, + A93E85FC160352820004D29A /* CoreVideo.framework */, + A93E85FD160352820004D29A /* libsqlite3.dylib */, + A93E85FE160352820004D29A /* libz.dylib */, + A93E85FF160352820004D29A /* OpenGLES.framework */, + A93E8600160352820004D29A /* Security.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + 301BF5B4109A6A2B0062928A /* AddressBook.framework */, + 301BF5B6109A6A2B0062928A /* AddressBookUI.framework */, + 301BF5B8109A6A2B0062928A /* AudioToolbox.framework */, + 301BF5BA109A6A2B0062928A /* AVFoundation.framework */, + 301BF5BC109A6A2B0062928A /* CFNetwork.framework */, + 301BF5BE109A6A2B0062928A /* CoreLocation.framework */, + 301BF5C0109A6A2B0062928A /* MediaPlayer.framework */, + 301BF5C2109A6A2B0062928A /* QuartzCore.framework */, + 301BF5C4109A6A2B0062928A /* SystemConfiguration.framework */, + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */, + 30E5649113A7FCAF007403D8 /* CoreMedia.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 301BF52E109A57CC0062928A /* Products */ = { + isa = PBXGroup; + children = ( + 301BF535109A57CC0062928A /* libCordova.a */, + 302D95EC14D23909003F00A1 /* CordovaLibTests.octest */, + 3088BBB5154F38EF009F9C59 /* CordovaLibApp.app */, + ); + name = Products; + sourceTree = ""; + }; + 307C750510C5A3420062BCA9 /* Plugins */ = { + isa = PBXGroup; + children = ( + A93E85C216034FEE0004D29A /* Wikitude */, + ); + name = Plugins; + path = HelloImageRecognition/Plugins; + sourceTree = SOURCE_ROOT; + }; + 308D052D1370CCF300D202BF /* icons */ = { + isa = PBXGroup; + children = ( + 308D052E1370CCF300D202BF /* icon-72.png */, + 308D052F1370CCF300D202BF /* icon.png */, + 308D05301370CCF300D202BF /* icon@2x.png */, + ); + path = icons; + sourceTree = ""; + }; + 308D05311370CCF300D202BF /* splash */ = { + isa = PBXGroup; + children = ( + 3088BBB7154F3926009F9C59 /* Default-Landscape@2x~ipad.png */, + 3088BBB8154F3926009F9C59 /* Default-Landscape~ipad.png */, + 3088BBB9154F3926009F9C59 /* Default-Portrait@2x~ipad.png */, + 3088BBBA154F3926009F9C59 /* Default-Portrait~ipad.png */, + 3088BBBB154F3926009F9C59 /* Default@2x~iphone.png */, + 3088BBBC154F3926009F9C59 /* Default~iphone.png */, + ); + path = splash; + sourceTree = ""; + }; + 30A0434214DC770100060A13 /* de.lproj */ = { + isa = PBXGroup; + children = ( + 30A0434314DC770100060A13 /* Localizable.strings */, + ); + path = de.lproj; + sourceTree = ""; + }; + 30A0434514DC770100060A13 /* se.lproj */ = { + isa = PBXGroup; + children = ( + 30A0434614DC770100060A13 /* Localizable.strings */, + ); + path = se.lproj; + sourceTree = ""; + }; + A93E85C216034FEE0004D29A /* Wikitude */ = { + isa = PBXGroup; + children = ( + A93E85C316034FEE0004D29A /* WTWikitudePlugin.h */, + A93E85C416034FEE0004D29A /* WTWikitudePlugin.m */, + ); + path = Wikitude; + sourceTree = ""; + }; + A93E85C6160351690004D29A /* Vuforia */ = { + isa = PBXGroup; + children = ( + A93E85C7160351690004D29A /* include */, + A93E85E7160351690004D29A /* lib */, + ); + name = Vuforia; + path = HelloImageRecognition/Vuforia; + sourceTree = ""; + }; + A93E85C7160351690004D29A /* include */ = { + isa = PBXGroup; + children = ( + A93E85C8160351690004D29A /* QCAR */, + ); + path = include; + sourceTree = ""; + }; + A93E85C8160351690004D29A /* QCAR */ = { + isa = PBXGroup; + children = ( + A93E85C9160351690004D29A /* Area.h */, + A93E85CA160351690004D29A /* CameraCalibration.h */, + A93E85CB160351690004D29A /* CameraDevice.h */, + A93E85CC160351690004D29A /* DataSet.h */, + A93E85CD160351690004D29A /* Frame.h */, + A93E85CE160351690004D29A /* Image.h */, + A93E85CF160351690004D29A /* ImageTarget.h */, + A93E85D0160351690004D29A /* ImageTracker.h */, + A93E85D1160351690004D29A /* Marker.h */, + A93E85D2160351690004D29A /* MarkerTracker.h */, + A93E85D3160351690004D29A /* Matrices.h */, + A93E85D4160351690004D29A /* MultiTarget.h */, + A93E85D5160351690004D29A /* NonCopyable.h */, + A93E85D6160351690004D29A /* QCAR.h */, + A93E85D7160351690004D29A /* QCAR_iOS.h */, + A93E85D8160351690004D29A /* Rectangle.h */, + A93E85D9160351690004D29A /* Renderer.h */, + A93E85DA160351690004D29A /* State.h */, + A93E85DB160351690004D29A /* System.h */, + A93E85DC160351690004D29A /* Tool.h */, + A93E85DD160351690004D29A /* Trackable.h */, + A93E85DE160351690004D29A /* Tracker.h */, + A93E85DF160351690004D29A /* TrackerManager.h */, + A93E85E0160351690004D29A /* UIGLViewProtocol.h */, + A93E85E1160351690004D29A /* UpdateCallback.h */, + A93E85E2160351690004D29A /* Vectors.h */, + A93E85E3160351690004D29A /* VideoBackgroundConfig.h */, + A93E85E4160351690004D29A /* VideoBackgroundTextureInfo.h */, + A93E85E5160351690004D29A /* VideoMode.h */, + A93E85E6160351690004D29A /* VirtualButton.h */, + ); + path = QCAR; + sourceTree = ""; + }; + A93E85E7160351690004D29A /* lib */ = { + isa = PBXGroup; + children = ( + A93E85E8160351690004D29A /* arm */, + ); + path = lib; + sourceTree = ""; + }; + A93E85E8160351690004D29A /* arm */ = { + isa = PBXGroup; + children = ( + A93E85E9160351690004D29A /* libQCAR.a */, + ); + path = arm; + sourceTree = ""; + }; + A93E85EA160351690004D29A /* WikitudeSDK */ = { + isa = PBXGroup; + children = ( + A93E85EB160351690004D29A /* Extensions */, + A93E85EF160351690004D29A /* SDK */, + ); + name = WikitudeSDK; + path = HelloImageRecognition/WikitudeSDK; + sourceTree = ""; + }; + A93E85EB160351690004D29A /* Extensions */ = { + isa = PBXGroup; + children = ( + A93E85EC160351690004D29A /* VuforiaExtension */, + ); + path = Extensions; + sourceTree = ""; + }; + A93E85EC160351690004D29A /* VuforiaExtension */ = { + isa = PBXGroup; + children = ( + A93E85ED160351690004D29A /* lib */, + ); + path = VuforiaExtension; + sourceTree = ""; + }; + A93E85ED160351690004D29A /* lib */ = { + isa = PBXGroup; + children = ( + A93E85EE160351690004D29A /* libExtensionVuforia.a */, + ); + path = lib; + sourceTree = ""; + }; + A93E85EF160351690004D29A /* SDK */ = { + isa = PBXGroup; + children = ( + A93E85F0160351690004D29A /* inc */, + A93E85F2160351690004D29A /* lib */, + ); + path = SDK; + sourceTree = ""; + }; + A93E85F0160351690004D29A /* inc */ = { + isa = PBXGroup; + children = ( + A93E85F1160351690004D29A /* WTArchitectView.h */, + ); + path = inc; + sourceTree = ""; + }; + A93E85F2160351690004D29A /* lib */ = { + isa = PBXGroup; + children = ( + A93E85F3160351690004D29A /* Release-iphoneos */, + A93E85F5160351690004D29A /* Release-iphonesimulator */, + ); + path = lib; + sourceTree = ""; + }; + A93E85F3160351690004D29A /* Release-iphoneos */ = { + isa = PBXGroup; + children = ( + A93E85F4160351690004D29A /* libWikitudeSDK.a */, + ); + path = "Release-iphoneos"; + sourceTree = ""; + }; + A93E85F5160351690004D29A /* Release-iphonesimulator */ = { + isa = PBXGroup; + children = ( + A93E85F6160351690004D29A /* libWikitudeSDK.a */, + ); + path = "Release-iphonesimulator"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* HelloImageRecognition */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloImageRecognition" */; + buildPhases = ( + 304B58A110DAC018002A0835 /* Touch www folder */, + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 301BF551109A68C00062928A /* PBXTargetDependency */, + ); + name = HelloImageRecognition; + productName = HelloImageRecognition; + productReference = 1D6058910D05DD3D006BFB54 /* HelloImageRecognition.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0420; + }; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HelloImageRecognition" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + es, + de, + se, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 301BF52E109A57CC0062928A /* Products */; + ProjectRef = 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* HelloImageRecognition */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 301BF535109A57CC0062928A /* libCordova.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libCordova.a; + remoteRef = 301BF534109A57CC0062928A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 302D95EC14D23909003F00A1 /* CordovaLibTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CordovaLibTests.octest; + remoteRef = 302D95EB14D23909003F00A1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 3088BBB5154F38EF009F9C59 /* CordovaLibApp.app */ = { + isa = PBXReferenceProxy; + fileType = wrapper.application; + path = CordovaLibApp.app; + remoteRef = 3088BBB4154F38EF009F9C59 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 301BF570109A69640062928A /* www in Resources */, + 3053AC6F109B7857006FCFE7 /* VERSION in Resources */, + 30E1352710E2C1420031B30D /* Cordova.plist in Resources */, + 308D05371370CCF300D202BF /* icon-72.png in Resources */, + 308D05381370CCF300D202BF /* icon.png in Resources */, + 308D05391370CCF300D202BF /* icon@2x.png in Resources */, + 3072F99713A8081B00425683 /* Capture.bundle in Resources */, + 1F766FE113BBADB100FB74C0 /* Localizable.strings in Resources */, + 1F766FE213BBADB100FB74C0 /* Localizable.strings in Resources */, + 302D95F214D2391D003F00A1 /* MainViewController.xib in Resources */, + 30A0434814DC770100060A13 /* Localizable.strings in Resources */, + 30A0434914DC770100060A13 /* Localizable.strings in Resources */, + 3088BBBD154F3926009F9C59 /* Default-Landscape@2x~ipad.png in Resources */, + 3088BBBE154F3926009F9C59 /* Default-Landscape~ipad.png in Resources */, + 3088BBBF154F3926009F9C59 /* Default-Portrait@2x~ipad.png in Resources */, + 3088BBC0154F3926009F9C59 /* Default-Portrait~ipad.png in Resources */, + 3088BBC1154F3926009F9C59 /* Default@2x~iphone.png in Resources */, + 3088BBC2154F3926009F9C59 /* Default~iphone.png in Resources */, + A93E8608160352BE0004D29A /* assets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 304B58A110DAC018002A0835 /* Touch www folder */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Touch www folder"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "touch -cm ${PROJECT_DIR}/www"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 302D95F114D2391D003F00A1 /* MainViewController.m in Sources */, + A93E85C516034FEE0004D29A /* WTWikitudePlugin.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 301BF551109A68C00062928A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = CordovaLib; + targetProxy = 301BF550109A68C00062928A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 1F766FDC13BBADB100FB74C0 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 1F766FDD13BBADB100FB74C0 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 1F766FDF13BBADB100FB74C0 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 1F766FE013BBADB100FB74C0 /* es */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 30A0434314DC770100060A13 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 30A0434414DC770100060A13 /* de */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 30A0434614DC770100060A13 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 30A0434714DC770100060A13 /* se */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "HelloImageRecognition/HelloImageRecognition-Prefix.pch"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "HelloImageRecognition/HelloImageRecognition-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 4.2; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/HelloImageRecognition/Vuforia/lib/arm\"", + "\"$(SRCROOT)/HelloImageRecognition/WikitudeSDK/Extensions/VuforiaExtension/lib\"", + "\"$(SRCROOT)/HelloImageRecognition/WikitudeSDK/SDK/lib/Release$(EFFECTIVE_PLATFORM_NAME)\"", + ); + PRODUCT_NAME = HelloImageRecognition; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "HelloImageRecognition/HelloImageRecognition-Prefix.pch"; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_FILE = "HelloImageRecognition/HelloImageRecognition-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 4.2; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/HelloImageRecognition/Vuforia/lib/arm\"", + "\"$(SRCROOT)/HelloImageRecognition/WikitudeSDK/Extensions/VuforiaExtension/lib\"", + "\"$(SRCROOT)/HelloImageRecognition/WikitudeSDK/SDK/lib/Release$(EFFECTIVE_PLATFORM_NAME)\"", + ); + PRODUCT_NAME = HelloImageRecognition; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 307D28A1123043350040C0FA /* CordovaBuildSettings.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", + ); + IPHONEOS_DEPLOYMENT_TARGET = 4.2; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-force_load", + "$(BUILT_PRODUCTS_DIR)/libCordova.a", + "-ObjC", + "-lstdc++", + ); + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 307D28A1123043350040C0FA /* CordovaBuildSettings.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", + "\"$(OBJROOT)/UninstalledProducts/include\"", + "\"$(BUILT_PRODUCTS_DIR)\"", + ); + IPHONEOS_DEPLOYMENT_TARGET = 4.2; + OTHER_LDFLAGS = ( + "-weak_framework", + CoreFoundation, + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak-lSystem", + "-force_load", + "$(BUILT_PRODUCTS_DIR)/libCordova.a", + "-ObjC", + "-lstdc++", + ); + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "HelloImageRecognition" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "HelloImageRecognition" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..5ee0a53 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/project.xcworkspace/xcuserdata/Andi.xcuserdatad/UserInterfaceState.xcuserstate b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/project.xcworkspace/xcuserdata/Andi.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..348184b Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/project.xcworkspace/xcuserdata/Andi.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/HelloImageRecognition.xcscheme b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/HelloImageRecognition.xcscheme new file mode 100644 index 0000000..363f631 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/HelloImageRecognition.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/xcschememanagement.plist b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..b074716 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition.xcodeproj/xcuserdata/Andi.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + HelloImageRecognition.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 1D6058900D05DD3D006BFB54 + + primary + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/.gitignore b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/.gitignore new file mode 100644 index 0000000..d30c0b0 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/.gitignore @@ -0,0 +1,6 @@ +*.mode1v3 +*.perspectivev3 +*.pbxuser +.DS_Store +build +www/phonegap.js diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/AppDelegate.h b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/AppDelegate.h new file mode 100644 index 0000000..6f0c82f --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/AppDelegate.h @@ -0,0 +1,45 @@ +/* + 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. + */ + +// +// AppDelegate.h +// HelloImageRecognition +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import + +#import + +@interface AppDelegate : NSObject < UIApplicationDelegate > { + +} + +// invoke string is passed to your app on launch, this is only valid if you +// edit HelloImageRecognition-Info.plist to add a protocol +// a simple tutorial can be found here : +// http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html + +@property (nonatomic, retain) IBOutlet UIWindow* window; +@property (nonatomic, retain) IBOutlet CDVViewController* viewController; + +@end + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/AppDelegate.m b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/AppDelegate.m new file mode 100644 index 0000000..0cfe1fd --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/AppDelegate.m @@ -0,0 +1,135 @@ +/* + 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. + */ + +// +// AppDelegate.m +// HelloImageRecognition +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "AppDelegate.h" +#import "MainViewController.h" + +#import +#import + + +@implementation AppDelegate + +@synthesize window, viewController; + +- (id) init +{ + /** If you need to do any extra app-specific initialization, you can do it here + * -jm + **/ + NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + [cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; + + [CDVURLProtocol registerURLProtocol]; + + return [super init]; +} + +#pragma UIApplicationDelegate implementation + +/** + * This is main kick off after the app inits, the views and Settings are setup here. (preferred - iOS4 and up) + */ +- (BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions +{ + NSURL* url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey]; + NSString* invokeString = nil; + + if (url && [url isKindOfClass:[NSURL class]]) { + invokeString = [url absoluteString]; + NSLog(@"HelloImageRecognition launchOptions = %@", url); + } + + CGRect screenBounds = [[UIScreen mainScreen] bounds]; + self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease]; + self.window.autoresizesSubviews = YES; + + CGRect viewBounds = [[UIScreen mainScreen] applicationFrame]; + + self.viewController = [[[MainViewController alloc] init] autorelease]; + self.viewController.useSplashScreen = YES; + self.viewController.wwwFolderName = @"www"; + self.viewController.startPage = @"index.html"; + self.viewController.invokeString = invokeString; + self.viewController.view.frame = viewBounds; + + // check whether the current orientation is supported: if it is, keep it, rather than forcing a rotation + BOOL forceStartupRotation = YES; + UIDeviceOrientation curDevOrientation = [[UIDevice currentDevice] orientation]; + + if (UIDeviceOrientationUnknown == curDevOrientation) { + // UIDevice isn't firing orientation notifications yet… go look at the status bar + curDevOrientation = (UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation]; + } + + if (UIDeviceOrientationIsValidInterfaceOrientation(curDevOrientation)) { + for (NSNumber *orient in self.viewController.supportedOrientations) { + if ([orient intValue] == curDevOrientation) { + forceStartupRotation = NO; + break; + } + } + } + + if (forceStartupRotation) { + NSLog(@"supportedOrientations: %@", self.viewController.supportedOrientations); + // The first item in the supportedOrientations array is the start orientation (guaranteed to be at least Portrait) + UIInterfaceOrientation newOrient = [[self.viewController.supportedOrientations objectAtIndex:0] intValue]; + NSLog(@"AppDelegate forcing status bar to: %d from: %d", newOrient, curDevOrientation); + [[UIApplication sharedApplication] setStatusBarOrientation:newOrient]; + } + + [self.window addSubview:self.viewController.view]; + [self.window makeKeyAndVisible]; + + return YES; +} + +// this happens while we are running ( in the background, or from within our own app ) +// only valid if HelloImageRecognition-Info.plist specifies a protocol to handle +- (BOOL) application:(UIApplication*)application handleOpenURL:(NSURL*)url +{ + if (!url) { + return NO; + } + + // calls into javascript global function 'handleOpenURL' + NSString* jsString = [NSString stringWithFormat:@"handleOpenURL(\"%@\");", url]; + [self.viewController.webView stringByEvaluatingJavaScriptFromString:jsString]; + + // all plugins will get the notification, and their handlers will be called + [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]]; + + return YES; +} + +- (void) dealloc +{ + [super dealloc]; +} + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/MainViewController.h b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/MainViewController.h new file mode 100644 index 0000000..d7bebc1 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/MainViewController.h @@ -0,0 +1,32 @@ +/* + 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. + */ + +// +// MainViewController.h +// HelloImageRecognition +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import + +@interface MainViewController : CDVViewController + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/MainViewController.m b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/MainViewController.m new file mode 100644 index 0000000..64c9bcb --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/MainViewController.m @@ -0,0 +1,141 @@ +/* + 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. + */ + +// +// MainViewController.h +// HelloImageRecognition +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import "MainViewController.h" + +@implementation MainViewController + +- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return self; +} + +- (void) didReceiveMemoryWarning +{ + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + +#pragma mark - View lifecycle + +- (void) viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view from its nib. +} + +- (void) viewDidUnload +{ + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + +- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + // Return YES for supported orientations + return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation]; +} + +/* Comment out the block below to over-ride */ +/* +- (CDVCordovaView*) newCordovaViewWithFrame:(CGRect)bounds +{ + return[super newCordovaViewWithFrame:bounds]; +} +*/ + +/* Comment out the block below to over-ride */ +/* +#pragma CDVCommandDelegate implementation + +- (id) getCommandInstance:(NSString*)className +{ + return [super getCommandInstance:className]; +} + +- (BOOL) execute:(CDVInvokedUrlCommand*)command +{ + return [super execute:command]; +} + +- (NSString*) pathForResource:(NSString*)resourcepath; +{ + return [super pathForResource:resourcepath]; +} + +- (void) registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className +{ + return [super registerPlugin:plugin withClassName:className]; +} +*/ + +#pragma UIWebDelegate implementation + +- (void) webViewDidFinishLoad:(UIWebView*) theWebView +{ + // only valid if ___PROJECTNAME__-Info.plist specifies a protocol to handle + if (self.invokeString) + { + // this is passed before the deviceready event is fired, so you can access it in js when you receive deviceready + NSLog(@"DEPRECATED: window.invokeString - use the window.handleOpenURL(url) function instead, which is always called when the app is launched through a custom scheme url."); + NSString* jsString = [NSString stringWithFormat:@"var invokeString = \"%@\";", self.invokeString]; + [theWebView stringByEvaluatingJavaScriptFromString:jsString]; + } + + // Black base color for background matches the native apps + theWebView.backgroundColor = [UIColor blackColor]; + + return [super webViewDidFinishLoad:theWebView]; +} + +/* Comment out the block below to over-ride */ +/* + +- (void) webViewDidStartLoad:(UIWebView*)theWebView +{ + return [super webViewDidStartLoad:theWebView]; +} + +- (void) webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error +{ + return [super webView:theWebView didFailLoadWithError:error]; +} + +- (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType +{ + return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType]; +} +*/ + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/MainViewController.xib b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/MainViewController.xib new file mode 100644 index 0000000..e45d65c --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Classes/MainViewController.xib @@ -0,0 +1,138 @@ + + + + + 1280 + 11C25 + 1919 + 1138.11 + 566.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 916 + + + IBProxyObject + IBUIView + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBCocoaTouchFramework + + + IBFirstResponder + IBCocoaTouchFramework + + + + 274 + {{0, 20}, {320, 460}} + + + + 3 + MQA + + 2 + + + + IBCocoaTouchFramework + + + + + + + view + + + + 3 + + + + + + 0 + + + + + + 1 + + + + + -1 + + + File's Owner + + + -2 + + + + + + + MainViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 3 + + + + + MainViewController + UIViewController + + IBProjectSource + ./Classes/MainViewController.h + + + + + 0 + IBCocoaTouchFramework + YES + 3 + 916 + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Cordova.plist b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Cordova.plist new file mode 100644 index 0000000..01a59d6 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Cordova.plist @@ -0,0 +1,67 @@ + + + + + UIWebViewBounce + + TopActivityIndicator + gray + EnableLocation + + EnableViewportScale + + AutoHideSplashScreen + + ShowSplashScreenSpinner + + MediaPlaybackRequiresUserAction + + AllowInlineMediaPlayback + + OpenAllWhitelistURLsInWebView + + BackupWebStorage + + ExternalHosts + + * + + Plugins + + WikitudePlugin + WTWikitudePlugin + Device + CDVDevice + Logger + CDVLogger + Compass + CDVLocation + Accelerometer + CDVAccelerometer + Camera + CDVCamera + NetworkStatus + CDVConnection + Contacts + CDVContacts + Debug Console + CDVDebugConsole + File + CDVFile + FileTransfer + CDVFileTransfer + Geolocation + CDVLocation + Notification + CDVNotification + Media + CDVSound + Capture + CDVCapture + SplashScreen + CDVSplashScreen + Battery + CDVBattery + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/CordovaBuildSettings.xcconfig b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/CordovaBuildSettings.xcconfig new file mode 100644 index 0000000..c70086c --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/CordovaBuildSettings.xcconfig @@ -0,0 +1,26 @@ +// +// 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. +// + +// Cordova.xcconfig +// __TESTING__ +// + +// Override this to use your project specific CORDOVALIB. +// You can base it off the current project path, $(PROJECT_DIR) +CORDOVALIB = $(CORDOVALIB) diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/HelloImageRecognition-Info.plist b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/HelloImageRecognition-Info.plist new file mode 100644 index 0000000..1f62951 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/HelloImageRecognition-Info.plist @@ -0,0 +1,58 @@ + + + + + CFBundleIcons + + CFBundlePrimaryIcon + + CFBundleIconFiles + + icon.png + icon@2x.png + icon-72.png + icon-72@2x.png + + UIPrerenderedIcon + + + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + icon.png + CFBundleIdentifier + com.wikitude.phonegapsamplehelloimagerecognition + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + + NSMainNibFile~ipad + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/HelloImageRecognition-Prefix.pch b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/HelloImageRecognition-Prefix.pch new file mode 100644 index 0000000..b4aef82 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/HelloImageRecognition-Prefix.pch @@ -0,0 +1,26 @@ +/* + 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. + */ +// +// Prefix header for all source files of the 'HelloImageRecognition' target in the 'HelloImageRecognition' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Plugins/README b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Plugins/README new file mode 100644 index 0000000..f6e19d7 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Plugins/README @@ -0,0 +1,20 @@ +# +# 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. +# + +Put the .h and .m files of your plugin here. The .js files of your plugin belong in the www folder. \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Plugins/Wikitude/WTWikitudePlugin.h b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Plugins/Wikitude/WTWikitudePlugin.h new file mode 100644 index 0000000..0a71316 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Plugins/Wikitude/WTWikitudePlugin.h @@ -0,0 +1,14 @@ +// +// WTWikitudeSDK.h +// HelloWorld +// +// Created by Andreas Schacherbauer on 8/24/12. +// +// + + +#import + +@interface WTWikitudePlugin : CDVPlugin + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Plugins/Wikitude/WTWikitudePlugin.m b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Plugins/Wikitude/WTWikitudePlugin.m new file mode 100644 index 0000000..3e54f35 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Plugins/Wikitude/WTWikitudePlugin.m @@ -0,0 +1,402 @@ +// +// WTWikitudeSDK.m +// HelloWorld +// +// Created by Andreas Schacherbauer on 8/24/12. +// +// + +#import "WTWikitudePlugin.h" + +// Wikitude SDK +#import "WTArchitectView.h" + + + + +@interface WTWikitudePlugin () + +@property (nonatomic, strong) WTArchitectView *architectView; + +@property (nonatomic, strong) NSString *currentARchitectViewCallbackID; +@property (nonatomic, strong) NSString *currentPlugInErrorCallback; + +@property (nonatomic, assign) BOOL isUsingInjectedLocation; + +@end + + +@implementation WTWikitudePlugin +@synthesize architectView=_architectView; + + +#pragma mark - View Lifecycle +/* View Lifecycle */ +- (void)isDeviceSupported:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + BOOL isDeviceSupported = [WTArchitectView isDeviceSupported]; + + if (isDeviceSupported) { + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:isDeviceSupported]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + } else { + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:isDeviceSupported]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + + +- (void)open:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { +// NSString* echo = [arguments objectAtIndex:1]; + + + BOOL success = [WTArchitectView isDeviceSupported]; + if ( success ) { + + NSString *sdkKey = [options objectForKey:@"apiKey"]; + NSString *architectWorldFilePath = [options objectForKey:@"filePath"]; + + // First, lets check if we need to init a new sdk view + if ( !_architectView ) { + self.architectView = [[WTArchitectView alloc] initWithFrame:self.viewController.view.bounds]; + self.architectView.delegate = self; + [self.architectView initializeWithKey:sdkKey motionManager:nil]; + } + + // then add the view in its own navController to the ui. we need a own navController to have a backButton which can be used to dismiss the view + UIViewController *viewController = [[UIViewController alloc] init]; + viewController.view = self.architectView; + + UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; + navController.navigationBar.tintColor = [UIColor blackColor]; + navController.navigationBar.topItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissARchitectView)]; + [self.viewController presentViewController:navController animated:NO completion:^{ + // completion code + }]; + + + + // and finaly load the architect world, specified in the open function in js + if (architectWorldFilePath) { + + NSString *worldName = [architectWorldFilePath lastPathComponent]; + worldName = [worldName stringByDeletingPathExtension]; + NSString *worldNameExtension = [architectWorldFilePath pathExtension]; + + NSString *architectWorldDirectoryPath = [architectWorldFilePath stringByDeletingLastPathComponent]; + + NSString *loadablePath = [[NSBundle mainBundle] pathForResource:worldName ofType:worldNameExtension inDirectory:architectWorldDirectoryPath]; + [self.architectView loadArchitectWorldFromUrl:loadablePath]; + } + } + + // start the sdk view updates + [self.architectView start]; + + + if ( success ) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } else { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)close:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { +// NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + + [self.architectView stop]; +// [self.architectView removeFromSuperview]; + } + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)show:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { +// NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + self.architectView.hidden = NO; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)hide:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + self.architectView.hidden = YES; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)onResume:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + [self.architectView start]; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +- (void)onPause:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + [self.architectView stop]; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +#pragma mark - Location Handling + +- (void)setLocation:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + // NSString* echo = [arguments objectAtIndex:1]; + + if (self.architectView) { + + float latitude = [[options objectForKey:@"lat"] floatValue]; + float longitude = [[options objectForKey:@"lon"] floatValue]; + float altitude = [[options objectForKey:@"alt"] floatValue]; + float accuracy = [[options objectForKey:@"acc"] floatValue]; + + if (!self.isUsingInjectedLocation) { + [self.architectView setUseInjectedLocation:YES]; + self.isUsingInjectedLocation = YES; + } + + [self.architectView injectLocationWithLatitude:latitude longitude:longitude altitude:altitude accuracy:accuracy]; + } + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + + +#pragma mark - Javascript + +- (void)callJavascript:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + + @try { + + if (arguments.count >= 1) { + + NSMutableString *javascriptToCall = [[arguments objectAtIndex:1] mutableCopy]; + for (NSUInteger i = 2; i < arguments.count; i++) { + [javascriptToCall appendString:[arguments objectAtIndex:i]]; + } + + if (self.architectView) { + [self.architectView callJavaScript:javascriptToCall]; + } + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:nil]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + }else + { + // return error no javascript to call found + } + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + + +- (void)onUrlInvoke:(NSMutableArray *)arguments withDict:(NSMutableDictionary *)options +{ + NSString* callbackId = [arguments objectAtIndex:0]; + + CDVPluginResult* pluginResult = nil; + NSString* javaScript = nil; + + @try { + + + self.currentARchitectViewCallbackID = callbackId; + self.currentPlugInErrorCallback = callbackId; + + + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT]; + [pluginResult setKeepCallbackAsBool:YES]; + javaScript = [pluginResult toSuccessCallbackString:callbackId]; + + + } @catch (NSException* exception) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION messageAsString:[exception reason]]; + javaScript = [pluginResult toErrorCallbackString:callbackId]; + } + + [self writeJavascript:javaScript]; +} + +#pragma mark - WTArchitectView Delegate +- (void)urlWasInvoked:(NSString *)url +{ + + CDVPluginResult *pluginResult = nil; + NSString *javaScriptResult = nil; + + + if (url && self.currentARchitectViewCallbackID) { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:url]; + [pluginResult setKeepCallbackAsBool:YES]; + javaScriptResult = [pluginResult toSuccessCallbackString:self.currentARchitectViewCallbackID]; + + + }else + { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; + javaScriptResult = [pluginResult toSuccessCallbackString:self.currentPlugInErrorCallback]; + } + + [self writeJavascript:javaScriptResult]; +} + +- (void)dismissARchitectView +{ + [self.viewController dismissModalViewControllerAnimated:NO]; + [self.architectView stop]; +} + +@end diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg.png new file mode 100644 index 0000000..784e9c7 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg@2x.png new file mode 100644 index 0000000..1e28c6d Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg@2x~ipad.png new file mode 100644 index 0000000..d4e3483 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg~ipad.png new file mode 100644 index 0000000..efbef8a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/controls_bg~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone.png new file mode 100644 index 0000000..155b88c Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone@2x.png new file mode 100644 index 0000000..79ef16b Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone@2x~ipad.png new file mode 100644 index 0000000..af1bbb2 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone~ipad.png new file mode 100644 index 0000000..ef1c472 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/microphone~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button.png new file mode 100644 index 0000000..ceb9589 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button@2x.png new file mode 100644 index 0000000..d6ce302 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button@2x~ipad.png new file mode 100644 index 0000000..0ac2e67 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button~ipad.png new file mode 100644 index 0000000..d8e24a4 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/record_button~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg.png new file mode 100644 index 0000000..bafc087 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg@2x.png new file mode 100644 index 0000000..798490b Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg@2x~ipad.png new file mode 100644 index 0000000..a1b7208 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg~ipad.png new file mode 100644 index 0000000..3b467f6 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/recording_bg~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button.png new file mode 100644 index 0000000..9c31838 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button@2x.png new file mode 100644 index 0000000..8cf657e Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button@2x~ipad.png new file mode 100644 index 0000000..88b606c Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button~ipad.png new file mode 100644 index 0000000..59bb7a5 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/Capture.bundle/stop_button~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/de.lproj/Localizable.strings b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/de.lproj/Localizable.strings new file mode 100644 index 0000000..f1cdb42 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/de.lproj/Localizable.strings @@ -0,0 +1,26 @@ +/* + 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. + */ + + +// accessibility label for recording button +"toggle audio recording" = "starten/beenden der Tonaufnahme"; +// notification spoken by VoiceOver when timed recording finishes +"timed recording complete" = "programmierte Aufnahme beendet"; +// accessibility hint for display of recorded elapsed time +"recorded time in minutes and seconds" = "aufgenommene Zeit in Minuten und Sekunden"; \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/en.lproj/Localizable.strings b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/en.lproj/Localizable.strings new file mode 100644 index 0000000..8972684 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/en.lproj/Localizable.strings @@ -0,0 +1,25 @@ +/* + 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. + */ + +// accessibility label for recording button +"toggle audio recording" = "toggle audio recording"; +// notification spoken by VoiceOver when timed recording finishes +"timed recording complete" = "timed recording complete"; +// accessibility hint for display of recorded elapsed time +"recorded time in minutes and seconds" = "recorded time in minutes and seconds"; \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/es.lproj/Localizable.strings b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/es.lproj/Localizable.strings new file mode 100644 index 0000000..23831e6 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/es.lproj/Localizable.strings @@ -0,0 +1,25 @@ +/* + 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. + */ + +// accessibility label for recording button +"toggle audio recording" = "grabación de audio cambiar"; +// notification spoken by VoiceOver when timed recording finishes +"timed recording complete" = "tiempo de grabación completo"; +// accessibility hint for display of recorded elapsed time +"recorded time in minutes and seconds" = "tiempo registrado en minutos y segundos"; \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon-72.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon-72.png new file mode 100644 index 0000000..8c6e5df Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon-72.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon-72@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon-72@2x.png new file mode 100644 index 0000000..dd819da Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon-72@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon.png new file mode 100644 index 0000000..b2571a7 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon@2x.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon@2x.png new file mode 100644 index 0000000..d75098f Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/icons/icon@2x.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/se.lproj/Localizable.strings b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/se.lproj/Localizable.strings new file mode 100644 index 0000000..0af9646 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/se.lproj/Localizable.strings @@ -0,0 +1,26 @@ +/* + 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. + */ + + +// accessibility label for recording button +"toggle audio recording" = "börja/avsluta inspelning"; +// notification spoken by VoiceOver when timed recording finishes +"timed recording complete" = "inspelning har avslutad"; +// accessibility hint for display of recorded elapsed time +"recorded time in minutes and seconds" = "inspelad tid in minuter och sekund"; \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Landscape@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Landscape@2x~ipad.png new file mode 100644 index 0000000..95c542d Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Landscape@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Landscape~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Landscape~ipad.png new file mode 100644 index 0000000..f8e2b52 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Landscape~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Portrait@2x~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Portrait@2x~ipad.png new file mode 100644 index 0000000..aae1862 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Portrait@2x~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Portrait~ipad.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Portrait~ipad.png new file mode 100644 index 0000000..af9158a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default-Portrait~ipad.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default@2x~iphone.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default@2x~iphone.png new file mode 100644 index 0000000..bd24886 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default@2x~iphone.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default~iphone.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default~iphone.png new file mode 100644 index 0000000..6fcba56 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/Resources/splash/Default~iphone.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/main.m b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/main.m new file mode 100644 index 0000000..aee71a5 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/HelloImageRecognition/main.m @@ -0,0 +1,35 @@ +/* + 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. + */ +// +// main.m +// HelloImageRecognition +// +// Created by ___FULLUSERNAME___ on ___DATE___. +// Copyright ___ORGANIZATIONNAME___ ___YEAR___. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate"); + [pool release]; + return retVal; +} diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/DirectionArrow.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/DirectionArrow.png new file mode 100644 index 0000000..8a0ccb6 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/DirectionArrow.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/SimpleIRWorld.html b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/SimpleIRWorld.html new file mode 100644 index 0000000..57f4423 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/SimpleIRWorld.html @@ -0,0 +1,116 @@ + + + + + + +Simple IR World + + + + + + + + + + + + + +
Loading ...
+ + + + + \ No newline at end of file diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.png new file mode 100644 index 0000000..f820ca0 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.zip b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.zip new file mode 100644 index 0000000..34db5dc Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/WikitudeLogo.zip differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/overlay.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/overlay.png new file mode 100644 index 0000000..5d2dfcd Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/assets/world/SimpleImageRecognition/overlay.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/debug b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/debug new file mode 100755 index 0000000..37b0d63 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/debug @@ -0,0 +1,47 @@ +#!/bin/bash + +# +# 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. +# + +# +# compile and launch a Cordova/iOS project to the simulator +# + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) +PROJECT_PATH=$CORDOVA_PATH/.. + +for file in $PROJECT_PATH/*.xcodeproj; do + PROJECT_NAME=$(basename "$file" .xcodeproj) +done; + +cd $PROJECT_PATH + +APP=build/$PROJECT_NAME.app +SDK=`xcodebuild -showsdks | grep Sim | tail -1 | awk '{print $6}'` + +xcodebuild -project $PROJECT_NAME.xcodeproj -arch i386 -target $PROJECT_NAME -configuration Debug -sdk $SDK clean build VALID_ARCHS="i386" CONFIGURATION_BUILD_DIR=$PROJECT_PATH/build + +# launch using emulate + +$CORDOVA_PATH/emulate $PROJECT_PATH/$APP + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/emulate b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/emulate new file mode 100755 index 0000000..3822121 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/emulate @@ -0,0 +1,58 @@ +#! /bin/sh +# +# 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. +# + +set -e + +CORDOVA_PATH=$( cd "$( dirname "$0" )" && pwd ) +PROJECT_PATH=$CORDOVA_PATH/.. + +function getAppPath() { + for file in $PROJECT_PATH/*.xcodeproj; do + PROJECT_NAME=$(basename "$file" .xcodeproj) + done; + APP=build/$PROJECT_NAME.app + APP_PATH=$PROJECT_PATH/$APP +} + +APP_PATH=$1 + +if [ $# -lt 1 ]; then + getAppPath +fi + +if [ ! -d "$APP_PATH" ]; then + read -p "Project '$APP_PATH' is not built. Build? [y/n]: " REPLY + if [ "$REPLY" == "y" ]; then + $CORDOVA_PATH/debug + exit 0 + else + echo "$APP_PATH not found to emulate." + exit 1 + fi +fi + +# launch using ios-sim + +if which ios-sim >/dev/null; then + ios-sim launch $APP_PATH --stderr console.log --stdout console.log & +else + echo -e '\033[31mError: ios-sim was not found. Please download, build and install version 1.4 or greater from https://github.com/phonegap/ios-sim into your path. Or "brew install ios-sim" using homebrew: http://mxcl.github.com/homebrew/\033[m'; exit 1; +fi + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/log b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/log new file mode 100755 index 0000000..fd1261c --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/cordova/log @@ -0,0 +1,26 @@ +#! /bin/sh +# +# 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. +# + +# +# USAGE +# +# ./log [path] +# +tail -f ${1:-".."}/console.log diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/config.xml b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/config.xml new file mode 100644 index 0000000..a7e35db --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/config.xml @@ -0,0 +1,47 @@ + + + Hello Cordova + + + A sample Apache Cordova application that responds to the deviceready event. + + + + Apache Cordova Team + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/cordova-2.0.0.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/cordova-2.0.0.js new file mode 100644 index 0000000..c2caa2f --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/cordova-2.0.0.js @@ -0,0 +1,5240 @@ +// commit 114cf5304a74ff8f7c9ff1d21cf5652298af04b0 + +// File generated at :: Wed Jul 18 2012 16:47:25 GMT-0700 (PDT) + +/* + 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} phoneNumbers array of phone numbers +* @param {Array.} emails array of email addresses +* @param {Array.} addresses array of addresses +* @param {Array.} ims instant messaging user ids +* @param {Array.} organizations +* @param {DOMString} birthday contact's birthday +* @param {DOMString} note user notes about contact +* @param {Array.} photos +* @param {Array.} categories +* @param {Array.} 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][;base64], + * + * @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.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/ios/plugin/ios/Contact.js +define("cordova/plugin/ios/Contact", function(require, exports, module) { +var exec = require('cordova/exec'), + ContactError = require('cordova/plugin/ContactError'); + +/** + * Provides iOS Contact.display API. + */ +module.exports = { + display : function(errorCB, options) { + /* + * Display a contact using the iOS Contact Picker UI + * NOT part of W3C spec so no official documentation + * + * @param errorCB error callback + * @param options object + * allowsEditing: boolean AS STRING + * "true" to allow editing the contact + * "false" (default) display contact + */ + + if (this.id === null) { + if (typeof errorCB === "function") { + var errorObj = new ContactError(ContactError.UNKNOWN_ERROR); + errorCB(errorObj); + } + } + else { + exec(null, errorCB, "Contacts","displayContact", [this.id, options]); + } + } +}; +}); + +// file: lib/ios/plugin/ios/Entry.js +define("cordova/plugin/ios/Entry", function(require, exports, module) { +module.exports = { + toURL:function() { + // TODO: refactor path in a cross-platform way so we can eliminate + // these kinds of platform-specific hacks. + return "file://localhost" + this.fullPath; + }, + toURI: function() { + console.log("DEPRECATED: Update your code to use 'toURL'"); + return "file://localhost" + this.fullPath; + } +}; +}); + +// file: lib/ios/plugin/ios/FileReader.js +define("cordova/plugin/ios/FileReader", function(require, exports, module) { +var exec = require('cordova/exec'), + FileError = require('cordova/plugin/FileError'), + FileReader = require('cordova/plugin/FileReader'), + ProgressEvent = require('cordova/plugin/ProgressEvent'); + +module.exports = { + 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 = decodeURIComponent(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]); + } +}; +}); + +// file: lib/ios/plugin/ios/console.js +define("cordova/plugin/ios/console", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * This class provides access to the debugging console. + * @constructor + */ +var DebugConsole = function() { + this.winConsole = window.console; + this.logLevel = DebugConsole.INFO_LEVEL; +}; + +// from most verbose, to least verbose +DebugConsole.ALL_LEVEL = 1; // same as first level +DebugConsole.INFO_LEVEL = 1; +DebugConsole.WARN_LEVEL = 2; +DebugConsole.ERROR_LEVEL = 4; +DebugConsole.NONE_LEVEL = 8; + +DebugConsole.prototype.setLevel = function(level) { + this.logLevel = level; +}; + +var stringify = function(message) { + try { + if (typeof message === "object" && JSON && JSON.stringify) { + try { + return JSON.stringify(message); + } + catch (e) { + return "error JSON.stringify()ing argument: " + e; + } + } else { + return message.toString(); + } + } catch (e) { + return e.toString(); + } +}; + +/** + * Print a normal log message to the console + * @param {Object|String} message Message or object to print to the console + */ +DebugConsole.prototype.log = function(message) { + if (this.logLevel <= DebugConsole.INFO_LEVEL) { + exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'INFO' } ]); + } + else if (this.winConsole && this.winConsole.log) { + this.winConsole.log(message); + } +}; + +/** + * Print a warning message to the console + * @param {Object|String} message Message or object to print to the console + */ +DebugConsole.prototype.warn = function(message) { + if (this.logLevel <= DebugConsole.WARN_LEVEL) { + exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'WARN' } ]); + } + else if (this.winConsole && this.winConsole.warn) { + this.winConsole.warn(message); + } +}; + +/** + * Print an error message to the console + * @param {Object|String} message Message or object to print to the console + */ +DebugConsole.prototype.error = function(message) { + if (this.logLevel <= DebugConsole.ERROR_LEVEL) { + exec(null, null, 'Debug Console', 'log', [ stringify(message), { logLevel: 'ERROR' } ]); + } + else if (this.winConsole && this.winConsole.error){ + this.winConsole.error(message); + } +}; + +module.exports = new DebugConsole(); +}); + +// file: lib/ios/plugin/ios/contacts.js +define("cordova/plugin/ios/contacts", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * Provides iOS enhanced contacts API. + */ +module.exports = { + newContactUI : function(successCallback) { + /* + * Create a contact using the iOS Contact Picker UI + * NOT part of W3C spec so no official documentation + * + * returns: the id of the created contact as param to successCallback + */ + exec(successCallback, null, "Contacts","newContact", []); + }, + chooseContact : function(successCallback, options) { + /* + * Select a contact using the iOS Contact Picker UI + * NOT part of W3C spec so no official documentation + * + * @param errorCB error callback + * @param options object + * allowsEditing: boolean AS STRING + * "true" to allow editing the contact + * "false" (default) display contact + * + * returns: the id of the selected contact as param to successCallback + */ + exec(successCallback, null, "Contacts","chooseContact", [options]); + } +}; +}); + +// file: lib/ios/plugin/ios/nativecomm.js +define("cordova/plugin/ios/nativecomm", function(require, exports, module) { +var cordova = require('cordova'); + +/** + * Called by native code to retrieve all queued commands and clear the queue. + */ +module.exports = function() { + var json = JSON.stringify(cordova.commandQueue); + cordova.commandQueue = []; + return json; +}; +}); + +// file: lib/ios/plugin/ios/notification.js +define("cordova/plugin/ios/notification", function(require, exports, module) { +var Media = require('cordova/plugin/Media'); + +module.exports = { + beep:function(count) { + (new Media('beep.wav')).play(); + } +}; +}); + +// 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 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 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/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 + + + + + + + + Hello Cordova + + +
+

Apache Cordova™

+
+ + +
+
+ + + + + + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/js/WikitudePlugin.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/js/WikitudePlugin.js new file mode 100644 index 0000000..997558e --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/js/WikitudePlugin.js @@ -0,0 +1,353 @@ +var WikitudePlugin = { + + /** + * + * This is the SDK Key, provided to you after you purchased the Wikitude SDK from http://www.wikitude.com/developer/sdk + * If you're having a trial version, leave this string empty + * + */ + mySDKKey : "ENTER-YOUR-KEY-HERE", + + /** + * + * Change the value of this variable to modify the location update rate + * + */ + locationUpdateRate : 3000, + + /** + * + * This variable represents if the current device is capable of running the Wikitude SDK + * + */ + isDeviceSupported : false, + + /** + * + * This watchID is used to shedule location updates + * + */ + watchID : null, + + /** + * + * Callbacks to get device information if ARchitect Worlds can be launched + * + */ + onDeviceSupportedCallback : null, + onDeviceNotSupportedCallback : null, + + /** + * + * Callbacks to get notified if the ARchitect World finished launching or if something went wrong during the World launch + * + */ + onARchitectWorldLaunchedCallback : null, + onARchitectWorldFailedLaunchingCallback : null, + + /** + * + * This function gets called if PhoneGap reports that it has finished loading successfully. + * + */ + isDeviceSupported: function(successCallback, errorCallback) + { + + WikitudePlugin.onDeviceSupportedCallback = successCallback; + WikitudePlugin.onDeviceNotSupportedCallback = errorCallback; + + + // PhoneGap is running, so the first thing we do is to check if the current device is capable of running the Wikitude Plugin + cordova.exec(WikitudePlugin.deviceIsARchitectReady, WikitudePlugin.deviceIsNotARchitectReady, "WikitudePlugin", "isDeviceSupported", [""]); + + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is able to start the Wikitude SDK + * + */ + deviceIsARchitectReady : function() + { + // We keep track of the device status + WikitudePlugin.isDeviceSupported = true; + + + if(WikitudePlugin.onDeviceSupportedCallback) + { + WikitudePlugin.onDeviceSupportedCallback(); + } + }, + + /** + * + * This function gets called if the Wikitude Plugin reports that the device is not able of starting the Wikitude SDK. + * + */ + deviceIsNotARchitectReady : function() + { + WikitudePlugin.isDeviceSupported = false; + + // In this case we notify the user that his device is not supported by the Wikitude SDK + if(WikitudePlugin.onDeviceNotSupportedCallback) + { + WikitudePlugin.onDeviceNotSupportedCallback(); + } + }, + + + /* + * ============================================================================================================================= + * + * PUBLIC API + * + * ============================================================================================================================= + */ + + /* Managing ARchitect world loading */ + + /** + * + * Call this function if you want to load an ARchitect World + * + * @param {String} worldPath The path to an ARchitect world ether on the device or on e.g. your dropbox + * + */ + loadARchitectWorld : function(worldPath) + { + + // before we actually call load, we check again if the device is able to open the world + if(WikitudePlugin.isDeviceSupported) + { + + // the 'open' function of the Wikitude Plugin requires a option dictionary with two keys: + // @param {Object} options (required) + // @param {String} options.sdkKey License key for the Wikitude SDK + // @param {String} options.filePath The path to a local ARchitect world or to a ARchitect world on a server or your dropbox + + cordova.exec(WikitudePlugin.worldLaunched, WikitudePlugin.worldFailedLaunching, "WikitudePlugin", "open", [{ sdkKey: WikitudePlugin.mySDKKey, filePath: worldPath}]); + + + // We add an event listener on the resume and pause event of the application lifecycle + document.addEventListener("resume", WikitudePlugin.onResume, false); + document.addEventListener("pause", WikitudePlugin.onPause, false); + + // After we started loading the world, we start location updates + WikitudePlugin.startLocationUpdates(); + + }else + { + // if the device is not able to start the Wikitude SDK, we notify the user again + WikitudePlugin.deviceNotARchitectReady(); + } + }, + + /* Managing the Wikitude SDK Lifecycle */ + + /** + * + * Use this function to stop the Wikitude SDK and to remove the ARchitectView from the screen + * + */ + close : function() + { + document.removeEventListener("pause", WikitudePlugin.onPause, false); + document.removeEventListener("resume", WikitudePlugin.onResume, false); + + WikitudePlugin.stopLocationUpdates(); + + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]); + }, + + /** + * + * Use this function to only hide the Wikitude SDK. All location and rendering updates are still active + * + */ + hide : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "hide", [""]); + }, + + /** + * + * Use this function to show the Wikitude SDK if it was hidden before + * + */ + show : function() + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "show", [""]); + }, + + /* Interacting with the Wikitude SDK */ + + /** + * + * Use this function to call javascript which will be executed in the context of your ARchitect World + * + * + * @param js The JavaScript that gets evaluated in context of the ARchitect World + * + */ + callJavaScript : function(js) + { + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "callJavascript", [js]); + }, + + /** + * + * Use this function to set a callback which will be invoked when the ARchitect World calls for example + * document.location = "architectsdk://opendetailpage?id=9"; + * + * + * @param onUrlInvokeCallback A function which gets called when the ARchitect World invokes a call to "document.location = architectsdk://" + */ + setOnUrlInvokeCallback : function(onUrlInvokeCallback) + { + cordova.exec(onUrlInvokeCallback, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onUrlInvoke", [""]); + }, + + + /* + * ============================================================================================================================= + * + * Callbacks of public functions + * + * ============================================================================================================================= + */ + + /** + * + * Use this callback to get notified if the world loaded successfully + * + */ + worldLaunched : function() + { + if(WikitudePlugin.onARchitectWorldLaunchedCallback) + { + WikitudePlugin.onARchitectWorldLaunchedCallback(); + } + }, + + /** + * + * Use this callback to get notified if the Wikitude SDK wasn't able to load the ARchitect World + * + */ + worldFailedLaunching : function(err) + { + if(WikitudePlugin.onARchitectWorldFailedLaunchingCallback) + { + WikitudePlugin.onARchitectWorldFailedLaunchingCallback(err); + } + }, + + /* Lifecycle updates */ + + /** + * + * This function actually starts the PhoneGap location updates + * + */ + startLocationUpdates : function() + { + + WikitudePlugin.watchID = navigator.geolocation.watchPosition(WikitudePlugin.onReceivedLocation, WikitudePlugin.onWikitudeError, { frequency: WikitudePlugin.locationUpdateRate }); + }, + + /** + * + * This callback gets called everytime the location did update + * + */ + onReceivedLocation : function(position) + { + + // Every time that PhoneGap did received a location update, we pass the location into the Wikitude SDK + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "setLocation", [{ lat: position.coords.latitude, lon: position.coords.longitude, alt: position.coords.altitude, acc: position.coords.accuracy}]); + }, + + /** + * + * Use this function to stop location updates + * + */ + stopLocationUpdates : function() + { + + // We clear the location update watch which was responsible for updating the location in a specific time interval + navigator.geolocation.clearWatch(WikitudePlugin.watchID); + WikitudePlugin.watchID = null; + }, + + /** + * + * This function gets called every time the application did become active. + * + */ + onResume : function() + { + + // Call the Wikitude SDK that the application did become active again + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onResume", [""]); + + // And start continuing updating the user location + WikitudePlugin.startLocationUpdates(); + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onPause : function() + { + + // Call the Wikitude SDK that the application did resign active + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "onPause", [""]); + + // And stop all ongoing location updates + WikitudePlugin.stopLocationUpdates(); + }, + + /** + * + * Android specific! + * This function gets called if the user presses the back button + * + */ + onBackButton : function() + { + + cordova.exec(WikitudePlugin.onWikitudeOK, WikitudePlugin.onWikitudeError, "WikitudePlugin", "close", [""]); + WikitudePlugin.stopLocationUpdates(); + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeOK : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + onWikitudeError : function() + { + }, + + /** + * + * This function gets called every time the application is about to become inactive + * + */ + report: function(id) + { + console.log("app report: " + id); + } +}; diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/js/index.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/js/index.js new file mode 100644 index 0000000..b82a058 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/js/index.js @@ -0,0 +1,37 @@ +var app = { + initialize: function() { + this.bind(); + }, + bind: function() { + document.addEventListener('deviceready', this.deviceready, false); + }, + + // A callback which gets called if the device is able to launch ARchitect Worlds + onDeviceSupportedCallback : function() + { + // The device is able to launch ARchitect World, so lets do so :) + WikitudePlugin.loadARchitectWorld("assets/world/SimpleImageRecognition/SimpleIRWorld.html"); + }, + + // A callback which gets called if the device is not able to start ARchitect Worlds + onDeviceNotSupportedCallback : function() + { + app.report("Unable to launch ARchitect Worlds on this device"); + }, + + deviceready: function() { + // note that this is an event handler so the scope is that of the event + // so we need to call app.report(), and not this.report() + app.report('deviceready'); + + // check if the current device is able to launch ARchitect Worlds + WikitudePlugin.isDeviceSupported(app.onDeviceSupportedCallback, app.onDeviceNotSupportedCallback); + }, + report: function(id) { + console.log("report:" + id); + // hide the .pending

and show the .complete

+ document.querySelector('#' + id + ' .pending').className += ' hide'; + var completeElem = document.querySelector('#' + id + ' .complete'); + completeElem.className = completeElem.className.split('hide').join(''); + } +}; diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_128.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_128.png new file mode 100644 index 0000000..3516df3 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_128.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_16.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_16.png new file mode 100644 index 0000000..54e19c5 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_16.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_24.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_24.png new file mode 100644 index 0000000..c7d43ad Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_24.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_256.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_256.png new file mode 100644 index 0000000..e1cd0e6 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_256.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_32.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_32.png new file mode 100644 index 0000000..734fffc Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_32.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_48.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_48.png new file mode 100644 index 0000000..8ad8bac Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_48.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_512.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_512.png new file mode 100644 index 0000000..c9465f3 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_512.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_64.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_64.png new file mode 100644 index 0000000..03b3849 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_64.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_36.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_36.png new file mode 100644 index 0000000..cd5032a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_36.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_48.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_48.png new file mode 100644 index 0000000..e79c606 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_48.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_72.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_72.png new file mode 100644 index 0000000..4d27634 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_72.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_96.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_96.png new file mode 100644 index 0000000..ec7ffbf Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_android_96.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_bb_80.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_bb_80.png new file mode 100644 index 0000000..f86a27a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_bb_80.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_114.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_114.png new file mode 100644 index 0000000..efd9c37 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_114.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_144.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_144.png new file mode 100644 index 0000000..dd819da Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_144.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_57.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_57.png new file mode 100644 index 0000000..c795fc4 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_57.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_72.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_72.png new file mode 100644 index 0000000..b1cfde7 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/icon/cordova_ios_72.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_hdpi_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_hdpi_landscape.png new file mode 100644 index 0000000..a61e2b1 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_hdpi_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_hdpi_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_hdpi_portrait.png new file mode 100644 index 0000000..5d6a28a Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_hdpi_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_ldpi_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_ldpi_landscape.png new file mode 100644 index 0000000..f3934cd Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_ldpi_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_ldpi_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_ldpi_portrait.png new file mode 100644 index 0000000..65ad163 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_ldpi_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_mdpi_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_mdpi_landscape.png new file mode 100644 index 0000000..a1b697c Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_mdpi_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_mdpi_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_mdpi_portrait.png new file mode 100644 index 0000000..ea15693 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_mdpi_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_xhdpi_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_xhdpi_landscape.png new file mode 100644 index 0000000..79f2f09 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_xhdpi_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_xhdpi_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_xhdpi_portrait.png new file mode 100644 index 0000000..c2e8042 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/android_xhdpi_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/blackberry_transparent_300.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/blackberry_transparent_300.png new file mode 100644 index 0000000..b548bdc Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/blackberry_transparent_300.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/blackberry_transparent_400.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/blackberry_transparent_400.png new file mode 100644 index 0000000..3facdf9 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/blackberry_transparent_400.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_landscape.png new file mode 100644 index 0000000..04be5ac Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_portrait.png new file mode 100644 index 0000000..41e839d Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_retina_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_retina_landscape.png new file mode 100644 index 0000000..95c542d Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_retina_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_retina_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_retina_portrait.png new file mode 100644 index 0000000..aae1862 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/ipad_retina_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_landscape.png new file mode 100644 index 0000000..d154883 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_portrait.png new file mode 100644 index 0000000..6fcba56 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_retina_landscape.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_retina_landscape.png new file mode 100644 index 0000000..0165669 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_retina_landscape.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_retina_portrait.png b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_retina_portrait.png new file mode 100644 index 0000000..bd24886 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/iphone_retina_portrait.png differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/windows_phone_portrait.jpg b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/windows_phone_portrait.jpg new file mode 100644 index 0000000..9f95387 Binary files /dev/null and b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/res/screen/windows_phone_portrait.jpg differ diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/spec.html b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/spec.html new file mode 100644 index 0000000..83d7d2e --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/spec.html @@ -0,0 +1,50 @@ + + + + Jasmine Spec Runner + + + + + + + + + + + + + + + + + +

+ + diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/spec/helper.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/spec/helper.js new file mode 100644 index 0000000..9f99445 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/spec/helper.js @@ -0,0 +1,11 @@ +afterEach(function() { + document.getElementById('stage').innerHTML = ''; +}); + +var helper = { + trigger: function(obj, name) { + var e = document.createEvent('Event'); + e.initEvent(name, true, true); + obj.dispatchEvent(e); + } +}; diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/spec/index.js b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/spec/index.js new file mode 100644 index 0000000..121cf63 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/HelloImageRecognition/www/spec/index.js @@ -0,0 +1,49 @@ +describe('app', function() { + describe('initialize', function() { + it('should bind deviceready', function() { + runs(function() { + spyOn(app, 'deviceready'); + app.initialize(); + helper.trigger(window.document, 'deviceready'); + }); + + waitsFor(function() { + return (app.deviceready.calls.length > 0); + }, 'deviceready should be called once', 500); + + runs(function() { + expect(app.deviceready).toHaveBeenCalled(); + }); + }); + }); + + describe('deviceready', function() { + it('should report that it fired', function() { + spyOn(app, 'report'); + app.deviceready(); + expect(app.report).toHaveBeenCalledWith('deviceready'); + }); + }); + + describe('report', function() { + beforeEach(function() { + var el = document.getElementById('stage'); + el.innerHTML = ['
', + '

Pending

', + '

Complete

', + '
'].join('\n'); + }); + + it('should show the completion state', function() { + app.report('deviceready'); + var el = document.querySelector('#deviceready .complete:not(.hide)'); + expect(el).toBeTruthy(); + }); + + it('should hide the pending state', function() { + app.report('deviceready'); + var el = document.querySelector('#deviceready .pending.hide'); + expect(el).toBeTruthy(); + }); + }); +}); diff --git a/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/README.md b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/README.md new file mode 100644 index 0000000..378bd65 --- /dev/null +++ b/iOS/AugmentedReality-Wikitude/SampleProjects/Extended/README.md @@ -0,0 +1,16 @@ +# Hello Image Recognition iOS + +This document describes all necessary steps to get the sample running. + + +###Setup +*** + +* Download the Vuforia Framework from [Qualcomm](https://ar.qualcomm.at/sdk/ios) (You need to register yourself as a Qualcomm developer) + +* After that, copy the lib and and header files from your downloaded Vuforia SDK into the ``` [ProjectFolder/"AppName"/Vuforia/include/QCAR] ``` and ``` [ProjectFolder/"AppName"/Vuforia/lib/arm/] ``` folder of this project + +* Download the Wikitude SDK from [our website](http://www.wikitude.com/developer/sdk) (You need to register yourself as a Wikitude developer) + +* Copy the SDK folder from ``` [DownloadedSDKRoot/iOS/SDK] ``` into ``` [ProjectFolder/"AppName"/WikitudeSDK] ``` +