find : function(fields, successCB, failCB, options) { // Success callback is required. Throw exception if not specified. if (typeof successCB !== 'function') { throw new TypeError("You must specify a success callback for the find command."); } // Search qualifier is required and cannot be empty. if (!fields || !(utils.isArray(fields)) || fields.length === 0) { if (typeof failCB === 'function') { failCB(new ContactError(ContactError.INVALID_ARGUMENT_ERROR)); } return; } // options are optional var filter ="", multiple = false, contacts = [], tizenFilter = null; if (options) { filter = options.filter || ""; multiple = options.multiple || false; } if (filter){ tizenFilter = ContactUtils.buildFilterExpression(fields, filter); } tizen.contact.getDefaultAddressBook().find( function(tizenContacts) { if (multiple) { for (var index in tizenContacts) { contacts.push(ContactUtils.createContact(tizenContacts[index], fields)); } } else { contacts.push(ContactUtils.createContact(tizenContacts[0], fields)); } // return results successCB(contacts); }, function(error) { if (typeof failCB === 'function') { failCB(ContactError.UNKNOWN_ERROR); } }, tizenFilter, null); }
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; };
createContact: function(tizenContact, fields) { if (!tizenContact) { return null; } // construct a new contact object // always copy the contact id and displayName fields var contact = new Contact(tizenContact.id, tizenContact.name.displayName); // nothing to do if (!fields || !(utils.isArray(fields)) || fields.length === 0) { return contact; } else if (fields.length === 1 && fields[0] === "*") { // Cordova enhancement to allow fields value of ["*"] to indicate // all supported fields. fields = allFields; } // add the fields specified for ( var key in fields) { var field = fields[key], index = 0; if (!field) { continue; } // name if (field.indexOf('name') === 0) { var formattedName = (tizenContact.name.prefix || ""); if (tizenContact.name.firstName) { formattedName += ' '; formattedName += (tizenContact.name.firstName || ""); } if (tizenContact.name.middleName) { formattedName += ' '; formattedName += (tizenContact.name.middleName || ""); } if (tizenContact.name.lastName) { formattedName += ' '; formattedName += (tizenContact.name.lastName || ""); } contact.name = new ContactName( formattedName, tizenContact.name.lastName, tizenContact.name.firstName, tizenContact.name.middleName, tizenContact.name.prefix, null); } // phoneNumbers else if (field.indexOf('phoneNumbers') === 0) { var phoneNumbers = []; for (index = 0 ; index < tizenContact.phoneNumbers.length ; ++index) { phoneNumbers.push( new ContactField( 'PHONE', tizenContact.phoneNumbers[index].number, ((tizenContact.phoneNumbers[index].types[1]) && (tizenContact.emails[index].types[1] === "PREF") ) ? true : false)); } contact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : null; } // emails else if (field.indexOf('emails') === 0) { var emails = []; for (index = 0 ; index < tizenContact.emails.length ; ++index) { emails.push( new ContactField( 'EMAILS', tizenContact.emails[index].email, ((tizenContact.emails[index].types[1]) && (tizenContact.emails[index].types[1] === "PREF") ) ? true : false)); } contact.emails = emails.length > 0 ? emails : null; } // addresses else if (field.indexOf('addresses') === 0) { var addresses = []; for (index = 0 ; index < tizenContact.addresses.length ; ++index) { addresses.push( new ContactAddress( ((tizenContact.addresses[index].types[1] && tizenContact.addresses[index].types[1] === "PREF") ? true : false), tizenContact.addresses[index].types[0] ? tizenContact.addresses[index].types[0] : "HOME", null, tizenContact.addresses[index].streetAddress, tizenContact.addresses[index].city, tizenContact.addresses[index].region, tizenContact.addresses[index].postalCode, tizenContact.addresses[index].country )); } contact.addresses = addresses.length > 0 ? addresses : null; } // birthday else if (field.indexOf('birthday') === 0) { if (utils.isDate(tizenContact.birthday)) { contact.birthday = tizenContact.birthday; } } // note only one in Tizen Contact else if (field.indexOf('note') === 0) { if (tizenContact.note) { contact.note = tizenContact.note[0]; } } // organizations else if (field.indexOf('organizations') === 0) { var organizations = []; // there's only one organization in a Tizen Address if (tizenContact.organization) { organizations.push( new ContactOrganization( true, 'WORK', tizenContact.organization.name, tizenContact.organization.department, tizenContact.organization.jobTitle)); } contact.organizations = organizations.length > 0 ? organizations : null; } // categories else if (field.indexOf('categories') === 0) { var categories = []; if (tizenContact.categories) { for (index = 0 ; index < tizenContact.categories.length ; ++index) { categories.push( new ContactField( 'MAIN', tizenContact.categories, (index === 0) )); } contact.categories = categories.length > 0 ? categories : null; } } // urls else if (field.indexOf('urls') === 0) { var urls = []; if (tizenContact.urls) { for (index = 0 ; index <tizenContact.urls.length ; ++index) { urls.push( new ContactField( tizenContact.urls[index].type, tizenContact.urls[index].url, (index === 0))); } } contact.urls = urls.length > 0 ? urls : null; } // photos else if (field.indexOf('photos') === 0) { var photos = []; if (tizenContact.photoURI) { photos.push(new ContactField('URI', tizenContact.photoURI, true)); } contact.photos = photos.length > 0 ? photos : null; } } return contact; }
createContact : function(bbContact, fields) { if (!bbContact) { return null; } // construct a new contact object // always copy the contact id and displayName fields var contact = new Contact(bbContact.uid, bbContact.user1); // nothing to do if (!fields || !(utils.isArray(fields)) || fields.length === 0) { return contact; } else if (fields.length == 1 && fields[0] === "*") { // Cordova enhancement to allow fields value of ["*"] to indicate // all supported fields. fields = allFields; } // add the fields specified for ( var i in fields) { var field = fields[i]; if (!field) { continue; } // name if (field.indexOf('name') === 0) { var formattedName = bbContact.title + ' ' + bbContact.firstName + ' ' + bbContact.lastName; contact.name = new ContactName(formattedName, bbContact.lastName, bbContact.firstName, null, bbContact.title, null); } // phone numbers else if (field.indexOf('phoneNumbers') === 0) { var phoneNumbers = []; if (bbContact.homePhone) { phoneNumbers.push(new ContactField('home', bbContact.homePhone)); } if (bbContact.homePhone2) { phoneNumbers.push(new ContactField('home', bbContact.homePhone2)); } if (bbContact.workPhone) { phoneNumbers.push(new ContactField('work', bbContact.workPhone)); } if (bbContact.workPhone2) { phoneNumbers.push(new ContactField('work', bbContact.workPhone2)); } if (bbContact.mobilePhone) { phoneNumbers.push(new ContactField('mobile', bbContact.mobilePhone)); } if (bbContact.faxPhone) { phoneNumbers.push(new ContactField('fax', bbContact.faxPhone)); } if (bbContact.pagerPhone) { phoneNumbers.push(new ContactField('pager', bbContact.pagerPhone)); } if (bbContact.otherPhone) { phoneNumbers.push(new ContactField('other', bbContact.otherPhone)); } contact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : null; } // emails else if (field.indexOf('emails') === 0) { var emails = []; if (bbContact.email1) { emails.push(new ContactField(null, bbContact.email1, null)); } if (bbContact.email2) { emails.push(new ContactField(null, bbContact.email2, null)); } if (bbContact.email3) { emails.push(new ContactField(null, bbContact.email3, null)); } contact.emails = emails.length > 0 ? emails : null; } // addresses else if (field.indexOf('addresses') === 0) { var addresses = []; if (bbContact.homeAddress) { addresses.push(createContactAddress("home", bbContact.homeAddress)); } if (bbContact.workAddress) { addresses.push(createContactAddress("work", bbContact.workAddress)); } contact.addresses = addresses.length > 0 ? addresses : null; } // birthday else if (field.indexOf('birthday') === 0) { if (bbContact.birthday) { contact.birthday = bbContact.birthday; } } // note else if (field.indexOf('note') === 0) { if (bbContact.note) { contact.note = bbContact.note; } } // organizations else if (field.indexOf('organizations') === 0) { var organizations = []; if (bbContact.company || bbContact.jobTitle) { organizations.push(new ContactOrganization(null, null, bbContact.company, null, bbContact.jobTitle)); } contact.organizations = organizations.length > 0 ? organizations : null; } // categories else if (field.indexOf('categories') === 0) { if (bbContact.categories && bbContact.categories.length > 0) { contact.categories = bbContact.categories; } else { contact.categories = null; } } // urls else if (field.indexOf('urls') === 0) { var urls = []; if (bbContact.webpage) { urls.push(new ContactField(null, bbContact.webpage)); } contact.urls = urls.length > 0 ? urls : null; } // photos else if (field.indexOf('photos') === 0) { var photos = []; // The BlackBerry Contact object will have a picture attribute // with Base64 encoded image if (bbContact.picture) { photos.push(new ContactField('base64', bbContact.picture)); } contact.photos = photos.length > 0 ? photos : null; } } return contact; }
buildFilterExpression : function(fields, filter) { // ensure filter exists if (!filter || filter === "") { return null; } if (fields.length == 1 && fields[0] === "*") { // Cordova enhancement to allow fields value of ["*"] to indicate // all supported fields. fields = allFields; } // BlackBerry API uses specific operators to build filter expressions // for // querying Contact lists. The operators are // ["!=","==","<",">","<=",">="]. // Use of regex is also an option, and the only one we can use to // simulate // an SQL '%LIKE%' clause. // // Note: The BlackBerry regex implementation doesn't seem to support // conventional regex switches that would enable a case insensitive // search. // It does not honor the (?i) switch (which causes Contact.find() to // fail). // We need case INsensitivity to match the W3C Contacts API spec. // So the guys at RIM proposed this method: // // original filter = "norm" // case insensitive filter = "[nN][oO][rR][mM]" // var ciFilter = ""; for ( var i = 0; i < filter.length; i++) { ciFilter = ciFilter + "[" + filter[i].toLowerCase() + filter[i].toUpperCase() + "]"; } // match anything that contains our filter string filter = ".*" + ciFilter + ".*"; // build a filter expression using all Contact fields provided var filterExpression = null; if (fields && utils.isArray(fields)) { var fe = null; for ( var f in fields) { if (!fields[f]) { continue; } // retrieve the BlackBerry contact fields that map to the one // specified var bbFields = fieldMappings[fields[f]]; // BlackBerry doesn't support the field specified if (!bbFields) { continue; } // construct the filter expression using the BlackBerry fields for ( var j in bbFields) { fe = new blackberry.find.FilterExpression(bbFields[j], "REGEX", filter); if (filterExpression === null) { filterExpression = fe; } else { // combine the filters filterExpression = new blackberry.find.FilterExpression( filterExpression, "OR", fe); } } } } return filterExpression; },
module.exports = function() { if (!channel.onCordovaInfoReady.fired) { utils.alert("ERROR: Attempting to call cordova.exec()" + " before 'deviceready'. Ignoring."); return; } var successCallback, failCallback, service, action, actionArgs, splitCommand; var callbackId = null; if (typeof arguments[0] !== "string") { // FORMAT ONE successCallback = arguments[0]; failCallback = arguments[1]; service = arguments[2]; action = arguments[3]; actionArgs = arguments[4]; // Since we need to maintain backwards compatibility, we have to pass // an invalid callbackId even if no callback was provided since plugins // will be expecting it. The Cordova.exec() implementation allocates // an invalid callbackId and passes it even if no callbacks were given. callbackId = 'INVALID'; } else { // FORMAT TWO splitCommand = arguments[0].split("."); action = splitCommand.pop(); service = splitCommand.join("."); actionArgs = Array.prototype.splice.call(arguments, 1); } // Start building the command object. var command = { className: service, methodName: action, "arguments": [] }; // Register the callbacks and add the callbackId to the positional // arguments if given. if (successCallback || failCallback) { callbackId = service + cordova.callbackId++; cordova.callbacks[callbackId] = {success:successCallback, fail:failCallback}; } if (callbackId !== null) { command["arguments"].push(callbackId); } for (var i = 0; i < actionArgs.length; ++i) { var arg = actionArgs[i]; if (arg === undefined || arg === null) { // nulls are pushed to the args now (becomes NSNull) command["arguments"].push(arg); } else if (typeof(arg) == 'object' && !(utils.isArray(arg))) { command.options = arg; } else { command["arguments"].push(arg); } } // Stringify and queue the command. We stringify to command now to // effectively clone the command arguments in case they are mutated before // the command is executed. cordova.commandQueue.push(JSON.stringify(command)); // If the queue length is 1, then that means it was empty before we queued // the given command, so let the native side know that we have some // commands to execute, unless the queue is currently being flushed, in // which case the command will be picked up without notification. if (cordova.commandQueue.length == 1 && !cordova.commandQueueFlushing) { if (!gapBridge) { createGapBridge(); } gapBridge.src = "gap://ready"; } };
var calculate = function (marker) { //var marker = self.get("marker"); var map = marker.getMap(); var div = map.getDiv(); var frame = self.get("frame"); var contentFrame = frame.firstChild; var contentBox = contentFrame.firstChild; contentBox.style.minHeight = "50px"; contentBox.style.width = "auto"; contentBox.style.height = "auto"; contentBox.style.padding = "5px"; var content = self.get("content"); if (typeof content === "string") { contentBox.style.whiteSpace = "pre-wrap"; contentBox.innerHTML = content; } else { if (!content) { contentBox.innerText = ""; } else if (content.nodeType === 1) { contentBox.innerHTML = ""; contentBox.appendChild(content); } else { contentBox.innerText = content; } } var cssOptions = self.get("cssOptions"); if (cssOptions && typeof cssOptions === "object") { var keys = Object.keys(cssOptions); keys.forEach(function (key) { contentBox.style.setProperty(key, cssOptions[key]); }); } // Insert the contents to this HTMLInfoWindow if (!anchorDiv.parentNode) { map._layers.info.appendChild(anchorDiv); } // Adjust the HTMLInfoWindow size var contentsWidth = contentBox.offsetWidth + 10; // padding 5px x 2 var contentsHeight = contentBox.offsetHeight; self.set("contentsHeight", contentsHeight); contentFrame.style.width = contentsWidth + "px"; contentFrame.style.height = contentsHeight + "px"; frame.style.width = contentsWidth + "px"; frame.style.height = (contentsHeight + 15) + "px"; if (contentBox.offsetWidth > div.offsetWidth * 0.9) { contentBox.style.width = (div.offsetWidth * 0.9) + "px"; } contentBox.style.width = "100%"; contentBox.style.height = "100%"; contentBox.style.padding = "5px 17px 17px 5px"; self.set("contentsWidth", contentsWidth); var infoOffset = { x: 31, y: 31 }; var iconSize = { width: 62, height: 110 }; // If there is no specification with `anchor` property, // the values {x: 0.5, y: 1} are specified by native APIs. // For the case, anchor values are {x: 0} in JS. var anchor = { x: 15, y: 15 }; var icon = marker.get("icon"); if (typeof icon === "object") { if (typeof icon.url === "string" && icon.url.indexOf("data:image/") === 0) { var img = document.createElement("img"); img.src = icon.url; iconSize.width = img.width; iconSize.height = img.height; } if (typeof icon.size === "object") { iconSize.width = icon.size.width; iconSize.height = icon.size.height; } if (Array.isArray(icon.anchor)) { anchor.x = icon.anchor[0]; anchor.y = icon.anchor[1]; } } var infoWindowAnchor = marker.get("infoWindowAnchor"); if (utils.isArray(infoWindowAnchor)) { infoOffset.x = infoWindowAnchor[0]; infoOffset.y = infoWindowAnchor[1]; } infoOffset.x = infoOffset.x / iconSize.width; infoOffset.x = infoOffset.x > 1 ? 1 : infoOffset.x; infoOffset.x = infoOffset.x < 0 ? 0 : infoOffset.x; infoOffset.y = infoOffset.y / iconSize.height; infoOffset.y = infoOffset.y > 1 ? 1 : infoOffset.y; infoOffset.y = infoOffset.y < 0 ? 0 : infoOffset.y; infoOffset.y *= iconSize.height; infoOffset.x *= iconSize.width; anchor.x = anchor.x / iconSize.width; anchor.x = anchor.x > 1 ? 1 : anchor.x; anchor.x = anchor.x < 0 ? 0 : anchor.x; anchor.y = anchor.y / iconSize.height; anchor.y = anchor.y > 1 ? 1 : anchor.y; anchor.y = anchor.y < 0 ? 0 : anchor.y; anchor.y *= iconSize.height; anchor.x *= iconSize.width; //console.log("contentsSize = " + contentsWidth + ", " + contentsHeight); //console.log("iconSize = " + iconSize.width + ", " + iconSize.height); //console.log("infoOffset = " + infoOffset.x + ", " + infoOffset.y); var frameBorder = parseInt(common.getStyle(contentFrame, "border-left-width").replace(/[^\d]/g, ""), 10); //var offsetX = (contentsWidth + frameBorder + anchor.x ) * 0.5 + (iconSize.width / 2 - infoOffset.x); //var offsetY = contentsHeight + anchor.y - (frameBorder * 2) - infoOffset.y + 15; var offsetX = -(iconSize.width / 2) - (cordova.platformId === "android" ? 1 : 0); var offsetY = -iconSize.height - (cordova.platformId === "android" ? 1 : 0); anchorDiv.style.width = iconSize.width + "px"; anchorDiv.style.height = iconSize.height + "px"; self.set("offsetX", offsetX); self.set("offsetY", offsetY); frame.style.bottom = (iconSize.height - infoOffset.y) + "px"; frame.style.left = ((-contentsWidth) / 2 + infoOffset.x) + "px"; //console.log("frameLeft = " + frame.style.left ); var point = map.get("infoPosition"); anchorDiv.style.visibility = "hidden"; var x = point.x + self.get("offsetX"); var y = point.y + self.get("offsetY"); anchorDiv.style['-webkit-transform'] = "translate3d(" + x + "px, " + y + "px, 0px)"; anchorDiv.style.transform = "translate3d(" + x + "px, " + y + "px, 0px)"; anchorDiv.style.visibility = "visible"; self.trigger("infoPosition_changed", "", point); self.trigger(event.INFO_OPEN); };
it("should return false for {}.", function() { var isArray = utils.isArray({}); expect(isArray).toBe(false); });
it("should return true for new Array().", function() { var isArray = utils.isArray(new Array()); expect(isArray).toBe(true); });
it("should return true for [].", function() { var isArray = utils.isArray([]); expect(isArray).toBe(true); });
(function(){var CORDOVA_JS_BUILD_LABEL="3.1.0";var require,define;(function(){var modules={},requireStack=[],inProgressModules={},SEPERATOR=".";function build(module){var factory=module.factory,localRequire=function(id){var resultantId=id;if(id.charAt(0)==="."){resultantId=module.id.slice(0,module.id.lastIndexOf(SEPERATOR))+SEPERATOR+id.slice(2)}return require(resultantId)};module.exports={};delete module.factory;factory(localRequire,module.exports,module);return module.exports}require=function(id){if(!modules[id]){throw"module "+id+" not found"}else{if(id in inProgressModules){var cycle=requireStack.slice(inProgressModules[id]).join("->")+"->"+id;throw"Cycle in require graph: "+cycle}}if(modules[id].factory){try{inProgressModules[id]=requireStack.length;requireStack.push(id);return build(modules[id])}finally{delete inProgressModules[id];requireStack.pop()}}return 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]};define.moduleMap=modules})();if(typeof module==="object"&&typeof require==="function"){module.exports.require=require;module.exports.define=define}define("cordova",function(require,exports,module){var channel=require("cordova/channel");var platform=require("cordova/platform");var m_document_addEventListener=document.addEventListener;var m_document_removeEventListener=document.removeEventListener;var m_window_addEventListener=window.addEventListener;var m_window_removeEventListener=window.removeEventListener;var documentEventHandlers={},windowEventHandlers={};document.addEventListener=function(evt,handler,capture){var e=evt.toLowerCase();if(typeof documentEventHandlers[e]!="undefined"){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(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(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}var cordova={define:define,require:require,version:CORDOVA_JS_BUILD_LABEL,platformId:platform.id,addWindowEventHandler:function(event){return(windowEventHandlers[event]=channel.create(event))},addStickyDocumentEventHandler:function(event){return(documentEventHandlers[event]=channel.createSticky(event))},addDocumentEventHandler:function(event){return(documentEventHandlers[event]=channel.create(event))},removeWindowEventHandler:function(event){delete windowEventHandlers[event]},removeDocumentEventHandler:function(event){delete documentEventHandlers[event]},getOriginalHandlers:function(){return{document:{addEventListener:m_document_addEventListener,removeEventListener:m_document_removeEventListener},window:{addEventListener:m_window_addEventListener,removeEventListener:m_window_removeEventListener}}},fireDocumentEvent:function(type,data,bNoDetach){var evt=createEvent(type,data);if(typeof documentEventHandlers[type]!="undefined"){if(bNoDetach){documentEventHandlers[type].fire(evt)}else{setTimeout(function(){if(type=="deviceready"){document.dispatchEvent(evt)}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)}},callbackId:Math.floor(Math.random()*2000000000),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},callbackSuccess:function(callbackId,args){try{cordova.callbackFromNative(callbackId,true,args.status,[args.message],args.keepCallback)}catch(e){console.log("Error in error callback: "+callbackId+" = "+e)}},callbackError:function(callbackId,args){try{cordova.callbackFromNative(callbackId,false,args.status,[args.message],args.keepCallback)}catch(e){console.log("Error in error callback: "+callbackId+" = "+e)}},callbackFromNative:function(callbackId,success,status,args,keepCallback){var callback=cordova.callbacks[callbackId];if(callback){if(success&&status==cordova.callbackStatus.OK){callback.success&&callback.success.apply(null,args)}else{if(!success){callback.fail&&callback.fail.apply(null,args)}}if(!keepCallback){delete cordova.callbacks[callbackId]}}},addConstructor:function(func){channel.onCordovaReady.subscribe(function(){try{func()}catch(e){console.log("Failed to run constructor: "+e)}})}};module.exports=cordova});define("cordova/android/nativeapiprovider",function(require,exports,module){var nativeApi=this._cordovaNative||require("cordova/android/promptbasednativeapi");var currentApi=nativeApi;module.exports={get:function(){return currentApi},setPreferPrompt:function(value){currentApi=value?require("cordova/android/promptbasednativeapi"):nativeApi},set:function(value){currentApi=value}}});define("cordova/android/promptbasednativeapi",function(require,exports,module){module.exports={exec:function(service,action,callbackId,argsJson){return prompt(argsJson,"gap:"+JSON.stringify([service,action,callbackId]))},setNativeToJsBridgeMode:function(value){prompt(value,"gap_bridge_mode:")},retrieveJsMessages:function(fromOnlineEvent){return prompt(+fromOnlineEvent,"gap_poll:")}}});define("cordova/argscheck",function(require,exports,module){var exec=require("cordova/exec");var utils=require("cordova/utils");var moduleExports=module.exports;var typeMap={A:"Array",D:"Date",N:"Number",S:"String",F:"Function",O:"Object"};function extractParamName(callee,argIndex){return(/.*?\((.*?)\)/).exec(callee)[1].split(", ")[argIndex]}function checkArgs(spec,functionName,args,opt_callee){if(!moduleExports.enableChecks){return}var errMsg=null;var typeName;for(var i=0;i<spec.length;++i){var c=spec.charAt(i),cUpper=c.toUpperCase(),arg=args[i];if(c=="*"){continue}typeName=utils.typeName(arg);if((arg===null||arg===undefined)&&c==cUpper){continue}if(typeName!=typeMap[cUpper]){errMsg="Expected "+typeMap[cUpper];break}}if(errMsg){errMsg+=", but got "+typeName+".";errMsg='Wrong type for parameter "'+extractParamName(opt_callee||args.callee,i)+'" of '+functionName+": "+errMsg;if(typeof jasmine=="undefined"){console.error(errMsg)}throw TypeError(errMsg)}}function getValue(value,defaultValue){return value===undefined?defaultValue:value}moduleExports.checkArgs=checkArgs;moduleExports.getValue=getValue;moduleExports.enableChecks=true});define("cordova/base64",function(require,exports,module){var base64=exports;base64.fromArrayBuffer=function(arrayBuffer){var array=new Uint8Array(arrayBuffer);return uint8ToBase64(array)};var b64_6bit="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64_12bit;var b64_12bitTable=function(){b64_12bit=[];for(var i=0;i<64;i++){for(var j=0;j<64;j++){b64_12bit[i*64+j]=b64_6bit[i]+b64_6bit[j]}}b64_12bitTable=function(){return b64_12bit};return b64_12bit};function uint8ToBase64(rawData){var numBytes=rawData.byteLength;var output="";var segment;var table=b64_12bitTable();for(var i=0;i<numBytes-2;i+=3){segment=(rawData[i]<<16)+(rawData[i+1]<<8)+rawData[i+2];output+=table[segment>>12];output+=table[segment&4095]}if(numBytes-i==2){segment=(rawData[i]<<16)+(rawData[i+1]<<8);output+=table[segment>>12];output+=b64_6bit[(segment&4095)>>6];output+="="}else{if(numBytes-i==1){segment=(rawData[i]<<16);output+=table[segment>>12];output+="=="}}return output}});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 clobber(obj,key,value){exports.replaceHookForTesting(obj,key);obj[key]=value;if(obj[key]!==value){utils.defineGetter(obj,key,function(){return value})}}function assignOrWrapInDeprecateGetter(obj,key,value,message){if(message){utils.defineGetter(obj,key,function(){console.log(message);delete obj[key];clobber(obj,key,value);return value})}else{clobber(obj,key,value)}}function include(parent,objects,clobber,merge){each(objects,function(obj,key){try{var result=obj.path?require(obj.path):{};if(clobber){if(typeof parent[key]==="undefined"){assignOrWrapInDeprecateGetter(parent,key,result,obj.deprecated)}else{if(typeof obj.path!=="undefined"){if(merge){recursiveMerge(parent[key],result)}else{assignOrWrapInDeprecateGetter(parent,key,result,obj.deprecated)}}}result=parent[key]}else{if(typeof parent[key]=="undefined"){assignOrWrapInDeprecateGetter(parent,key,result,obj.deprecated)}else{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+'"')}})}function recursiveMerge(target,src){for(var prop in src){if(src.hasOwnProperty(prop)){if(target.prototype&&target.prototype.constructor===target){clobber(target.prototype,prop,src[prop])}else{if(typeof src[prop]==="object"&&typeof target[prop]==="object"){recursiveMerge(target[prop],src[prop])}else{clobber(target,prop,src[prop])}}}}}exports.buildIntoButDoNotClobber=function(objects,target){include(target,objects,false,false)};exports.buildIntoAndClobber=function(objects,target){include(target,objects,true,false)};exports.buildIntoAndMerge=function(objects,target){include(target,objects,true,true)};exports.recursiveMerge=recursiveMerge;exports.assignOrWrapInDeprecateGetter=assignOrWrapInDeprecateGetter;exports.replaceHookForTesting=function(){}});define("cordova/channel",function(require,exports,module){var utils=require("cordova/utils"),nextGuid=1;var Channel=function(type,sticky){this.type=type;this.handlers={};this.state=sticky?1:0;this.fireArgs=null;this.numHandlers=0;this.onHasSubscribersChange=null},channel={join:function(h,c){var len=c.length,i=len,f=function(){if(!(--i)){h()}};for(var j=0;j<len;j++){if(c[j].state===0){throw Error("Can only use join with sticky channels.")}c[j].subscribe(f)}if(!len){h()}},create:function(type){return channel[type]=new Channel(type,false)},createSticky:function(type){return channel[type]=new Channel(type,true)},deviceReadyChannelsArray:[],deviceReadyChannelsMap:{},waitForInitialization:function(feature){if(feature){var c=channel[feature]||this.createSticky(feature);this.deviceReadyChannelsMap[feature]=c;this.deviceReadyChannelsArray.push(c)}},initializationComplete:function(feature){var c=this.deviceReadyChannelsMap[feature];if(c){c.fire()}}};function forceFunction(f){if(typeof f!="function"){throw"Function required as first argument!"}}Channel.prototype.subscribe=function(f,c){forceFunction(f);if(this.state==2){f.apply(c||this,this.fireArgs);return}var func=f,guid=f.observer_guid;if(typeof c=="object"){func=utils.close(c,f)}if(!guid){guid=""+nextGuid++}func.observer_guid=guid;f.observer_guid=guid;if(!this.handlers[guid]){this.handlers[guid]=func;this.numHandlers++;if(this.numHandlers==1){this.onHasSubscribersChange&&this.onHasSubscribersChange()}}};Channel.prototype.unsubscribe=function(f){forceFunction(f);var guid=f.observer_guid,handler=this.handlers[guid];if(handler){delete this.handlers[guid];this.numHandlers--;if(this.numHandlers===0){this.onHasSubscribersChange&&this.onHasSubscribersChange()}}};Channel.prototype.fire=function(e){var fail=false,fireArgs=Array.prototype.slice.call(arguments);if(this.state==1){this.state=2;this.fireArgs=fireArgs}if(this.numHandlers){var toCall=[];for(var item in this.handlers){toCall.push(this.handlers[item])}for(var i=0;i<toCall.length;++i){toCall[i].apply(this,fireArgs)}if(this.state==2&&this.numHandlers){this.numHandlers=0;this.handlers={};this.onHasSubscribersChange&&this.onHasSubscribersChange()}}};channel.createSticky("onDOMContentLoaded");channel.createSticky("onNativeReady");channel.createSticky("onCordovaReady");channel.createSticky("onPluginsReady");channel.createSticky("onDeviceReady");channel.create("onResume");channel.create("onPause");channel.createSticky("onDestroy");channel.waitForInitialization("onCordovaReady");channel.waitForInitialization("onDOMContentLoaded");module.exports=channel});define("cordova/exec",function(require,exports,module){var cordova=require("cordova"),nativeApiProvider=require("cordova/android/nativeapiprovider"),utils=require("cordova/utils"),base64=require("cordova/base64"),jsToNativeModes={PROMPT:0,JS_OBJECT:1,LOCATION_CHANGE:2},nativeToJsModes={POLLING:0,LOAD_URL:1,ONLINE_EVENT:2,PRIVATE_API:3},jsToNativeBridgeMode,nativeToJsBridgeMode=nativeToJsModes.ONLINE_EVENT,pollEnabled=false,messagesFromNative=[];function androidExec(success,fail,service,action,args){if(jsToNativeBridgeMode===undefined){androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT)}for(var i=0;i<args.length;i++){if(utils.typeName(args[i])=="ArrayBuffer"){args[i]=base64.fromArrayBuffer(args[i])}}var callbackId=service+cordova.callbackId++,argsJson=JSON.stringify(args);if(success||fail){cordova.callbacks[callbackId]={success:success,fail:fail}}if(jsToNativeBridgeMode==jsToNativeModes.LOCATION_CHANGE){window.location="http://cdv_exec/"+service+"#"+action+"#"+callbackId+"#"+argsJson}else{var messages=nativeApiProvider.get().exec(service,action,callbackId,argsJson);if(jsToNativeBridgeMode==jsToNativeModes.JS_OBJECT&&messages==="@Null arguments."){androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);androidExec(success,fail,service,action,args);androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);return}else{androidExec.processMessages(messages)}}}function pollOnceFromOnlineEvent(){pollOnce(true)}function pollOnce(opt_fromOnlineEvent){var msg=nativeApiProvider.get().retrieveJsMessages(!!opt_fromOnlineEvent);androidExec.processMessages(msg)}function pollingTimerFunc(){if(pollEnabled){pollOnce();setTimeout(pollingTimerFunc,50)}}function hookOnlineApis(){function proxyEvent(e){cordova.fireWindowEvent(e.type)}window.addEventListener("online",pollOnceFromOnlineEvent,false);window.addEventListener("offline",pollOnceFromOnlineEvent,false);cordova.addWindowEventHandler("online");cordova.addWindowEventHandler("offline");document.addEventListener("online",proxyEvent,false);document.addEventListener("offline",proxyEvent,false)}hookOnlineApis();androidExec.jsToNativeModes=jsToNativeModes;androidExec.nativeToJsModes=nativeToJsModes;androidExec.setJsToNativeBridgeMode=function(mode){if(mode==jsToNativeModes.JS_OBJECT&&!window._cordovaNative){console.log("Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.");mode=jsToNativeModes.PROMPT}nativeApiProvider.setPreferPrompt(mode==jsToNativeModes.PROMPT);jsToNativeBridgeMode=mode};androidExec.setNativeToJsBridgeMode=function(mode){if(mode==nativeToJsBridgeMode){return}if(nativeToJsBridgeMode==nativeToJsModes.POLLING){pollEnabled=false}nativeToJsBridgeMode=mode;nativeApiProvider.get().setNativeToJsBridgeMode(mode);if(mode==nativeToJsModes.POLLING){pollEnabled=true;setTimeout(pollingTimerFunc,1)}};function processMessage(message){try{var firstChar=message.charAt(0);if(firstChar=="J"){eval(message.slice(1))}else{if(firstChar=="S"||firstChar=="F"){var success=firstChar=="S";var keepCallback=message.charAt(1)=="1";var spaceIdx=message.indexOf(" ",2);var status=+message.slice(2,spaceIdx);var nextSpaceIdx=message.indexOf(" ",spaceIdx+1);var callbackId=message.slice(spaceIdx+1,nextSpaceIdx);var payloadKind=message.charAt(nextSpaceIdx+1);var payload;if(payloadKind=="s"){payload=message.slice(nextSpaceIdx+2)}else{if(payloadKind=="t"){payload=true}else{if(payloadKind=="f"){payload=false}else{if(payloadKind=="N"){payload=null}else{if(payloadKind=="n"){payload=+message.slice(nextSpaceIdx+2)}else{if(payloadKind=="A"){var data=message.slice(nextSpaceIdx+2);var bytes=window.atob(data);var arraybuffer=new Uint8Array(bytes.length);for(var i=0;i<bytes.length;i++){arraybuffer[i]=bytes.charCodeAt(i)}payload=arraybuffer.buffer}else{if(payloadKind=="S"){payload=window.atob(message.slice(nextSpaceIdx+2))}else{payload=JSON.parse(message.slice(nextSpaceIdx+1))}}}}}}}cordova.callbackFromNative(callbackId,success,status,[payload],keepCallback)}else{console.log("processMessage failed: invalid message:"+message)}}}catch(e){console.log("processMessage failed: Message: "+message);console.log("processMessage failed: Error: "+e);console.log("processMessage failed: Stack: "+e.stack)}}androidExec.processMessages=function(messages){if(messages){messagesFromNative.push(messages);if(messagesFromNative.length>1){return}while(messagesFromNative.length){messages=messagesFromNative[0];if(messages=="*"){messagesFromNative.shift();window.setTimeout(pollOnce,0);return}var spaceIdx=messages.indexOf(" ");var msgLen=+messages.slice(0,spaceIdx);var message=messages.substr(spaceIdx+1,msgLen);messages=messages.slice(spaceIdx+msgLen+1);processMessage(message);if(messages){messagesFromNative[0]=messages}else{messagesFromNative.shift()}}}};module.exports=androidExec});define("cordova/init",function(require,exports,module){var channel=require("cordova/channel");var cordova=require("cordova");var modulemapper=require("cordova/modulemapper");var platform=require("cordova/platform");var pluginloader=require("cordova/pluginloader");var platformInitChannelsArray=[channel.onNativeReady,channel.onPluginsReady];function logUnfiredChannels(arr){for(var i=0;i<arr.length;++i){if(arr[i].state!=2){console.log("Channel not fired: "+arr[i].type)}}}window.setTimeout(function(){if(channel.onDeviceReady.state!=2){console.log("deviceready has not fired after 5 seconds.");logUnfiredChannels(platformInitChannelsArray);logUnfiredChannels(channel.deviceReadyChannelsArray)}},5000);function replaceNavigator(origNavigator){var CordovaNavigator=function(){};CordovaNavigator.prototype=origNavigator;var newNavigator=new CordovaNavigator();if(CordovaNavigator.bind){for(var key in origNavigator){if(typeof origNavigator[key]=="function"){newNavigator[key]=origNavigator[key].bind(origNavigator)}}}return newNavigator}if(window.navigator){window.navigator=replaceNavigator(window.navigator)}if(!window.console){window.console={log:function(){}}}if(!window.console.warn){window.console.warn=function(msg){this.log("warn: "+msg)}}channel.onPause=cordova.addDocumentEventHandler("pause");channel.onResume=cordova.addDocumentEventHandler("resume");channel.onDeviceReady=cordova.addStickyDocumentEventHandler("deviceready");if(document.readyState=="complete"||document.readyState=="interactive"){channel.onDOMContentLoaded.fire()}else{document.addEventListener("DOMContentLoaded",function(){channel.onDOMContentLoaded.fire()},false)}if(window._nativeReady){channel.onNativeReady.fire()}modulemapper.clobbers("cordova","cordova");modulemapper.clobbers("cordova/exec","cordova.exec");modulemapper.clobbers("cordova/exec","Cordova.exec");platform.bootstrap&&platform.bootstrap();pluginloader.load(function(){channel.onPluginsReady.fire()});channel.join(function(){modulemapper.mapModules(window);platform.initialize&&platform.initialize();channel.onCordovaReady.fire();channel.join(function(){require("cordova").fireDocumentEvent("deviceready")},channel.deviceReadyChannelsArray)},platformInitChannelsArray)});define("cordova/modulemapper",function(require,exports,module){var builder=require("cordova/builder"),moduleMap=define.moduleMap,symbolList,deprecationMap;exports.reset=function(){symbolList=[];deprecationMap={}};function addEntry(strategy,moduleName,symbolPath,opt_deprecationMessage){if(!(moduleName in moduleMap)){throw new Error("Module "+moduleName+" does not exist.")}symbolList.push(strategy,moduleName,symbolPath);if(opt_deprecationMessage){deprecationMap[symbolPath]=opt_deprecationMessage}}exports.clobbers=function(moduleName,symbolPath,opt_deprecationMessage){addEntry("c",moduleName,symbolPath,opt_deprecationMessage)};exports.merges=function(moduleName,symbolPath,opt_deprecationMessage){addEntry("m",moduleName,symbolPath,opt_deprecationMessage)};exports.defaults=function(moduleName,symbolPath,opt_deprecationMessage){addEntry("d",moduleName,symbolPath,opt_deprecationMessage)};exports.runs=function(moduleName){addEntry("r",moduleName,null)};function prepareNamespace(symbolPath,context){if(!symbolPath){return context}var parts=symbolPath.split(".");var cur=context;for(var i=0,part;part=parts[i];++i){cur=cur[part]=cur[part]||{}}return cur}exports.mapModules=function(context){var origSymbols={};context.CDV_origSymbols=origSymbols;for(var i=0,len=symbolList.length;i<len;i+=3){var strategy=symbolList[i];var moduleName=symbolList[i+1];var module=require(moduleName);if(strategy=="r"){continue}var symbolPath=symbolList[i+2];var lastDot=symbolPath.lastIndexOf(".");var namespace=symbolPath.substr(0,lastDot);var lastName=symbolPath.substr(lastDot+1);var deprecationMsg=symbolPath in deprecationMap?"Access made to deprecated symbol: "+symbolPath+". "+deprecationMsg:null;var parentObj=prepareNamespace(namespace,context);var target=parentObj[lastName];if(strategy=="m"&&target){builder.recursiveMerge(target,module)}else{if((strategy=="d"&&!target)||(strategy!="d")){if(!(symbolPath in origSymbols)){origSymbols[symbolPath]=target}builder.assignOrWrapInDeprecateGetter(parentObj,lastName,module,deprecationMsg)}}}};exports.getOriginalSymbol=function(context,symbolPath){var origSymbols=context.CDV_origSymbols;if(origSymbols&&(symbolPath in origSymbols)){return origSymbols[symbolPath]}var parts=symbolPath.split(".");var obj=context;for(var i=0;i<parts.length;++i){obj=obj&&obj[parts[i]]}return obj};exports.reset()});define("cordova/platform",function(require,exports,module){module.exports={id:"android",bootstrap:function(){var channel=require("cordova/channel"),cordova=require("cordova"),exec=require("cordova/exec"),modulemapper=require("cordova/modulemapper");exec(null,null,"PluginManager","startup",[]);channel.onNativeReady.fire();modulemapper.clobbers("cordova/plugin/android/app","navigator.app");var backButtonChannel=cordova.addDocumentEventHandler("backbutton");backButtonChannel.onHasSubscribersChange=function(){exec(null,null,"App","overrideBackbutton",[this.numHandlers==1])};cordova.addDocumentEventHandler("menubutton");cordova.addDocumentEventHandler("searchbutton");channel.onCordovaReady.subscribe(function(){exec(null,null,"App","show",[])})}}});define("cordova/plugin/android/app",function(require,exports,module){var exec=require("cordova/exec");module.exports={clearCache:function(){exec(null,null,"App","clearCache",[])},loadUrl:function(url,props){exec(null,null,"App","loadUrl",[url,props])},cancelLoadUrl:function(){exec(null,null,"App","cancelLoadUrl",[])},clearHistory:function(){exec(null,null,"App","clearHistory",[])},backHistory:function(){exec(null,null,"App","backHistory",[])},overrideBackbutton:function(override){exec(null,null,"App","overrideBackbutton",[override])},exitApp:function(){return exec(null,null,"App","exitApp",[])}}});define("cordova/pluginloader",function(require,exports,module){var modulemapper=require("cordova/modulemapper");function injectScript(url,onload,onerror){var script=document.createElement("script");script.onload=onload;script.onerror=onerror||onload;script.src=url;document.head.appendChild(script)}function onScriptLoadingComplete(moduleList,finishPluginLoading){for(var i=0,module;module=moduleList[i];i++){if(module){try{if(module.clobbers&&module.clobbers.length){for(var j=0;j<module.clobbers.length;j++){modulemapper.clobbers(module.id,module.clobbers[j])}}if(module.merges&&module.merges.length){for(var k=0;k<module.merges.length;k++){modulemapper.merges(module.id,module.merges[k])}}if(module.runs&&!(module.clobbers&&module.clobbers.length)&&!(module.merges&&module.merges.length)){modulemapper.runs(module.id)}}catch(err){}}}finishPluginLoading()}function handlePluginsObject(path,moduleList,finishPluginLoading){var scriptCounter=moduleList.length;if(!scriptCounter){finishPluginLoading();return}function scriptLoadedCallback(){if(!--scriptCounter){onScriptLoadingComplete(moduleList,finishPluginLoading)}}for(var i=0;i<moduleList.length;i++){injectScript(path+moduleList[i].file,scriptLoadedCallback)}}function injectPluginScript(pathPrefix,finishPluginLoading){injectScript(pathPrefix+"cordova_plugins.js",function(){try{var moduleList=require("cordova/plugin_list");handlePluginsObject(pathPrefix,moduleList,finishPluginLoading)}catch(e){finishPluginLoading()}},finishPluginLoading)}function findCordovaPath(){var path=null;var scripts=document.getElementsByTagName("script");var term="cordova.js";for(var n=scripts.length-1;n>-1;n--){var src=scripts[n].src;if(src.indexOf(term)==(src.length-term.length)){path=src.substring(0,src.length-term.length);break}}return path}exports.load=function(callback){var pathPrefix=findCordovaPath();if(pathPrefix===null){console.log("Could not find cordova.js script tag. Plugin loading may fail.");pathPrefix=""}injectPluginScript(pathPrefix,callback)}});define("cordova/urlutil",function(require,exports,module){var urlutil=exports;var anchorEl=document.createElement("a");urlutil.makeAbsolute=function(url){anchorEl.href=url;return anchorEl.href}});define("cordova/utils",function(require,exports,module){var utils=exports;utils.defineGetterSetter=function(obj,key,getFunc,opt_setFunc){if(Object.defineProperty){var desc={get:getFunc,configurable:true};if(opt_setFunc){desc.set=opt_setFunc}Object.defineProperty(obj,key,desc)}else{obj.__defineGetter__(key,getFunc);if(opt_setFunc){obj.__defineSetter__(key,opt_setFunc)}}};utils.defineGetter=utils.defineGetterSetter;utils.arrayIndexOf=function(a,item){if(a.indexOf){return a.indexOf(item)}var len=a.length;for(var i=0;i<len;++i){if(a[i]==item){return i}}return -1};utils.arrayRemove=function(a,item){var index=utils.arrayIndexOf(a,item);if(index!=-1){a.splice(index,1)}return index!=-1};utils.typeName=function(val){return Object.prototype.toString.call(val).slice(8,-1)};utils.isArray=function(a){return utils.typeName(a)=="Array"};utils.isDate=function(d){return utils.typeName(d)=="Date"};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};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)}}};utils.createUUID=function(){return UUIDcreatePart(4)+"-"+UUIDcreatePart(2)+"-"+UUIDcreatePart(2)+"-"+UUIDcreatePart(2)+"-"+UUIDcreatePart(6)};utils.extend=(function(){var F=function(){};return function(Child,Parent){F.prototype=Parent.prototype;Child.prototype=new F();Child.__super__=Parent.prototype;Child.prototype.constructor=Child}}());utils.alert=function(msg){if(window.alert){window.alert(msg)}else{if(console&&console.log){console.log(msg)}}};function UUIDcreatePart(length){var uuidpart="";for(var i=0;i<length;i++){var uuidchar=parseInt((Math.random()*256),10).toString(16);if(uuidchar.length==1){uuidchar="0"+uuidchar}uuidpart+=uuidchar}return uuidpart}});window.cordova=require("cordova");require("cordova/init")})();
var saveToDevice = function(contact) { if (!contact) { return; } var tizenContact = null; var update = false; var i = 0; // if the underlying Tizen Contact object already exists, retrieve it for // update if (contact.id) { // we must attempt to retrieve the BlackBerry contact from the device // because this may be an update operation tizenContact = findByUniqueId(contact.id); } // contact not found on device, create a new one if (!tizenContact) { tizenContact = new tizen.Contact(); } // update the existing contact else { update = true; } // NOTE: The user may be working with a partial Contact object, because only // user-specified Contact fields are returned from a find operation (blame // the W3C spec). If this is an update to an existing Contact, we don't // want to clear an attribute from the contact database simply because the // Contact object that the user passed in contains a null value for that // attribute. So we only copy the non-null Contact attributes to the // Tizen Contact object before saving. // // This means that a user must explicitly set a Contact attribute to a // non-null value in order to update it in the contact database. // traceTizenContact (tizenContact); // display name if (contact.displayName !== null) { if (tizenContact.name === null) { tizenContact.name = new tizen.ContactName(); } if (tizenContact.name !== null) { tizenContact.name.displayName = contact.displayName; } } // name if (contact.name !== null) { if (contact.name.givenName) { if (tizenContact.name === null) { tizenContact.name = new tizen.ContactName(); } if (tizenContact.name !== null) { tizenContact.name.firstName = contact.name.givenName; } } if (contact.name.middleName) { if (tizenContact.name === null) { tizenContact.name = new tizen.ContactName(); } if (tizenContact.name !== null) { tizenContact.name.middleName = contact.name.middleName; } } if (contact.name.familyName) { if (tizenContact.name === null) { tizenContact.name = new tizen.ContactName(); } if (tizenContact.name !== null) { tizenContact.name.lastName = contact.name.familyName; } } if (contact.name.honorificPrefix) { if (tizenContact.name === null) { tizenContact.name = new tizen.ContactName(); } if (tizenContact.name !== null) { tizenContact.name.prefix = contact.name.honorificPrefix; } } } // nickname if (contact.nickname !== null) { if (tizenContact.name === null) { tizenContact.name = new tizen.ContactName(); } if (tizenContact.name !== null) { if (!utils.isArray(tizenContact.name.nicknames)) { tizenContact.name.nicknames = []; } tizenContact.name.nicknames[0] = contact.nickname; } } else { tizenContact.name.nicknames = []; } // note if (contact.note !== null) { if (tizenContact.note === null) { tizenContact.note = []; } if (tizenContact.note !== null) { tizenContact.note[0] = contact.note; } } // photos if (contact.photos && utils.isArray(contact.emails) && contact.emails.length > 0) { tizenContact.photoURI = contact.photos[0]; } if (utils.isDate(contact.birthday)) { if (!utils.isDate(tizenContact.birthday)) { tizenContact.birthday = new Date(); } if (utils.isDate(tizenContact.birthday)) { tizenContact.birthday.setDate(contact.birthday.getDate()); } } // Tizen supports many addresses if (utils.isArray(contact.emails)) { // if this is an update, re initialize email addresses if (update) { // doit on effacer sur un update?????? } // copy the first three email addresses found var emails = []; for (i = 0; i < contact.emails.length; i += 1) { var emailTypes = []; emailTypes.push (contact.emails[i].type); if (contact.emails[i].pref) { emailTypes.push ("PREF"); } emails.push( new tizen.ContactEmailAddress( contact.emails[i].value, emailTypes) ); } tizenContact.emails = emails.length > 0 ? emails : []; } else { tizenContact.emails = []; } // Tizen supports many phone numbers // copy into appropriate fields based on type if (utils.isArray(contact.phoneNumbers)) { // if this is an update, re-initialize phone numbers if (update) { } var phoneNumbers = []; for (i = 0; i < contact.phoneNumbers.length; i += 1) { if (!contact.phoneNumbers[i] || !contact.phoneNumbers[i].value) { continue; } var phoneTypes = []; phoneTypes.push (contact.phoneNumbers[i].type); if (contact.phoneNumbers[i].pref) { phoneTypes.push ("PREF"); } phoneNumbers.push( new tizen.ContactPhoneNumber( contact.phoneNumbers[i].value, phoneTypes) ); } tizenContact.phoneNumbers = phoneNumbers.length > 0 ? phoneNumbers : []; } else { tizenContact.phoneNumbers = []; } if (utils.isArray(contact.addresses)) { // if this is an update, re-initialize addresses if (update) { } var addresses = [], address = null; for ( i = 0; i < contact.addresses.length; i += 1) { address = contact.addresses[i]; if (!address || address.id === undefined || address.pref === undefined || address.type === undefined || address.formatted === undefined) { continue; } var addressTypes = []; addressTypes.push (address.type); if (address.pref) { addressTypes.push ("PREF"); } addresses.push( new tizen.ContactAddress({ country: address.country, region : address.region, city: address.locality, streetAddress: address.streetAddress, additionalInformation: "", postalCode: address.postalCode, types : addressTypes })); } tizenContact.addresses = addresses.length > 0 ? addresses : []; } else{ tizenContact.addresses = []; } // copy first url found to BlackBerry 'webpage' field if (utils.isArray(contact.urls)) { // if this is an update, re-initialize web page if (update) { } var url = null, urls = []; for ( i = 0; i< contact.urls.length; i+= 1) { url = contact.urls[i]; if (!url || !url.value) { continue; } urls.push( new tizen.ContactWebSite(url.value, url.type)); } tizenContact.urls = urls.length > 0 ? urls : []; } else{ tizenContact.urls = []; } if (utils.isArray(contact.organizations && contact.organizations.length > 0) ) { // if this is an update, re-initialize org attributes var organization = contact.organizations[0]; tizenContact.organization = new tizen.ContacOrganization({ name: organization.name, department: organization.department, office: "", title: organization.title, role: "", logoURI: "" }); } // categories if (utils.isArray(contact.categories)) { tizenContact.categories = []; var category = null; for (i = 0; i < contact.categories.length; i += 1) { category = contact.categories[i]; if (typeof category === "string") { tizenContact.categories.push(category); } } } else { tizenContact.categories = []; } // save to device // in tizen contact mean update or add // later we might use addBatch and updateBatch if (update){ tizen.contact.getDefaultAddressBook().update(tizenContact); } else { tizen.contact.getDefaultAddressBook().add(tizenContact); } // Use the fully populated Tizen contact object to create a // corresponding W3C contact object. return ContactUtils.createContact(tizenContact, [ "*" ]); };
var saveToDevice = function(contact) { if (!contact) { return; } var bbContact = null; var update = false; // if the underlying BlackBerry contact already exists, retrieve it for // update if (contact.id) { // we must attempt to retrieve the BlackBerry contact from the device // because this may be an update operation bbContact = findByUniqueId(contact.id); } // contact not found on device, create a new one if (!bbContact) { bbContact = new blackberry.pim.Contact(); } // update the existing contact else { update = true; } // NOTE: The user may be working with a partial Contact object, because only // user-specified Contact fields are returned from a find operation (blame // the W3C spec). If this is an update to an existing Contact, we don't // want to clear an attribute from the contact database simply because the // Contact object that the user passed in contains a null value for that // attribute. So we only copy the non-null Contact attributes to the // BlackBerry contact object before saving. // // This means that a user must explicitly set a Contact attribute to a // non-null value in order to update it in the contact database. // // name if (contact.name !== null) { if (contact.name.givenName) { bbContact.firstName = contact.name.givenName; } if (contact.name.familyName) { bbContact.lastName = contact.name.familyName; } if (contact.name.honorificPrefix) { bbContact.title = contact.name.honorificPrefix; } } // display name if (contact.displayName !== null) { bbContact.user1 = contact.displayName; } // note if (contact.note !== null) { bbContact.note = contact.note; } // birthday // // user may pass in Date object or a string representation of a date // if it is a string, we don't know the date format, so try to create a // new Date with what we're given // // NOTE: BlackBerry's Date.parse() does not work well, so use new Date() // if (contact.birthday !== null) { if (utils.isDate(contact.birthday)) { bbContact.birthday = contact.birthday; } else { var bday = contact.birthday.toString(); bbContact.birthday = (bday.length > 0) ? new Date(bday) : ""; } } // BlackBerry supports three email addresses if (contact.emails && utils.isArray(contact.emails)) { // if this is an update, re-initialize email addresses if (update) { bbContact.email1 = ""; bbContact.email2 = ""; bbContact.email3 = ""; } // copy the first three email addresses found var email = null; for ( var i = 0; i < contact.emails.length; i += 1) { email = contact.emails[i]; if (!email || !email.value) { continue; } if (bbContact.email1 === "") { bbContact.email1 = email.value; } else if (bbContact.email2 === "") { bbContact.email2 = email.value; } else if (bbContact.email3 === "") { bbContact.email3 = email.value; } } } // BlackBerry supports a finite number of phone numbers // copy into appropriate fields based on type if (contact.phoneNumbers && utils.isArray(contact.phoneNumbers)) { // if this is an update, re-initialize phone numbers if (update) { bbContact.homePhone = ""; bbContact.homePhone2 = ""; bbContact.workPhone = ""; bbContact.workPhone2 = ""; bbContact.mobilePhone = ""; bbContact.faxPhone = ""; bbContact.pagerPhone = ""; bbContact.otherPhone = ""; } var type = null; var number = null; for ( var j = 0; j < contact.phoneNumbers.length; j += 1) { if (!contact.phoneNumbers[j] || !contact.phoneNumbers[j].value) { continue; } type = contact.phoneNumbers[j].type; number = contact.phoneNumbers[j].value; if (type === 'home') { if (bbContact.homePhone === "") { bbContact.homePhone = number; } else if (bbContact.homePhone2 === "") { bbContact.homePhone2 = number; } } else if (type === 'work') { if (bbContact.workPhone === "") { bbContact.workPhone = number; } else if (bbContact.workPhone2 === "") { bbContact.workPhone2 = number; } } else if (type === 'mobile' && bbContact.mobilePhone === "") { bbContact.mobilePhone = number; } else if (type === 'fax' && bbContact.faxPhone === "") { bbContact.faxPhone = number; } else if (type === 'pager' && bbContact.pagerPhone === "") { bbContact.pagerPhone = number; } else if (bbContact.otherPhone === "") { bbContact.otherPhone = number; } } } // BlackBerry supports two addresses: home and work // copy the first two addresses found from Contact if (contact.addresses && utils.isArray(contact.addresses)) { // if this is an update, re-initialize addresses if (update) { bbContact.homeAddress = null; bbContact.workAddress = null; } var address = null; var bbHomeAddress = null; var bbWorkAddress = null; for ( var k = 0; k < contact.addresses.length; k += 1) { address = contact.addresses[k]; if (!address || address.id === undefined || address.pref === undefined || address.type === undefined || address.formatted === undefined) { continue; } if (bbHomeAddress === null && (!address.type || address.type === "home")) { bbHomeAddress = createBlackBerryAddress(address); bbContact.homeAddress = bbHomeAddress; } else if (bbWorkAddress === null && (!address.type || address.type === "work")) { bbWorkAddress = createBlackBerryAddress(address); bbContact.workAddress = bbWorkAddress; } } } // copy first url found to BlackBerry 'webpage' field if (contact.urls && utils.isArray(contact.urls)) { // if this is an update, re-initialize web page if (update) { bbContact.webpage = ""; } var url = null; for ( var m = 0; m < contact.urls.length; m += 1) { url = contact.urls[m]; if (!url || !url.value) { continue; } if (bbContact.webpage === "") { bbContact.webpage = url.value; break; } } } // copy fields from first organization to the // BlackBerry 'company' and 'jobTitle' fields if (contact.organizations && utils.isArray(contact.organizations)) { // if this is an update, re-initialize org attributes if (update) { bbContact.company = ""; } var org = null; for ( var n = 0; n < contact.organizations.length; n += 1) { org = contact.organizations[n]; if (!org) { continue; } if (bbContact.company === "") { bbContact.company = org.name || ""; bbContact.jobTitle = org.title || ""; break; } } } // categories if (contact.categories && utils.isArray(contact.categories)) { bbContact.categories = []; var category = null; for ( var o = 0; o < contact.categories.length; o += 1) { category = contact.categories[o]; if (typeof category == "string") { bbContact.categories.push(category); } } } // save to device bbContact.save(); // invoke native side to save photo // fail gracefully if photo URL is no good, but log the error if (contact.photos && utils.isArray(contact.photos)) { var photo = null; for ( var p = 0; p < contact.photos.length; p += 1) { photo = contact.photos[p]; if (!photo || !photo.value) { continue; } exec( // success function() { }, // fail function(e) { console.log('Contact.setPicture failed:' + e); }, "Contacts", "setPicture", [ bbContact.uid, photo.type, photo.value ]); break; } } // Use the fully populated BlackBerry contact object to create a // corresponding W3C contact object. return ContactUtils.createContact(bbContact, [ "*" ]); };