From 1e2c38598f1f194c6f904e9fb13519640ab20a01 Mon Sep 17 00:00:00 2001 From: macdonst Date: Sat, 24 Mar 2012 14:09:57 -0400 Subject: [PATCH 01/11] CB-383: Fixes issue with misspelled destinationType for Camera.getPicture() --- framework/assets/js/cordova.android.js | 3252 ++++++++++++------------ 1 file changed, 1604 insertions(+), 1648 deletions(-) diff --git a/framework/assets/js/cordova.android.js b/framework/assets/js/cordova.android.js index 7f16f2f3..705d4e43 100644 --- a/framework/assets/js/cordova.android.js +++ b/framework/assets/js/cordova.android.js @@ -1,302 +1,25 @@ /* - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. - -============================================================== -This product also include the following software: -============================================================== - --------------------------------------------------------------- -jasmine from GitHub - - https://github.com/pivotal/jasmine - -MIT-style license - -license available from: - - https://github.com/pivotal/jasmine/blob/master/MIT.LICENSE - ------------------------------ - -Copyright (c) 2008-2011 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --------------------------------------------------------------- -commonjs tests from the commonjs organization at GitHub - - https://github.com/commonjs/commonjs - -MIT-style license - -license available from: - - https://github.com/commonjs/commonjs/blob/master/docs/license.html.markdown - -contributor list available from: - - https://github.com/commonjs/commonjs/blob/master/docs/contributors.html.markdown - ------------------------------ - -Copyright 2009 Kevin Dangoor -Copyright 2009 Ihab Awad -Copyright 2009 Ash Berlin -Copyright 2009 Aristid Breitkreuz -Copyright 2009 Kevin Dangoor -Copyright 2009 Daniel Friesen -Copyright 2009 Wes Garland -Copyright 2009 Kris Kowal -Copyright 2009 Dean Landolt -Copyright 2009 Peter Michaux -Copyright 2009 George Moschovitis -Copyright 2009 Michael O'Brien -Copyright 2009 Tom Robinson -Copyright 2009 Hannes Wallnoefer -Copyright 2009 Mike Wilson -Copyright 2009 Ondrej Zara -Copyright 2009 Chris Zumbrunn -Copyright 2009 Kris Zyp - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - + 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() { + +;(function() { + +// file: lib/scripts/require.js var require, define; @@ -316,7 +39,7 @@ var require, throw "module " + id + " not found"; } return modules[id].factory ? build(modules[id]) : modules[id].exports; - } + }; define = function (id, factory) { if (modules[id]) { @@ -327,7 +50,7 @@ var require, id: id, factory: factory }; - } + }; define.remove = function (id) { delete modules[id]; @@ -341,154 +64,8 @@ if (typeof module === "object" && typeof require === "function") { module.exports.define = define; } -define('cordova/channel', function(require, exports, module) { -/** - * Custom pub-sub channel that can have functions subscribed to it - * @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 = 0; - 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) { - eval("var v="+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]; - } +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 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); - } + 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); + } + }; + } }; -}); -define('cordova/common', function(require, exports, module) { +}) + +// file: lib/common/channel.js +define("cordova/channel", function(require, exports, module) { +/** + * Custom pub-sub channel that can have functions subscribed to it + * @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 = 0; + 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) { + eval("var v="+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; } - } - }, - navigator: { - children: { - app:{ - path: "cordova/plugin/android/app" + + // 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; } - } - }, - device:{ - path: "cordova/plugin/android/device" - }, - 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" } + } catch (e2) { + console.log("Error: "+e2); } }; -}); -define('cordova/utils', function(require, exports, module) { -function UUIDcreatePart(length) { - var uuidpart = ""; - for (var i=0; i frequency + 10 sec - exec( - function(timeout) { - if (timeout < (frequency + 10000)) { - exec(null, null, "Accelerometer", "setTimeout", [frequency + 10000]); - } - }, - function(e) { }, "Accelerometer", "getTimeout", []); - - // Start watch timer - var id = utils.createUUID(); - timers[id] = window.setInterval(function() { - exec(successCallback, errorCallback, "Accelerometer", "getAcceleration", []); - }, (frequency ? frequency : 1)); - - 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] !== undefined) { - window.clearInterval(timers[id]); - delete timers[id]; - } - } -}; - -module.exports = accelerometer; - -}); - - -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; - -}); - - -define('cordova/plugin/Camera', function(require, exports, module) { +// file: lib/common/plugin/Camera.js +define("cordova/plugin/Camera", function(require, exports, module) { var exec = require('cordova/exec'), Camera = require('cordova/plugin/CameraConstants'); @@ -1522,7 +1070,7 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) { } } - var destinationType = Camera.DestinationType.FILE_URL; + var destinationType = Camera.DestinationType.FILE_URI; if (typeof options.destinationType == "number") { destinationType = options.destinationType; } @@ -1564,9 +1112,10 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) { module.exports = cameraExport; -}); +}) -define('cordova/plugin/CameraConstants', function(require, exports, module) { +// file: lib/common/plugin/CameraConstants.js +define("cordova/plugin/CameraConstants", function(require, exports, module) { module.exports = { DestinationType:{ DATA_URL: 0, // Return base64 encoded string @@ -1588,85 +1137,10 @@ module.exports = { } }; -}); +}) -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(); - -}); - -define('cordova/plugin/CaptureAudioOptions', function(require, exports, module) { +// file: lib/common/plugin/CaptureAudioOptions.js +define("cordova/plugin/CaptureAudioOptions", function(require, exports, module) { /** * Encapsulates all audio capture operation configuration options. */ @@ -1681,9 +1155,10 @@ var CaptureAudioOptions = function(){ module.exports = CaptureAudioOptions; -}); +}) -define('cordova/plugin/CaptureError', function(require, exports, module) { +// file: lib/common/plugin/CaptureError.js +define("cordova/plugin/CaptureError", function(require, exports, module) { /** * The CaptureError interface encapsulates all errors in the Capture API. */ @@ -1704,9 +1179,10 @@ CaptureError.CAPTURE_NOT_SUPPORTED = 20; module.exports = CaptureError; -}); +}) -define('cordova/plugin/CaptureImageOptions', function(require, exports, module) { +// file: lib/common/plugin/CaptureImageOptions.js +define("cordova/plugin/CaptureImageOptions", function(require, exports, module) { /** * Encapsulates all image capture operation configuration options. */ @@ -1719,9 +1195,10 @@ var CaptureImageOptions = function(){ module.exports = CaptureImageOptions; -}); +}) -define('cordova/plugin/CaptureVideoOptions', function(require, exports, module) { +// file: lib/common/plugin/CaptureVideoOptions.js +define("cordova/plugin/CaptureVideoOptions", function(require, exports, module) { /** * Encapsulates all video capture operation configuration options. */ @@ -1736,103 +1213,10 @@ var CaptureVideoOptions = function(){ module.exports = CaptureVideoOptions; -}); +}) -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) { - // 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", []); - }, - - /** - * 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. - */ - watchHeading:function(successCallback, errorCallback, options) { - // Default interval (100 msec) - var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100; - - // 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; - } - - // Start watch timer to get headings - var id = utils.createUUID(); - - 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]) { - clearInterval(timers[id]); - delete timers[id]; - } - } - // TODO: add the filter-based iOS-only methods - }; - -module.exports = compass; - -}); - -define('cordova/plugin/CompassError', function(require, exports, module) { +// 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 @@ -1847,9 +1231,10 @@ CompassError.COMPASS_NOT_SUPPORTED = 20; module.exports = CompassError; -}); +}) -define('cordova/plugin/CompassHeading', function(require, exports, module) { +// 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); @@ -1859,9 +1244,10 @@ var CompassHeading = function(magneticHeading, trueHeading, headingAccuracy, tim module.exports = CompassHeading; -}); +}) -define('cordova/plugin/ConfigurationData', function(require, exports, module) { +// file: lib/common/plugin/ConfigurationData.js +define("cordova/plugin/ConfigurationData", function(require, exports, module) { /** * Encapsulates a set of parameters that the capture device supports. */ @@ -1878,9 +1264,10 @@ function ConfigurationData() { module.exports = ConfigurationData; -}); +}) -define('cordova/plugin/Connection', function(require, exports, module) { +// file: lib/common/plugin/Connection.js +define("cordova/plugin/Connection", function(require, exports, module) { /** * Network status */ @@ -1894,13 +1281,52 @@ module.exports = { NONE: "none" }; -}); +}) -define('cordova/plugin/Contact', function(require, exports, module) { +// 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 (!value instanceof Date){ + try { + value = new Date(value); + } catch(exception){ + value = null; + } + } + if (value instanceof Date){ + value = value.valueOf(); // convert to milliseconds + } + contact.birthday = value; + } + return contact; +}; + /** * Contains information about a single contact. * @constructor @@ -1926,16 +1352,16 @@ var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, a this.displayName = displayName || null; this.name = name || null; // ContactName this.nickname = nickname || null; - this.phoneNumbers = phoneNumbers || []; // ContactField[] - this.emails = emails || []; // ContactField[] - this.addresses = addresses || []; // ContactAddress[] - this.ims = ims || []; // ContactField[] - this.organizations = organizations || []; // ContactOrganization[] + 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 || []; // ContactField[] - this.categories = categories || []; // ContactField[] - this.urls = urls || []; // ContactField[] + this.photos = photos || null; // ContactField[] + this.categories = categories || null; // ContactField[] + this.urls = urls || null; // ContactField[] }; /** @@ -1944,12 +1370,14 @@ var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, a * @param errorCB error callback */ Contact.prototype.remove = function(successCB, errorCB) { + var fail = function(code) { + errorCB(new ContactError(code)); + }; if (this.id === null) { - var errorObj = new ContactError(ContactError.UNKNOWN_ERROR); - errorCB(errorObj); + fail(ContactError.UNKNOWN_ERROR); } else { - exec(successCB, errorCB, "Contacts", "remove", [this.id]); + exec(successCB, fail, "Contacts", "remove", [this.id]); } }; @@ -2013,15 +1441,32 @@ Contact.prototype.clone = function() { * @param errorCB error callback */ Contact.prototype.save = function(successCB, errorCB) { - exec(successCB, errorCB, "Contacts", "save", [this]); + 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; -}); +}) -define('cordova/plugin/ContactAddress', function(require, exports, module) { +// file: lib/common/plugin/ContactAddress.js +define("cordova/plugin/ContactAddress", function(require, exports, module) { /** * Contact address. * @constructor @@ -2048,9 +1493,10 @@ var ContactAddress = function(pref, type, formatted, streetAddress, locality, re module.exports = ContactAddress; -}); +}) -define('cordova/plugin/ContactError', function(require, exports, module) { +// 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 @@ -2073,9 +1519,10 @@ ContactError.PERMISSION_DENIED_ERROR = 20; module.exports = ContactError; -}); +}) -define('cordova/plugin/ContactField', function(require, exports, module) { +// file: lib/common/plugin/ContactField.js +define("cordova/plugin/ContactField", function(require, exports, module) { /** * Generic contact field. * @constructor @@ -2093,9 +1540,10 @@ var ContactField = function(type, value, pref) { module.exports = ContactField; -}); +}) -define('cordova/plugin/ContactFindOptions', function(require, exports, module) { +// file: lib/common/plugin/ContactFindOptions.js +define("cordova/plugin/ContactFindOptions", function(require, exports, module) { /** * ContactFindOptions. * @constructor @@ -2110,9 +1558,10 @@ var ContactFindOptions = function(filter, multiple) { module.exports = ContactFindOptions; -}); +}) -define('cordova/plugin/ContactName', function(require, exports, module) { +// file: lib/common/plugin/ContactName.js +define("cordova/plugin/ContactName", function(require, exports, module) { /** * Contact name. * @constructor @@ -2134,9 +1583,10 @@ var ContactName = function(formatted, familyName, givenName, middle, prefix, suf module.exports = ContactName; -}); +}) -define('cordova/plugin/ContactOrganization', function(require, exports, module) { +// file: lib/common/plugin/ContactOrganization.js +define("cordova/plugin/ContactOrganization", function(require, exports, module) { /** * Contact organization. * @constructor @@ -2161,70 +1611,10 @@ var ContactOrganization = function(pref, type, name, dept, title) { module.exports = ContactOrganization; -}); +}) -define('cordova/plugin/contacts', function(require, exports, module) { -var exec = require('cordova/exec'), - ContactError = require('cordova/plugin/ContactError'), - 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 || (fields instanceof Array && 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; - -}); - -define('cordova/plugin/Coordinates', function(require, exports, module) { +// file: lib/common/plugin/Coordinates.js +define("cordova/plugin/Coordinates", function(require, exports, module) { /** * This class contains position information. * @param {Object} lat @@ -2269,9 +1659,10 @@ var Coordinates = function(lat, lng, alt, acc, head, vel, altacc) { module.exports = Coordinates; -}); +}) -define('cordova/plugin/DirectoryEntry', function(require, exports, module) { +// 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'), @@ -2353,9 +1744,10 @@ DirectoryEntry.prototype.getFile = function(path, options, successCallback, erro module.exports = DirectoryEntry; -}); +}) -define('cordova/plugin/DirectoryReader', function(require, exports, module) { +// file: lib/common/plugin/DirectoryReader.js +define("cordova/plugin/DirectoryReader", function(require, exports, module) { var exec = require('cordova/exec'); /** @@ -2398,9 +1790,10 @@ DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) module.exports = DirectoryReader; -}); +}) -define('cordova/plugin/Entry', function(require, exports, module) { +// file: lib/common/plugin/Entry.js +define("cordova/plugin/Entry", function(require, exports, module) { var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError'), Metadata = require('cordova/plugin/Metadata'); @@ -2600,9 +1993,10 @@ Entry.prototype.getParent = function(successCallback, errorCallback) { module.exports = Entry; -}); +}) -define('cordova/plugin/File', function(require, exports, module) { +// file: lib/common/plugin/File.js +define("cordova/plugin/File", function(require, exports, module) { /** * Constructor. * name {DOMString} name of the file, without path information @@ -2622,9 +2016,10 @@ var File = function(name, fullPath, type, lastModifiedDate, size){ module.exports = File; -}); +}) -define('cordova/plugin/FileEntry', function(require, exports, module) { +// file: lib/common/plugin/FileEntry.js +define("cordova/plugin/FileEntry", function(require, exports, module) { var utils = require('cordova/utils'), exec = require('cordova/exec'), Entry = require('cordova/plugin/Entry'), @@ -2689,9 +2084,10 @@ FileEntry.prototype.file = function(successCallback, errorCallback) { module.exports = FileEntry; -}); +}) -define('cordova/plugin/FileError', function(require, exports, module) { +// file: lib/common/plugin/FileError.js +define("cordova/plugin/FileError", function(require, exports, module) { /** * FileError */ @@ -2718,9 +2114,10 @@ FileError.PATH_EXISTS_ERR = 12; module.exports = FileError; -}); +}) -define('cordova/plugin/FileReader', function(require, exports, module) { +// file: lib/common/plugin/FileReader.js +define("cordova/plugin/FileReader", function(require, exports, module) { var exec = require('cordova/exec'), FileError = require('cordova/plugin/FileError'), ProgressEvent = require('cordova/plugin/ProgressEvent'); @@ -2821,6 +2218,7 @@ FileReader.prototype.readAsText = function(file, encoding) { if (me.readyState === FileReader.DONE) { return; } + // Save result me.result = r; @@ -2955,7 +2353,7 @@ FileReader.prototype.readAsDataURL = function(file) { */ FileReader.prototype.readAsBinaryString = function(file) { // TODO - Can't return binary data to browser. - console.log('This method is not supported at this time.'); + console.log('method "readAsBinaryString" is not supported at this time.'); }; /** @@ -2970,9 +2368,10 @@ FileReader.prototype.readAsArrayBuffer = function(file) { module.exports = FileReader; -}); +}) -define('cordova/plugin/FileSystem', function(require, exports, module) { +// file: lib/common/plugin/FileSystem.js +define("cordova/plugin/FileSystem", function(require, exports, module) { var DirectoryEntry = require('cordova/plugin/DirectoryEntry'); /** @@ -2991,9 +2390,10 @@ var FileSystem = function(name, root) { module.exports = FileSystem; -}); +}) -define('cordova/plugin/FileTransfer', function(require, exports, module) { +// file: lib/common/plugin/FileTransfer.js +define("cordova/plugin/FileTransfer", function(require, exports, module) { var exec = require('cordova/exec'); /** @@ -3063,9 +2463,10 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro module.exports = FileTransfer; -}); +}) -define('cordova/plugin/FileTransferError', function(require, exports, module) { +// file: lib/common/plugin/FileTransferError.js +define("cordova/plugin/FileTransferError", function(require, exports, module) { /** * FileTransferError * @constructor @@ -3080,9 +2481,10 @@ FileTransferError.CONNECTION_ERR = 3; module.exports = FileTransferError; -}); +}) -define('cordova/plugin/FileUploadOptions', function(require, exports, module) { +// 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 @@ -3100,9 +2502,10 @@ var FileUploadOptions = function(fileKey, fileName, mimeType, params) { module.exports = FileUploadOptions; -}); +}) -define('cordova/plugin/FileUploadResult', function(require, exports, module) { +// file: lib/common/plugin/FileUploadResult.js +define("cordova/plugin/FileUploadResult", function(require, exports, module) { /** * FileUploadResult * @constructor @@ -3115,9 +2518,10 @@ var FileUploadResult = function() { module.exports = FileUploadResult; -}); +}) -define('cordova/plugin/FileWriter', function(require, exports, module) { +// 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'); @@ -3372,9 +2776,10 @@ FileWriter.prototype.truncate = function(size) { module.exports = FileWriter; -}); +}) -define('cordova/plugin/Flags', function(require, exports, module) { +// 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. * @@ -3391,108 +2796,10 @@ function Flags(create, exclusive) { module.exports = Flags; -}); +}) -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: 10000, - enableHighAccuracy: false, - timeout: 10000 - }; - - if (options) { - if (options.maximumAge !== undefined) { - opt.maximumAge = options.maximumAge; - } - if (options.enableHighAccuracy !== undefined) { - opt.enableHighAccuracy = options.enableHighAccuracy; - } - if (options.timeout !== undefined) { - opt.timeout = options.timeout; - } - } - - return opt; -} - -var geolocation = { - /** - * 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) { - options = parseParameters(options); - - var win = function(p) { - successCallback(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 || new Date() - )); - }; - var fail = function(e) { - errorCallback(new PositionError(e.code, e.message)); - }; - - exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.timeout, options.maximumAge]); - }, - /** - * 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) { - options = parseParameters(options); - - var id = utils.createUUID(); - timers[id] = window.setInterval(function() { - geolocation.getCurrentPosition(successCallback, errorCallback, options); - }, options.timeout); - - 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) { - window.clearInterval(timers[id]); - delete timers[id]; - } - } -}; - -module.exports = geolocation; - -}); - - -define('cordova/plugin/LocalFileSystem', function(require, exports, module) { +// file: lib/common/plugin/LocalFileSystem.js +define("cordova/plugin/LocalFileSystem", function(require, exports, module) { var exec = require('cordova/exec'); /** @@ -3507,9 +2814,10 @@ LocalFileSystem.PERSISTENT = 1; //persistent module.exports = LocalFileSystem; -}); +}) -define('cordova/plugin/Media', function(require, exports, module) { +// file: lib/common/plugin/Media.js +define("cordova/plugin/Media", function(require, exports, module) { var utils = require('cordova/utils'), exec = require('cordova/exec'); @@ -3580,8 +2888,8 @@ Media.get = function(id) { /** * Start or resume playing audio file. */ -Media.prototype.play = function() { - exec(this.successCallback, this.errorCallback, "Media", "startPlayingAudio", [this.id, this.src]); +Media.prototype.play = function(options) { + exec(this.successCallback, this.errorCallback, "Media", "startPlayingAudio", [this.id, this.src, options]); }; /** @@ -3687,7 +2995,8 @@ Media.onStatus = function(id, msg, value) { } else if (msg === Media.MEDIA_ERROR) { if (media.errorCallback) { - media.errorCallback({"code":value}); + // value should be a MediaError object when msg == MEDIA_ERROR + media.errorCallback(value); } } else if (msg === Media.MEDIA_POSITION) { @@ -3697,15 +3006,16 @@ Media.onStatus = function(id, msg, value) { module.exports = Media; -}); +}) -define('cordova/plugin/MediaError', function(require, exports, module) { +// 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 || null; + this.code = (code !== undefined ? code : null); this.message = msg || ""; }; @@ -3717,9 +3027,10 @@ MediaError.MEDIA_ERR_NONE_SUPPORTED = 4; module.exports = MediaError; -}); +}) -define('cordova/plugin/MediaFile', function(require, exports, module) { +// 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'), @@ -3777,9 +3088,10 @@ MediaFile.cast = function(pluginResult) { module.exports = MediaFile; -}); +}) -define('cordova/plugin/MediaFileData', function(require, exports, module) { +// file: lib/common/plugin/MediaFileData.js +define("cordova/plugin/MediaFileData", function(require, exports, module) { /** * MediaFileData encapsulates format information of a media file. * @@ -3799,9 +3111,10 @@ var MediaFileData = function(codecs, bitrate, height, width, duration){ module.exports = MediaFileData; -}); +}) -define('cordova/plugin/Metadata', function(require, exports, module) { +// file: lib/common/plugin/Metadata.js +define("cordova/plugin/Metadata", function(require, exports, module) { /** * Information about the state of the file or directory * @@ -3813,133 +3126,10 @@ var Metadata = function(time) { module.exports = Metadata; -}); +}) -define('cordova/plugin/network', function(require, exports, module) { -var exec = require('cordova/exec'), - cordova = require('cordova'), - channel = require('cordova/channel'); - -var NetworkConnection = function () { - this.type = null; - this._firstRun = true; - this._timer = null; - this.timeout = 500; - - var me = this; - - this.getInfo( - function (info) { - me.type = info; - if (info === "none") { - // set a timer if still offline at the end of timer send the offline event - me._timer = setTimeout(function(){ - cordova.fireDocumentEvent("offline"); - me._timer = null; - }, me.timeout); - } else { - // If there is a current offline event pending clear it - if (me._timer !== null) { - clearTimeout(me._timer); - me._timer = null; - } - cordova.fireDocumentEvent("online"); - } - - // should only fire this once - if (me._firstRun) { - me._firstRun = false; - channel.onCordovaConnectionReady.fire(); - } - }, - function (e) { - // If we can't get the network info we should still tell Cordova - // to fire the deviceready event. - if (me._firstRun) { - me._firstRun = false; - channel.onCordovaConnectionReady.fire(); - } - console.log("Error initializing Network Connection: " + e); - }); -}; - -/** - * Get connection info - * - * @param {Function} successCallback The function to call when the Connection data is available - * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL) - */ -NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) { - // Get info - exec(successCallback, errorCallback, "Network Status", "getConnectionInfo", []); -}; - -module.exports = new NetworkConnection(); - -}); - -define('cordova/plugin/notification', function(require, exports, module) { -var exec = require('cordova/exec'); - -/** - * Provides access to notifications on the device. - */ - -module.exports = { - - /** - * Open a native alert dialog, with a customizable title and button text. - * - * @param {String} message Message to print in the body of the alert - * @param {Function} completeCallback The callback that is called when user clicks on a button. - * @param {String} title Title of the alert dialog (default: Alert) - * @param {String} buttonLabel Label of the close button (default: OK) - */ - alert: function(message, completeCallback, title, buttonLabel) { - var _title = (title || "Alert"); - var _buttonLabel = (buttonLabel || "OK"); - exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]); - }, - - /** - * Open a native confirm dialog, with a customizable title and button text. - * The result that the user selects is returned to the result callback. - * - * @param {String} message Message to print in the body of the alert - * @param {Function} resultCallback The callback that is called when user clicks on a button. - * @param {String} title Title of the alert dialog (default: Confirm) - * @param {String} buttonLabels Comma separated list of the labels of the buttons (default: 'OK,Cancel') - */ - confirm: function(message, resultCallback, title, buttonLabels) { - var _title = (title || "Confirm"); - var _buttonLabels = (buttonLabels || "OK,Cancel"); - exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]); - }, - - /** - * Causes the device to vibrate. - * - * @param {Integer} mills The number of milliseconds to vibrate for. - */ - vibrate: function(mills) { - exec(null, null, "Notification", "vibrate", [mills]); - }, - - /** - * Causes the device to beep. - * On Android, the default notification ringtone is played "count" times. - * - * @param {Integer} count The number of beeps. - */ - beep: function(count) { - exec(null, null, "Notification", "beep", [count]); - } -}; - -}); - - -define('cordova/plugin/Position', function(require, exports, module) { +// file: lib/common/plugin/Position.js +define("cordova/plugin/Position", function(require, exports, module) { var Coordinates = require('cordova/plugin/Coordinates'); var Position = function(coords, timestamp) { @@ -3949,9 +3139,10 @@ var Position = function(coords, timestamp) { module.exports = Position; -}); +}) -define('cordova/plugin/PositionError', function(require, exports, module) { +// file: lib/common/plugin/PositionError.js +define("cordova/plugin/PositionError", function(require, exports, module) { /** * Position error object * @@ -3970,9 +3161,10 @@ PositionError.TIMEOUT = 3; module.exports = PositionError; -}); +}) -define('cordova/plugin/ProgressEvent', function(require, exports, module) { +// file: lib/common/plugin/ProgressEvent.js +define("cordova/plugin/ProgressEvent", function(require, exports, module) { // If ProgressEvent exists in global context, use it already, otherwise use our own polyfill // Feature test: See if we can instantiate a native ProgressEvent; // if so, use that approach, @@ -4020,99 +3212,110 @@ var ProgressEvent = (function() { module.exports = ProgressEvent; -}); - -define('cordova/plugin/requestFileSystem', function(require, exports, module) { -var FileError = require('cordova/plugin/FileError'), - FileSystem = require('cordova/plugin/FileSystem'), - exec = require('cordova/exec'); +}) +// file: lib/common/plugin/accelerometer.js +define("cordova/plugin/accelerometer", function(require, exports, module) { /** - * Request a file system in which to store application data. - * @param type local file system type - * @param size indicates how much storage space, in bytes, the application expects to need - * @param successCallback invoked with a FileSystem object - * @param errorCallback invoked if error occurs retrieving file system + * This class provides access to device accelerometer data. + * @constructor */ -var requestFileSystem = function(type, size, successCallback, errorCallback) { - var fail = function(code) { - if (typeof errorCallback === 'function') { - errorCallback(new FileError(code)); - } - }; +var utils = require("cordova/utils"), + exec = require("cordova/exec"); - if (type < 0 || type > 3) { - fail(FileError.SYNTAX_ERR); - } else { - // if successful, return a FileSystem object - var success = function(file_system) { - if (file_system) { - if (typeof successCallback === 'function') { - // grab the name and root from the file system object - var result = new FileSystem(file_system.name, file_system.root); - successCallback(result); +// Local singleton variables. +var timers = {}; + +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") { + console.log("Accelerometer Error: successCallback is not a function"); + return; + } + + // errorCallback optional + if (errorCallback && (typeof errorCallback !== "function")) { + console.log("Accelerometer Error: errorCallback is not a function"); + return; + } + + // Get acceleration + exec(successCallback, errorCallback, "Accelerometer", "getAcceleration", []); + }, + + /** + * 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 !== undefined && options.frequency !== undefined)? options.frequency : 10000; + + // successCallback required + if (typeof successCallback !== "function") { + console.log("Accelerometer Error: successCallback is not a function"); + return; + } + + // errorCallback optional + if (errorCallback && (typeof errorCallback !== "function")) { + console.log("Accelerometer Error: errorCallback is not a function"); + return; + } + + // Make sure accelerometer timeout > frequency + 10 sec + exec( + function(timeout) { + if (timeout < (frequency + 10000)) { + exec(null, null, "Accelerometer", "setTimeout", [frequency + 10000]); } - } - else { - // no FileSystem object returned - fail(FileError.NOT_FOUND_ERR); - } - }; - exec(success, fail, "File", "requestFileSystem", [type, size]); + }, + function(e) { }, "Accelerometer", "getTimeout", []); + + // Start watch timer + var id = utils.createUUID(); + timers[id] = window.setInterval(function() { + exec(successCallback, errorCallback, "Accelerometer", "getAcceleration", []); + }, (frequency ? frequency : 1)); + + 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] !== undefined) { + window.clearInterval(timers[id]); + delete timers[id]; + } } }; -module.exports = requestFileSystem; +module.exports = accelerometer; -}); +}) -define('cordova/plugin/resolveLocalFileSystemURI', function(require, exports, module) { -var DirectoryEntry = require('cordova/plugin/DirectoryEntry'), - FileEntry = require('cordova/plugin/FileEntry'), - 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)); - } - }; - // 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]); -}; - -}); - - -define('cordova/plugin/android/app', function(require, exports, module) { +// file: lib/android/plugin/android/app.js +define("cordova/plugin/android/app", function(require, exports, module) { var exec = require('cordova/exec'); module.exports = { @@ -4185,9 +3388,10 @@ module.exports = { } }; -}); +}) -define('cordova/plugin/android/callback', function(require, exports, module) { +// file: lib/android/plugin/android/callback.js +define("cordova/plugin/android/callback", function(require, exports, module) { var port = null, token = null, cordova = require('cordova'), @@ -4274,9 +3478,10 @@ var port = null, module.exports = callback; -}); +}) -define('cordova/plugin/android/device', function(require, exports, module) { +// file: lib/android/plugin/android/device.js +define("cordova/plugin/android/device", function(require, exports, module) { var channel = require('cordova/channel'), exec = require('cordova/exec'); @@ -4370,9 +3575,10 @@ Device.prototype.exitApp = function() { module.exports = new Device(); -}); +}) -define('cordova/plugin/android/polling', function(require, exports, module) { +// file: lib/android/plugin/android/polling.js +define("cordova/plugin/android/polling", function(require, exports, module) { var cordova = require('cordova'), period = 50, polling = function() { @@ -4407,11 +3613,13 @@ var cordova = require('cordova'), module.exports = polling; -}); +}) -define('cordova/plugin/android/storage', function(require, exports, module) { +// 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 = {}; @@ -4699,6 +3907,8 @@ var DroidDB_openDatabase = function(name, version, display_name, size) { * @constructor */ var CupcakeLocalStorage = function() { + channel.waitForInitialization("cupcakeStorage"); + try { this.db = openDatabase('localStorage', '1.0', 'localStorage', 2621440); @@ -4717,6 +3927,7 @@ var CupcakeLocalStorage = function() { storage[result.rows.item(i)['id']] = result.rows.item(i)['body']; } setLength(result.rows.length); + channel.initializationComplete("cupcakeStorage"); }); }, @@ -4784,15 +3995,754 @@ module.exports = { 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) { + // 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", []); + }, + + /** + * 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. + */ + watchHeading:function(successCallback, errorCallback, options) { + // Default interval (100 msec) + var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100; + + // 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; + } + + // Start watch timer to get headings + var id = utils.createUUID(); + + 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]) { + clearInterval(timers[id]); + delete timers[id]; + } + } + // TODO: add the filter-based iOS-only methods + }; + +module.exports = compass; + +}) + +// file: lib/common/plugin/contacts.js +define("cordova/plugin/contacts", function(require, exports, module) { +var exec = require('cordova/exec'), + ContactError = require('cordova/plugin/ContactError'), + 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 || (fields instanceof Array && 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/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: 10000, + enableHighAccuracy: false, + timeout: 10000 + }; + + if (options) { + if (options.maximumAge !== undefined) { + opt.maximumAge = options.maximumAge; + } + if (options.enableHighAccuracy !== undefined) { + opt.enableHighAccuracy = options.enableHighAccuracy; + } + if (options.timeout !== undefined) { + opt.timeout = options.timeout; + } + } + + return opt; +} + +var geolocation = { + /** + * 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) { + options = parseParameters(options); + + var win = function(p) { + successCallback(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 || new Date() + )); + }; + var fail = function(e) { + errorCallback(new PositionError(e.code, e.message)); + }; + + exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.timeout, options.maximumAge]); + }, + /** + * 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) { + options = parseParameters(options); + + var id = utils.createUUID(); + timers[id] = window.setInterval(function() { + geolocation.getCurrentPosition(successCallback, errorCallback, options); + }, options.timeout); + + 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) { + window.clearInterval(timers[id]); + delete timers[id]; + } + } +}; + +module.exports = geolocation; + +}) + +// file: lib/common/plugin/network.js +define("cordova/plugin/network", function(require, exports, module) { +var exec = require('cordova/exec'), + cordova = require('cordova'), + channel = require('cordova/channel'); + +var NetworkConnection = function () { + this.type = null; + this._firstRun = true; + this._timer = null; + this.timeout = 500; + + var me = this; + + this.getInfo( + function (info) { + me.type = info; + if (info === "none") { + // set a timer if still offline at the end of timer send the offline event + me._timer = setTimeout(function(){ + cordova.fireDocumentEvent("offline"); + me._timer = null; + }, me.timeout); + } else { + // If there is a current offline event pending clear it + if (me._timer !== null) { + clearTimeout(me._timer); + me._timer = null; + } + cordova.fireDocumentEvent("online"); + } + + // should only fire this once + if (me._firstRun) { + me._firstRun = false; + channel.onCordovaConnectionReady.fire(); + } + }, + function (e) { + // If we can't get the network info we should still tell Cordova + // to fire the deviceready event. + if (me._firstRun) { + me._firstRun = false; + channel.onCordovaConnectionReady.fire(); + } + console.log("Error initializing Network Connection: " + e); + }); +}; + +/** + * Get connection info + * + * @param {Function} successCallback The function to call when the Connection data is available + * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL) + */ +NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) { + // Get info + exec(successCallback, errorCallback, "Network Status", "getConnectionInfo", []); +}; + +module.exports = new NetworkConnection(); + +}) + +// file: lib/common/plugin/notification.js +define("cordova/plugin/notification", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * Provides access to notifications on the device. + */ + +module.exports = { + + /** + * Open a native alert dialog, with a customizable title and button text. + * + * @param {String} message Message to print in the body of the alert + * @param {Function} completeCallback The callback that is called when user clicks on a button. + * @param {String} title Title of the alert dialog (default: Alert) + * @param {String} buttonLabel Label of the close button (default: OK) + */ + alert: function(message, completeCallback, title, buttonLabel) { + var _title = (title || "Alert"); + var _buttonLabel = (buttonLabel || "OK"); + exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]); + }, + + /** + * Open a native confirm dialog, with a customizable title and button text. + * The result that the user selects is returned to the result callback. + * + * @param {String} message Message to print in the body of the alert + * @param {Function} resultCallback The callback that is called when user clicks on a button. + * @param {String} title Title of the alert dialog (default: Confirm) + * @param {String} buttonLabels Comma separated list of the labels of the buttons (default: 'OK,Cancel') + */ + confirm: function(message, resultCallback, title, buttonLabels) { + var _title = (title || "Confirm"); + var _buttonLabels = (buttonLabels || "OK,Cancel"); + exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]); + }, + + /** + * Causes the device to vibrate. + * + * @param {Integer} mills The number of milliseconds to vibrate for. + */ + vibrate: function(mills) { + exec(null, null, "Notification", "vibrate", [mills]); + }, + + /** + * Causes the device to beep. + * On Android, the default notification ringtone is played "count" times. + * + * @param {Integer} count The number of beeps. + */ + beep: function(count) { + exec(null, null, "Notification", "beep", [count]); + } +}; + +}) + +// file: lib/common/plugin/requestFileSystem.js +define("cordova/plugin/requestFileSystem", function(require, exports, module) { +var FileError = require('cordova/plugin/FileError'), + FileSystem = require('cordova/plugin/FileSystem'), + exec = require('cordova/exec'); + +/** + * Request a file system in which to store application data. + * @param type local file system type + * @param size indicates how much storage space, in bytes, the application expects to need + * @param successCallback invoked with a FileSystem object + * @param errorCallback invoked if error occurs retrieving file system + */ +var requestFileSystem = function(type, size, successCallback, errorCallback) { + var fail = function(code) { + if (typeof errorCallback === 'function') { + errorCallback(new FileError(code)); + } + }; + + if (type < 0 || type > 3) { + fail(FileError.SYNTAX_ERR); + } else { + // if successful, return a FileSystem object + var success = function(file_system) { + if (file_system) { + if (typeof successCallback === 'function') { + // grab the name and root from the file system object + var result = new FileSystem(file_system.name, file_system.root); + successCallback(result); + } + } + else { + // no FileSystem object returned + fail(FileError.NOT_FOUND_ERR); + } + }; + exec(success, fail, "File", "requestFileSystem", [type, size]); + } +}; + +module.exports = requestFileSystem; + +}) + +// file: lib/common/plugin/resolveLocalFileSystemURI.js +define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) { +var DirectoryEntry = require('cordova/plugin/DirectoryEntry'), + FileEntry = require('cordova/plugin/FileEntry'), + 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)); + } + }; + // 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/utils.js +define("cordova/utils", function(require, exports, module) { +function UUIDcreatePart(length) { + var uuidpart = ""; + for (var i=0; i Date: Mon, 26 Mar 2012 21:35:34 -0400 Subject: [PATCH 02/11] Fix for CB-389: resolveLocalFileSystemURI does not work on a resized image captured from Camera.getPicture() --- framework/src/org/apache/cordova/FileUtils.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/framework/src/org/apache/cordova/FileUtils.java b/framework/src/org/apache/cordova/FileUtils.java index 297219de..9334543c 100755 --- a/framework/src/org/apache/cordova/FileUtils.java +++ b/framework/src/org/apache/cordova/FileUtils.java @@ -254,7 +254,12 @@ public class FileUtils extends Plugin { URL testUrl = new URL(decoded); if (decoded.startsWith("file://")) { - fp = new File(decoded.substring(7, decoded.length())); + int questionMark = decoded.indexOf("?"); + if (questionMark < 0) { + fp = new File(decoded.substring(7, decoded.length())); + } else { + fp = new File(decoded.substring(7, questionMark)); + } } else { fp = new File(decoded); } From 993fb296d69ecd9f00d4ed8c1f2f27ea5451057c Mon Sep 17 00:00:00 2001 From: Fil Maj Date: Wed, 28 Mar 2012 13:47:45 -0700 Subject: [PATCH 03/11] updating network status plugin label and updating cordova-js to latest --- framework/assets/js/cordova.android.js | 95 +++++++++++++++++++++++--- framework/res/xml/plugins.xml | 2 +- 2 files changed, 88 insertions(+), 9 deletions(-) diff --git a/framework/assets/js/cordova.android.js b/framework/assets/js/cordova.android.js index 705d4e43..5ab3ac5e 100644 --- a/framework/assets/js/cordova.android.js +++ b/framework/assets/js/cordova.android.js @@ -262,8 +262,9 @@ var cordova = { } } }, - + // TODO: remove in 2.0. addPlugin: function(name, obj) { + console.log("[DEPRECATION NOTICE] window.addPlugin and window.plugins will be removed in version 2.0."); if (!window.plugins[name]) { window.plugins[name] = obj; } @@ -285,6 +286,7 @@ var cordova = { /** * Legacy variable for plugin support + * TODO: remove in 2.0. */ if (!window.PhoneGap) { window.PhoneGap = cordova; @@ -292,6 +294,7 @@ if (!window.PhoneGap) { /** * Plugins object + * TODO: remove in 2.0. */ if (!window.plugins) { window.plugins = {}; @@ -347,7 +350,7 @@ function include(parent, objects, clobber, merge) { include(result, obj.children, clobber, merge); } } catch(e) { - alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"'); + utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"'); } }); } @@ -1007,6 +1010,15 @@ module.exports = { MediaError: { // exists natively on Android WebView on Android 4.x path: "cordova/plugin/MediaError" } + }, + merges: { + navigator: { + children: { + notification: { + path: 'cordova/plugin/android/notification' + } + } + } } }; @@ -3483,6 +3495,7 @@ 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'); /** @@ -3511,8 +3524,7 @@ function Device() { }, function(e) { me.available = false; - console.log("Error initializing Cordova: " + e); - alert("Error initializing Cordova: "+e); + utils.alert("[ERROR] Error initializing Cordova: " + e); }); } @@ -3577,6 +3589,63 @@ module.exports = new Device(); }) +// 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'), @@ -3932,7 +4001,7 @@ var CupcakeLocalStorage = function() { }, function (err) { - alert(err.message); + utils.alert(err.message); } ); this.setItem = function(key, val) { @@ -3983,7 +4052,7 @@ var CupcakeLocalStorage = function() { }; } catch(e) { - alert("Database error "+e+"."); + utils.alert("Database error "+e+"."); return; } }; @@ -4479,7 +4548,7 @@ var NetworkConnection = function () { */ NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) { // Get info - exec(successCallback, errorCallback, "Network Status", "getConnectionInfo", []); + exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []); }; module.exports = new NetworkConnection(); @@ -4729,8 +4798,18 @@ var _self = { Child.__super__ = Parent.prototype; Child.prototype.constructor = Child; }; - }()) + }()), + /** + * Alerts a message in any available way: alert or console.log. + */ + alert:function(msg) { + if (alert) { + alert(msg); + } else if (console && console.log) { + console.log(msg); + } + } }; module.exports = _self; diff --git a/framework/res/xml/plugins.xml b/framework/res/xml/plugins.xml index 0a17cc88..ce978fb4 100755 --- a/framework/res/xml/plugins.xml +++ b/framework/res/xml/plugins.xml @@ -27,7 +27,7 @@ - + From d2b329636f2f6d477c4e207fce94f0546431c677 Mon Sep 17 00:00:00 2001 From: macdonst Date: Thu, 29 Mar 2012 15:08:44 -0400 Subject: [PATCH 04/11] Fixing license header in com.phonegap.api.PluginManager --- framework/src/com/phonegap/api/PluginManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/com/phonegap/api/PluginManager.java b/framework/src/com/phonegap/api/PluginManager.java index 65c6f11e..4f0f13f0 100755 --- a/framework/src/com/phonegap/api/PluginManager.java +++ b/framework/src/com/phonegap/api/PluginManager.java @@ -1,4 +1,5 @@ /* + 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 From 900be3afe0d0b73553df9378a8618c9a706663e5 Mon Sep 17 00:00:00 2001 From: Bryce Curtis Date: Fri, 30 Mar 2012 11:37:29 -0500 Subject: [PATCH 05/11] Tests to verify Android native features. --- test/.classpath | 9 + test/.project | 33 + test/AndroidManifest.xml | 87 + test/README.md | 23 + test/ant.properties | 17 + .../assets/www/backbuttonmultipage/index.html | 23 + .../www/backbuttonmultipage/sample2.html | 23 + .../www/backbuttonmultipage/sample3.html | 26 + test/assets/www/background/index.html | 99 + test/assets/www/background/index2.html | 98 + test/assets/www/cordova-1.6.0rc1.js | 4897 +++++++++++++++++ test/assets/www/cordova.js | 2 + test/assets/www/htmlnotfound/error.html | 1 + test/assets/www/iframe/index.html | 33 + test/assets/www/iframe/index2.html | 24 + test/assets/www/index.html | 47 + test/assets/www/jqmtabbackbutton/index.html | 49 + test/assets/www/jqmtabbackbutton/tab1.html | 29 + test/assets/www/jqmtabbackbutton/tab2.html | 30 + test/assets/www/jqmtabbackbutton/tab3.html | 30 + test/assets/www/lifecycle/index.html | 108 + test/assets/www/lifecycle/index2.html | 104 + test/assets/www/main.js | 150 + test/assets/www/master.css | 117 + test/assets/www/menus/index.html | 29 + test/assets/www/splashscreen/index.html | 22 + test/assets/www/userwebview/index.html | 49 + test/assets/www/whitelist/index.html | 29 + test/assets/www/whitelist/index2.html | 23 + test/assets/www/xhr/index.html | 48 + test/build.xml | 85 + test/libs/cordova-1.6.0rc1.jar | Bin 0 -> 170594 bytes test/project.properties | 11 + test/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 4147 bytes test/res/drawable-ldpi/ic_launcher.png | Bin 0 -> 1723 bytes test/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 2574 bytes test/res/drawable/icon.png | Bin 0 -> 5800 bytes test/res/drawable/sandy.jpg | Bin 0 -> 48450 bytes test/res/layout/main.xml | 13 + test/res/values/strings.xml | 4 + test/res/xml/cordova.xml | 5 + test/res/xml/plugins.xml | 19 + .../apache/cordova/test/ActivityPlugin.java | 81 + .../org/apache/cordova/test/FixWebView.java | 43 + .../cordova/test/backbuttonmultipage.java | 30 + .../org/apache/cordova/test/background.java | 34 + .../src/org/apache/cordova/test/errorurl.java | 32 + .../org/apache/cordova/test/htmlnotfound.java | 31 + test/src/org/apache/cordova/test/iframe.java | 30 + .../apache/cordova/test/jqmtabbackbutton.java | 30 + .../org/apache/cordova/test/lifecycle.java | 30 + test/src/org/apache/cordova/test/loading.java | 31 + test/src/org/apache/cordova/test/menus.java | 80 + .../org/apache/cordova/test/splashscreen.java | 35 + test/src/org/apache/cordova/test/tests.java | 32 + test/src/org/apache/cordova/test/timeout.java | 34 + .../org/apache/cordova/test/userwebview.java | 72 + .../org/apache/cordova/test/whitelist.java | 51 + test/src/org/apache/cordova/test/xhr.java | 30 + 59 files changed, 7102 insertions(+) create mode 100755 test/.classpath create mode 100755 test/.project create mode 100755 test/AndroidManifest.xml create mode 100755 test/README.md create mode 100755 test/ant.properties create mode 100755 test/assets/www/backbuttonmultipage/index.html create mode 100755 test/assets/www/backbuttonmultipage/sample2.html create mode 100755 test/assets/www/backbuttonmultipage/sample3.html create mode 100755 test/assets/www/background/index.html create mode 100755 test/assets/www/background/index2.html create mode 100755 test/assets/www/cordova-1.6.0rc1.js create mode 100755 test/assets/www/cordova.js create mode 100755 test/assets/www/htmlnotfound/error.html create mode 100755 test/assets/www/iframe/index.html create mode 100755 test/assets/www/iframe/index2.html create mode 100755 test/assets/www/index.html create mode 100755 test/assets/www/jqmtabbackbutton/index.html create mode 100755 test/assets/www/jqmtabbackbutton/tab1.html create mode 100755 test/assets/www/jqmtabbackbutton/tab2.html create mode 100755 test/assets/www/jqmtabbackbutton/tab3.html create mode 100755 test/assets/www/lifecycle/index.html create mode 100755 test/assets/www/lifecycle/index2.html create mode 100755 test/assets/www/main.js create mode 100755 test/assets/www/master.css create mode 100755 test/assets/www/menus/index.html create mode 100755 test/assets/www/splashscreen/index.html create mode 100755 test/assets/www/userwebview/index.html create mode 100755 test/assets/www/whitelist/index.html create mode 100755 test/assets/www/whitelist/index2.html create mode 100755 test/assets/www/xhr/index.html create mode 100755 test/build.xml create mode 100755 test/libs/cordova-1.6.0rc1.jar create mode 100755 test/project.properties create mode 100755 test/res/drawable-hdpi/ic_launcher.png create mode 100755 test/res/drawable-ldpi/ic_launcher.png create mode 100755 test/res/drawable-mdpi/ic_launcher.png create mode 100755 test/res/drawable/icon.png create mode 100755 test/res/drawable/sandy.jpg create mode 100755 test/res/layout/main.xml create mode 100755 test/res/values/strings.xml create mode 100755 test/res/xml/cordova.xml create mode 100755 test/res/xml/plugins.xml create mode 100755 test/src/org/apache/cordova/test/ActivityPlugin.java create mode 100755 test/src/org/apache/cordova/test/FixWebView.java create mode 100755 test/src/org/apache/cordova/test/backbuttonmultipage.java create mode 100755 test/src/org/apache/cordova/test/background.java create mode 100755 test/src/org/apache/cordova/test/errorurl.java create mode 100755 test/src/org/apache/cordova/test/htmlnotfound.java create mode 100755 test/src/org/apache/cordova/test/iframe.java create mode 100755 test/src/org/apache/cordova/test/jqmtabbackbutton.java create mode 100755 test/src/org/apache/cordova/test/lifecycle.java create mode 100755 test/src/org/apache/cordova/test/loading.java create mode 100755 test/src/org/apache/cordova/test/menus.java create mode 100755 test/src/org/apache/cordova/test/splashscreen.java create mode 100755 test/src/org/apache/cordova/test/tests.java create mode 100755 test/src/org/apache/cordova/test/timeout.java create mode 100755 test/src/org/apache/cordova/test/userwebview.java create mode 100755 test/src/org/apache/cordova/test/whitelist.java create mode 100755 test/src/org/apache/cordova/test/xhr.java diff --git a/test/.classpath b/test/.classpath new file mode 100755 index 00000000..8fb3e5fb --- /dev/null +++ b/test/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/test/.project b/test/.project new file mode 100755 index 00000000..d31f9d76 --- /dev/null +++ b/test/.project @@ -0,0 +1,33 @@ + + + CordovaTest + + + + + + 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/test/AndroidManifest.xml b/test/AndroidManifest.xml new file mode 100755 index 00000000..b92fc014 --- /dev/null +++ b/test/AndroidManifest.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/README.md b/test/README.md new file mode 100755 index 00000000..be2df511 --- /dev/null +++ b/test/README.md @@ -0,0 +1,23 @@ +## Android Native Tests ## + +These tests are designed to verify Android native features and other Android specific features. + +Before running the tests, they need to be set up. + +1. Copy the version of cordova-x.y.z.js into assets/www directory +2. Edit assets/www/cordova.js to reference the correct version +3. Copy cordova-x.y.z.jar into libs directory + +To run from command line: + +4. Build by entering "ant debug install" +5. Run tests by clicking on "CordovaTest" icon on device + +To run from Eclipse: + +4. Import Android project into Eclipse +5. Ensure Project properties "Java Build Path" includes the lib/cordova-x.y.z.jar +6. Create run configuration if not already created +7. Run tests + + diff --git a/test/ant.properties b/test/ant.properties new file mode 100755 index 00000000..ee52d86d --- /dev/null +++ b/test/ant.properties @@ -0,0 +1,17 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked in Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. + diff --git a/test/assets/www/backbuttonmultipage/index.html b/test/assets/www/backbuttonmultipage/index.html new file mode 100755 index 00000000..35f4bc82 --- /dev/null +++ b/test/assets/www/backbuttonmultipage/index.html @@ -0,0 +1,23 @@ + + + +Backbutton + + + + + +

Cordova Android Tests

+
+

Platform:  , Version:  

+

UUID:  , Name:  

+

Width:  , Height:  , Color Depth:

+
+
+

Page 1

+ Go to next page.
+ If returning from previous page, press "backbutton". You should exit this app. +
+ Next page + + \ No newline at end of file diff --git a/test/assets/www/backbuttonmultipage/sample2.html b/test/assets/www/backbuttonmultipage/sample2.html new file mode 100755 index 00000000..ad6f9600 --- /dev/null +++ b/test/assets/www/backbuttonmultipage/sample2.html @@ -0,0 +1,23 @@ + + + +Backbutton + + + + + +

Cordova Android Tests

+
+

Platform:  , Version:  

+

UUID:  , Name:  

+

Width:  , Height:  , Color Depth:

+
+
+

Page 2

+ Go to next page.
+ If returning from previous page, press "backbutton". You should go to Page 1. +
+ Next page + + \ No newline at end of file diff --git a/test/assets/www/backbuttonmultipage/sample3.html b/test/assets/www/backbuttonmultipage/sample3.html new file mode 100755 index 00000000..2238536e --- /dev/null +++ b/test/assets/www/backbuttonmultipage/sample3.html @@ -0,0 +1,26 @@ + + + +Backbutton + + + + + +

Cordova Android Tests

+
+

Platform:  , Version:  

+

UUID:  , Name:  

+

Width:  , Height:  , Color Depth:

+
+
+

Page 3

+ Press the 3 buttons below. You should stay on same page.
+ Press "backbutton" 4 times. This will go back to #test3, #test2, #test1, then return to previous Page 2.
+ (NOTE: IS THIS CORRECT BEHAVIOR?) +
+ page3#test1 + page3#test2 + page3#test3 + + diff --git a/test/assets/www/background/index.html b/test/assets/www/background/index.html new file mode 100755 index 00000000..62d7bbb8 --- /dev/null +++ b/test/assets/www/background/index.html @@ -0,0 +1,99 @@ + + + + + +Background Page 1 + + + + + + +

Events

+
+

+ Platform:  , Version:   +

+

+ UUID:  , Name:   +

+

+ Width:  , Height:   + , Color Depth: +

+
+
+ Press "Home" button, then return to this app to see pause/resume.
+ There shouldn't be any "Running" entries between pause and resume.
+
+
+

Info for event testing:

+
+
+ + + Clear status + + + + + + diff --git a/test/assets/www/background/index2.html b/test/assets/www/background/index2.html new file mode 100755 index 00000000..f0dd2b9f --- /dev/null +++ b/test/assets/www/background/index2.html @@ -0,0 +1,98 @@ + + + + + +Background Page 2 + + + + + + +

Events

+
+

+ Platform:  , Version:   +

+

+ UUID:  , Name:   +

+

+ Width:  , Height:   + , Color Depth: +

+
+
+

Press "Back" button to return to Page 1.

+
+
+

Info for event testing:

+
+
+ + Load new page + Clear status + + + + + + diff --git a/test/assets/www/cordova-1.6.0rc1.js b/test/assets/www/cordova-1.6.0rc1.js new file mode 100755 index 00000000..c4408829 --- /dev/null +++ b/test/assets/www/cordova-1.6.0rc1.js @@ -0,0 +1,4897 @@ +/* + 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'); +/** + * 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 (e == 'deviceready') { + channel.onDeviceReady.subscribeOnce(handler); + } else if (e == 'resume') { + channel.onResume.subscribe(handler); + // if subscribing listener after event has already fired, invoke the handler + if (channel.onResume.fired && handler instanceof Function) { + handler(); + } + } else if (e == 'pause') { + channel.onPause.subscribe(handler); + } else 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 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; +} + +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]; + }, + /** + * Method to fire event from native code + */ + fireDocumentEvent: function(type, data) { + var evt = createEvent(type, data); + if (typeof documentEventHandlers[type] != 'undefined') { + documentEventHandlers[type].fire(evt); + } else { + document.dispatchEvent(evt); + } + }, + fireWindowEvent: function(type, data) { + var evt = createEvent(type,data); + if (typeof windowEventHandlers[type] != 'undefined') { + windowEventHandlers[type].fire(evt); + } 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]; + } + } + }, + // TODO: remove in 2.0. + addPlugin: function(name, obj) { + console.log("[DEPRECATION NOTICE] window.addPlugin and window.plugins will be removed in version 2.0."); + if (!window.plugins[name]) { + window.plugins[name] = obj; + } + else { + console.log("Error: Plugin "+name+" already exists."); + } + }, + + addConstructor: function(func) { + channel.onCordovaReady.subscribeOnce(function() { + try { + func(); + } catch(e) { + console.log("Failed to run constructor: " + e); + } + }); + } +}; + +/** + * Legacy variable for plugin support + * TODO: remove in 2.0. + */ +if (!window.PhoneGap) { + window.PhoneGap = cordova; +} + +/** + * Plugins object + * TODO: remove in 2.0. + */ +if (!window.plugins) { + window.plugins = {}; +} + +module.exports = cordova; + +}) + +// file: lib/common/builder.js +define("cordova/builder", function(require, exports, module) { +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) { +/** + * Custom pub-sub channel that can have functions subscribed to it + * @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 = 0; + 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) { + eval("var v="+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) { + db = null; + } + + 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() { + prompt("", "gap_init:"); + }, [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" + } + } + }, + device:{ + path: "cordova/plugin/android/device" + }, + 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: { + 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) { + this.x = x; + this.y = y; + this.z = z; + this.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_URL. + * + * @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; + } + // TODO: parse MediaType + // TODO: enable allow edit? + + exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType]); +} + +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) + } +}; + +}) + +// 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 ? new Date(timestamp) : new Date()); +}; + +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 (!value instanceof Date){ + try { + value = new Date(value); + } catch(exception){ + value = null; + } + } + if (value instanceof Date){ + 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 || null; + this.value = value || 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; + /** + * The direction the device is moving at the position. + */ + this.heading = head; + /** + * The velocity with which the device is moving at the position. + */ + this.speed = vel; + /** + * 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'), + 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) + * {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'); + +/** + * 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'); + +/** + * 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 +*/ +FileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, debug) { + // 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 = {}; + } + } + + exec(successCallback, errorCallback, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, debug, 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) { + var win = function(result) { + var entry = null; + if (result.isDirectory) { + entry = new DirectoryEntry(); + } + else if (result.isFile) { + entry = new FileEntry(); + } + entry.isDirectory = result.isDirectory; + entry.isFile = result.isFile; + entry.name = result.name; + entry.fullPath = result.fullPath; + successCallback(entry); + }; + 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) { + this.code = code || 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) { + 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(this.successCallback, this.errorCallback, "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]); + } +}; + +/** + * 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 = []; + var i; + for (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"); + +// Local singleton variables. +var timers = {}; + +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") { + console.log("Accelerometer Error: successCallback is not a function"); + return; + } + + // errorCallback optional + if (errorCallback && (typeof errorCallback !== "function")) { + console.log("Accelerometer Error: errorCallback is not a function"); + return; + } + + // Get acceleration + exec(successCallback, errorCallback, "Accelerometer", "getAcceleration", []); + }, + + /** + * 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 !== undefined && options.frequency !== undefined)? options.frequency : 10000; + + // successCallback required + if (typeof successCallback !== "function") { + console.log("Accelerometer Error: successCallback is not a function"); + return; + } + + // errorCallback optional + if (errorCallback && (typeof errorCallback !== "function")) { + console.log("Accelerometer Error: errorCallback is not a function"); + return; + } + + // Make sure accelerometer timeout > frequency + 10 sec + exec( + function(timeout) { + if (timeout < (frequency + 10000)) { + exec(null, null, "Accelerometer", "setTimeout", [frequency + 10000]); + } + }, + function(e) { }, "Accelerometer", "getTimeout", []); + + // Start watch timer + var id = utils.createUUID(); + timers[id] = window.setInterval(function() { + exec(successCallback, errorCallback, "Accelerometer", "getAcceleration", []); + }, (frequency ? frequency : 1)); + + 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] !== undefined) { + window.clearInterval(timers[id]); + 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'); + +/** + * 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", []); +}; + +/* + * DEPRECATED + * This is only for Android. + * + * You must explicitly override the back button. + */ +Device.prototype.overrideBackButton = function() { + console.log("Device.overrideBackButton() is deprecated. Use App.overrideBackbutton(true)."); + navigator.app.overrideBackbutton(true); +}; + +/* + * DEPRECATED + * This is only for Android. + * + * This resets the back button to the default behaviour + */ +Device.prototype.resetBackButton = function() { + console.log("Device.resetBackButton() is deprecated. Use App.overrideBackbutton(false)."); + navigator.app.overrideBackbutton(false); +}; + +/* + * DEPRECATED + * This is only for Android. + * + * This terminates the activity! + */ +Device.prototype.exitApp = function() { + console.log("Device.exitApp() is deprecated. Use App.exitApp()."); + navigator.app.exitApp(); +}; + +module.exports = new Device(); + +}) + +// 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) { + // 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", []); + }, + + /** + * 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. + */ + watchHeading:function(successCallback, errorCallback, options) { + // Default interval (100 msec) + var frequency = (options !== undefined && options.frequency !== undefined) ? options.frequency : 100; + + // 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; + } + + // Start watch timer to get headings + var id = utils.createUUID(); + + 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]) { + clearInterval(timers[id]); + delete timers[id]; + } + } + // TODO: add the filter-based iOS-only methods + }; + +module.exports = compass; + +}) + +// file: lib/common/plugin/contacts.js +define("cordova/plugin/contacts", function(require, exports, module) { +var exec = require('cordova/exec'), + ContactError = require('cordova/plugin/ContactError'), + 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 || (fields instanceof Array && 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/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: 10000, + enableHighAccuracy: false, + timeout: 10000 + }; + + if (options) { + if (options.maximumAge !== undefined) { + opt.maximumAge = options.maximumAge; + } + if (options.enableHighAccuracy !== undefined) { + opt.enableHighAccuracy = options.enableHighAccuracy; + } + if (options.timeout !== undefined) { + opt.timeout = options.timeout; + } + } + + return opt; +} + +var geolocation = { + /** + * 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) { + options = parseParameters(options); + + var win = function(p) { + successCallback(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 || new Date() + )); + }; + var fail = function(e) { + errorCallback(new PositionError(e.code, e.message)); + }; + + exec(win, fail, "Geolocation", "getLocation", [options.enableHighAccuracy, options.timeout, options.maximumAge]); + }, + /** + * 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) { + options = parseParameters(options); + + var id = utils.createUUID(); + timers[id] = window.setInterval(function() { + geolocation.getCurrentPosition(successCallback, errorCallback, options); + }, options.timeout); + + 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) { + window.clearInterval(timers[id]); + delete timers[id]; + } + } +}; + +module.exports = geolocation; + +}) + +// file: lib/common/plugin/network.js +define("cordova/plugin/network", function(require, exports, module) { +var exec = require('cordova/exec'), + cordova = require('cordova'), + channel = require('cordova/channel'); + +var NetworkConnection = function () { + this.type = null; + this._firstRun = true; + this._timer = null; + this.timeout = 500; + + var me = this; + + channel.onCordovaReady.subscribeOnce(function() { + me.getInfo(function (info) { + me.type = info; + if (info === "none") { + // set a timer if still offline at the end of timer send the offline event + me._timer = setTimeout(function(){ + cordova.fireDocumentEvent("offline"); + me._timer = null; + }, me.timeout); + } else { + // If there is a current offline event pending clear it + if (me._timer !== null) { + clearTimeout(me._timer); + me._timer = null; + } + cordova.fireDocumentEvent("online"); + } + + // should only fire this once + if (me._firstRun) { + me._firstRun = false; + channel.onCordovaConnectionReady.fire(); + } + }, + function (e) { + // If we can't get the network info we should still tell Cordova + // to fire the deviceready event. + if (me._firstRun) { + me._firstRun = false; + channel.onCordovaConnectionReady.fire(); + } + console.log("Error initializing Network Connection: " + e); + }); + }); +}; + +/** + * Get connection info + * + * @param {Function} successCallback The function to call when the Connection data is available + * @param {Function} errorCallback The function to call when there is an error getting the Connection data. (OPTIONAL) + */ +NetworkConnection.prototype.getInfo = function (successCallback, errorCallback) { + // Get info + exec(successCallback, errorCallback, "NetworkStatus", "getConnectionInfo", []); +}; + +module.exports = new NetworkConnection(); + +}) + +// file: lib/common/plugin/notification.js +define("cordova/plugin/notification", function(require, exports, module) { +var exec = require('cordova/exec'); + +/** + * Provides access to notifications on the device. + */ + +module.exports = { + + /** + * Open a native alert dialog, with a customizable title and button text. + * + * @param {String} message Message to print in the body of the alert + * @param {Function} completeCallback The callback that is called when user clicks on a button. + * @param {String} title Title of the alert dialog (default: Alert) + * @param {String} buttonLabel Label of the close button (default: OK) + */ + alert: function(message, completeCallback, title, buttonLabel) { + var _title = (title || "Alert"); + var _buttonLabel = (buttonLabel || "OK"); + exec(completeCallback, null, "Notification", "alert", [message, _title, _buttonLabel]); + }, + + /** + * Open a native confirm dialog, with a customizable title and button text. + * The result that the user selects is returned to the result callback. + * + * @param {String} message Message to print in the body of the alert + * @param {Function} resultCallback The callback that is called when user clicks on a button. + * @param {String} title Title of the alert dialog (default: Confirm) + * @param {String} buttonLabels Comma separated list of the labels of the buttons (default: 'OK,Cancel') + */ + confirm: function(message, resultCallback, title, buttonLabels) { + var _title = (title || "Confirm"); + var _buttonLabels = (buttonLabels || "OK,Cancel"); + exec(resultCallback, null, "Notification", "confirm", [message, _title, _buttonLabels]); + }, + + /** + * Causes the device to vibrate. + * + * @param {Integer} mills The number of milliseconds to vibrate for. + */ + vibrate: function(mills) { + exec(null, null, "Notification", "vibrate", [mills]); + }, + + /** + * Causes the device to beep. + * On Android, the default notification ringtone is played "count" times. + * + * @param {Integer} count The number of beeps. + */ + beep: function(count) { + exec(null, null, "Notification", "beep", [count]); + } +}; + +}) + +// file: lib/common/plugin/requestFileSystem.js +define("cordova/plugin/requestFileSystem", function(require, exports, module) { +var FileError = require('cordova/plugin/FileError'), + FileSystem = require('cordova/plugin/FileSystem'), + exec = require('cordova/exec'); + +/** + * Request a file system in which to store application data. + * @param type local file system type + * @param size indicates how much storage space, in bytes, the application expects to need + * @param successCallback invoked with a FileSystem object + * @param errorCallback invoked if error occurs retrieving file system + */ +var requestFileSystem = function(type, size, successCallback, errorCallback) { + var fail = function(code) { + if (typeof errorCallback === 'function') { + errorCallback(new FileError(code)); + } + }; + + if (type < 0 || type > 3) { + fail(FileError.SYNTAX_ERR); + } else { + // if successful, return a FileSystem object + var success = function(file_system) { + if (file_system) { + if (typeof successCallback === 'function') { + // grab the name and root from the file system object + var result = new FileSystem(file_system.name, file_system.root); + successCallback(result); + } + } + else { + // no FileSystem object returned + fail(FileError.NOT_FOUND_ERR); + } + }; + exec(success, fail, "File", "requestFileSystem", [type, size]); + } +}; + +module.exports = requestFileSystem; + +}) + +// file: lib/common/plugin/resolveLocalFileSystemURI.js +define("cordova/plugin/resolveLocalFileSystemURI", function(require, exports, module) { +var DirectoryEntry = require('cordova/plugin/DirectoryEntry'), + FileEntry = require('cordova/plugin/FileEntry'), + 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)); + } + }; + // 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/utils.js +define("cordova/utils", function(require, exports, module) { +function UUIDcreatePart(length) { + var uuidpart = ""; + for (var i=0; i'); +document.write(''); diff --git a/test/assets/www/htmlnotfound/error.html b/test/assets/www/htmlnotfound/error.html new file mode 100755 index 00000000..3e9a61a8 --- /dev/null +++ b/test/assets/www/htmlnotfound/error.html @@ -0,0 +1 @@ +This is an error page. \ No newline at end of file diff --git a/test/assets/www/iframe/index.html b/test/assets/www/iframe/index.html new file mode 100755 index 00000000..b98773cf --- /dev/null +++ b/test/assets/www/iframe/index.html @@ -0,0 +1,33 @@ + + + + + + Cordova Tests + + + + + + +

IFrame

+
+

Platform:  , Version:  

+

UUID:  , Name:  

+

Width:  , Height:   + , Color Depth:

+
+
+ Press the two buttons:
+ 1. Google Maps should display in iframe.
+ 2. Page 2 replaces current page.
+ (NOTE: THIS BEHAVIOR IS WRONG - AND NEEDS TO BE FIXED IN FUTURE RELEASE.) +
+ + Google Maps + Page 2 + + diff --git a/test/assets/www/iframe/index2.html b/test/assets/www/iframe/index2.html new file mode 100755 index 00000000..ab0a430d --- /dev/null +++ b/test/assets/www/iframe/index2.html @@ -0,0 +1,24 @@ + + + + + + Cordova Tests + + + + + +

IFrame window

+
+

Platform:  , Version:  

+

UUID:  , Name:  

+

Width:  , Height:   + , Color Depth:

+
+
+ This should display a Cordova page inside an iframe. The info above should be filled out. + (NOTE: THIS DOES NOT WORK AND NEEDS TO BE FIXED IN FUTURE RELEASE.) +
+ + diff --git a/test/assets/www/index.html b/test/assets/www/index.html new file mode 100755 index 00000000..1fa149ef --- /dev/null +++ b/test/assets/www/index.html @@ -0,0 +1,47 @@ + + + + + + Cordova Tests + + + + + + + +

Cordova Android Tests

+
+

Platform:  , Version:  

+

UUID:  , Name:  

+

Width:  , Height:   + , Color Depth:

+

Cordova Version:  

+
+
+

Run each of the tests below:

+
+ + + + + + + + + + + + + + + + diff --git a/test/assets/www/jqmtabbackbutton/index.html b/test/assets/www/jqmtabbackbutton/index.html new file mode 100755 index 00000000..ee3bcfaa --- /dev/null +++ b/test/assets/www/jqmtabbackbutton/index.html @@ -0,0 +1,49 @@ + + + +Backbutton + + + + + + + + + +
+
+

Main

+
+
+ To test, press several tabs.
+ The "backbutton" can be pressed any time to exit app. +
+
+
+ +
+
+
\ No newline at end of file diff --git a/test/assets/www/jqmtabbackbutton/tab1.html b/test/assets/www/jqmtabbackbutton/tab1.html new file mode 100755 index 00000000..4d321424 --- /dev/null +++ b/test/assets/www/jqmtabbackbutton/tab1.html @@ -0,0 +1,29 @@ + + + +Tab 1 + + + +
+
+

Tab 1

+
+
+Tab 1 content. +
+
+
+ +
+ +
+ +
\ No newline at end of file diff --git a/test/assets/www/jqmtabbackbutton/tab2.html b/test/assets/www/jqmtabbackbutton/tab2.html new file mode 100755 index 00000000..a701b435 --- /dev/null +++ b/test/assets/www/jqmtabbackbutton/tab2.html @@ -0,0 +1,30 @@ + + + +Tab 2 + + + + +
+
+

Tab 2

+
+
+Tab 2 content. +
+
+
+ +
+ +
+ +
\ No newline at end of file diff --git a/test/assets/www/jqmtabbackbutton/tab3.html b/test/assets/www/jqmtabbackbutton/tab3.html new file mode 100755 index 00000000..c07cd904 --- /dev/null +++ b/test/assets/www/jqmtabbackbutton/tab3.html @@ -0,0 +1,30 @@ + + + +Tab 3 + + + + +
+
+

Tab 3

+
+
+Tab 3 content. +
+
+
+ +
+ +
+ +
\ No newline at end of file diff --git a/test/assets/www/lifecycle/index.html b/test/assets/www/lifecycle/index.html new file mode 100755 index 00000000..cd061549 --- /dev/null +++ b/test/assets/www/lifecycle/index.html @@ -0,0 +1,108 @@ + + + + + +Lifecycle Page 1 + + + + + + +

Events

+
+

+ Platform:  , Version:   +

+

+ UUID:  , Name:   +

+

+ Width:  , Height:   + , Color Depth: +

+
+
+

Test 1

+ Press "Home" button, then return to this app to see pause/resume.
+ There should be "Running" entries between pause and resume since app continues to run in the background. +

Test 2

+ Press "Load new page" button to load a new Cordova page.
+ When returning, you should see +
    +
  • Page2: onunload
  • +
  • Page1: onload
  • +
  • Page1: Running
  • +
+
+
+

Info for event testing:

+
+
+ + Load new page + Clear status + + + + + + diff --git a/test/assets/www/lifecycle/index2.html b/test/assets/www/lifecycle/index2.html new file mode 100755 index 00000000..ee79cf3f --- /dev/null +++ b/test/assets/www/lifecycle/index2.html @@ -0,0 +1,104 @@ + + + + + +Lifecycle Page 2 + + + + + + +

Events

+
+

+ Platform:  , Version:   +

+

+ UUID:  , Name:   +

+

+ Width:  , Height:   + , Color Depth: +

+
+
+ You should see
+
    +
  • Page1: onunload
  • +
  • Page2: onload
  • +
  • Page2: Running
  • +
+ Press "backbutton" to return to Page 1. +
+
+

Info for event testing:

+
+
+ + Load new page + Clear status + + + + + + diff --git a/test/assets/www/main.js b/test/assets/www/main.js new file mode 100755 index 00000000..bfc89a07 --- /dev/null +++ b/test/assets/www/main.js @@ -0,0 +1,150 @@ +var deviceInfo = function() { + document.getElementById("platform").innerHTML = device.platform; + document.getElementById("version").innerHTML = device.version; + document.getElementById("uuid").innerHTML = device.uuid; + document.getElementById("name").innerHTML = device.name; + document.getElementById("width").innerHTML = screen.width; + document.getElementById("height").innerHTML = screen.height; + document.getElementById("colorDepth").innerHTML = screen.colorDepth; + var el = document.getElementById("cordova"); + if (el) { + el.innerHTML = device.cordova; + } +}; + +var getLocation = function() { + var suc = function(p) { + alert(p.coords.latitude + " " + p.coords.longitude); + }; + var locFail = function() { + }; + navigator.geolocation.getCurrentPosition(suc, locFail); +}; + +var beep = function() { + navigator.notification.beep(2); +}; + +var vibrate = function() { + navigator.notification.vibrate(0); +}; + +function roundNumber(num) { + var dec = 3; + var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); + return result; +} + +var accelerationWatch = null; + +function updateAcceleration(a) { + document.getElementById('x').innerHTML = roundNumber(a.x); + document.getElementById('y').innerHTML = roundNumber(a.y); + document.getElementById('z').innerHTML = roundNumber(a.z); +} + +var toggleAccel = function() { + if (accelerationWatch !== null) { + navigator.accelerometer.clearWatch(accelerationWatch); + updateAcceleration({ + x : "", + y : "", + z : "" + }); + accelerationWatch = null; + } else { + var options = {}; + options.frequency = 1000; + accelerationWatch = navigator.accelerometer.watchAcceleration( + updateAcceleration, function(ex) { + alert("accel fail (" + ex.name + ": " + ex.message + ")"); + }, options); + } +}; + +var preventBehavior = function(e) { + e.preventDefault(); +}; + +function dump_pic(data) { + var viewport = document.getElementById('viewport'); + console.log(data); + viewport.style.display = ""; + viewport.style.position = "absolute"; + viewport.style.top = "10px"; + viewport.style.left = "10px"; + document.getElementById("test_img").src = "data:image/jpeg;base64," + data; +} + +function fail(msg) { + alert(msg); +} + +function show_pic() { + navigator.camera.getPicture(dump_pic, fail, { + quality : 50 + }); +} + +function close() { + var viewport = document.getElementById('viewport'); + viewport.style.position = "relative"; + viewport.style.display = "none"; +} + +function contacts_success(contacts) { + alert(contacts.length + + ' contacts returned.' + + (contacts[2] && contacts[2].name ? (' Third contact is ' + contacts[2].name.formatted) + : '')); +} + +function get_contacts() { + var obj = new ContactFindOptions(); + obj.filter = ""; + obj.multiple = true; + navigator.contacts.find( + [ "displayName", "name" ], contacts_success, + fail, obj); +} + +function check_network() { + var networkState = navigator.network.connection.type; + + var states = {}; + states[Connection.UNKNOWN] = 'Unknown connection'; + states[Connection.ETHERNET] = 'Ethernet connection'; + states[Connection.WIFI] = 'WiFi connection'; + states[Connection.CELL_2G] = 'Cell 2G connection'; + states[Connection.CELL_3G] = 'Cell 3G connection'; + states[Connection.CELL_4G] = 'Cell 4G connection'; + states[Connection.NONE] = 'No network connection'; + + confirm('Connection type:\n ' + states[networkState]); +} + +var watchID = null; + +function updateHeading(h) { + document.getElementById('h').innerHTML = h.magneticHeading; +} + +function toggleCompass() { + if (watchID !== null) { + navigator.compass.clearWatch(watchID); + watchID = null; + updateHeading({ magneticHeading : "Off"}); + } else { + var options = { frequency: 1000 }; + watchID = navigator.compass.watchHeading(updateHeading, function(e) { + alert('Compass Error: ' + e.code); + }, options); + } +} + +function init() { + // the next line makes it impossible to see Contacts on the HTC Evo since it + // doesn't have a scroll button + // document.addEventListener("touchmove", preventBehavior, false); + document.addEventListener("deviceready", deviceInfo, true); +} diff --git a/test/assets/www/master.css b/test/assets/www/master.css new file mode 100755 index 00000000..60a8451e --- /dev/null +++ b/test/assets/www/master.css @@ -0,0 +1,117 @@ + body { + background:#222 none repeat scroll 0 0; + color:#666; + font-family:Helvetica; + font-size:72%; + line-height:1.5em; + margin:0; + border-top:1px solid #393939; + } + + #info{ + background:#ffa; + border: 1px solid #ffd324; + -webkit-border-radius: 5px; + border-radius: 5px; + clear:both; + margin:15px 6px 0; + width:295px; + padding:4px 0px 2px 10px; + } + + #info > h4{ + font-size:.95em; + margin:5px 0; + } + + #stage.theme{ + padding-top:3px; + } + + /* Definition List */ + #stage.theme > dl{ + padding-top:10px; + clear:both; + margin:0; + list-style-type:none; + padding-left:10px; + overflow:auto; + } + + #stage.theme > dl > dt{ + font-weight:bold; + float:left; + margin-left:5px; + } + + #stage.theme > dl > dd{ + width:45px; + float:left; + color:#a87; + font-weight:bold; + } + + /* Content Styling */ + #stage.theme > h1, #stage.theme > h2, #stage.theme > p{ + margin:1em 0 .5em 13px; + } + + #stage.theme > h1{ + color:#eee; + font-size:1.6em; + text-align:center; + margin:0; + margin-top:15px; + padding:0; + } + + #stage.theme > h2{ + clear:both; + margin:0; + padding:3px; + font-size:1em; + text-align:center; + } + + /* Stage Buttons */ + #stage.theme a.btn{ + border: 1px solid #555; + -webkit-border-radius: 5px; + border-radius: 5px; + text-align:center; + display:block; + float:left; + background:#444; + width:150px; + color:#9ab; + font-size:1.1em; + text-decoration:none; + padding:1.2em 0; + margin:3px 0px 3px 5px; + } + #stage.theme a.btn.large{ + width:308px; + padding:1.2em 0; + } + + /* Stage Buttons */ + #stage.theme button.btn{ + border: 1px solid #555; + -webkit-border-radius: 5px; + border-radius: 5px; + text-align:center; + display:block; + float:left; + background:#444; + width:150px; + color:#9ab; + font-size:1.1em; + text-decoration:none; + padding:1.2em 0; + margin:3px 0px 3px 5px; + } +#stage.theme button.btn.large{ + width:308px; + padding:1.2em 0; + } + diff --git a/test/assets/www/menus/index.html b/test/assets/www/menus/index.html new file mode 100755 index 00000000..e79c7314 --- /dev/null +++ b/test/assets/www/menus/index.html @@ -0,0 +1,29 @@ + + + + + + Cordova Tests + + + + + +

Menu Test

+
+

Platform:  , Version:  

+

UUID:  , Name:  

+

Width:  , Height:   + , Color Depth:

+
+
+

The menu items should be:

+
  • Item1
    +
  • Item2
    +
  • Item3
    +

    There is also a context menu. Touch and hold finger here to see:

    +
  • Context Item1
    +
  • + + + diff --git a/test/assets/www/splashscreen/index.html b/test/assets/www/splashscreen/index.html new file mode 100755 index 00000000..b594c1e4 --- /dev/null +++ b/test/assets/www/splashscreen/index.html @@ -0,0 +1,22 @@ + + + + + + Cordova Tests + + + + + +

    Splash Screen Test

    +
    +

    Platform:  , Version:  

    +

    UUID:  , Name:  

    +

    Width:  , Height:   + , Color Depth:

    +
    +
    + You should have seen the splash screen for 2 seconds.
    + + diff --git a/test/assets/www/userwebview/index.html b/test/assets/www/userwebview/index.html new file mode 100755 index 00000000..9e68f67e --- /dev/null +++ b/test/assets/www/userwebview/index.html @@ -0,0 +1,49 @@ + + + + + + Cordova Tests + + + + + +

    User WebView/Client/Chrome Test

    +
    +

    Platform:  , Version:  

    +

    UUID:  , Name:  

    +

    Width:  , Height:   + , Color Depth:

    +
    +
    +

    The following should be seen in LogCat:

    +
  • userwebview: TestViewClient()
    +
  • userwebview: TestChromeClient()
    +
  • userwebview: onGeolocationPermissionsShowPrompt(file://)
    +
  • userwebview: shouldOverrideUrlLoading(test://this_will_call_shouldOverrideUrlLoading)
    + +
  • + + + diff --git a/test/assets/www/whitelist/index.html b/test/assets/www/whitelist/index.html new file mode 100755 index 00000000..bab52310 --- /dev/null +++ b/test/assets/www/whitelist/index.html @@ -0,0 +1,29 @@ + + + + + + Cordova Tests + + + + + +

    Whitelist Page 1

    +
    +

    Platform:  , Version:  

    +

    UUID:  , Name:  

    +

    Width:  , Height:   + , Color Depth:

    +
    +
    + Loading Page 2 should be successful.
    + Loading Page 3 should be in web browser.
    + Loading Page 2 with target=_blank should be in web browser?
    + (THIS DOESN'T HAPPEN.) https://issues.apache.org/jira/browse/CB-362 +
    + Page 2 + Page 3 + Page 2 with target=_blank + + diff --git a/test/assets/www/whitelist/index2.html b/test/assets/www/whitelist/index2.html new file mode 100755 index 00000000..ffd991e7 --- /dev/null +++ b/test/assets/www/whitelist/index2.html @@ -0,0 +1,23 @@ + + + + + + Cordova Tests + + + + + +

    Whitelist Page 2

    +
    +

    Platform:  , Version:  

    +

    UUID:  , Name:  

    +

    Width:  , Height:   + , Color Depth:

    +
    +
    + Press "backbutton" +
    + + diff --git a/test/assets/www/xhr/index.html b/test/assets/www/xhr/index.html new file mode 100755 index 00000000..37ac942d --- /dev/null +++ b/test/assets/www/xhr/index.html @@ -0,0 +1,48 @@ + + + + + + Cordova Tests + + + + + + +

    XHR

    +
    +

    Platform:  , Version:  

    +

    UUID:  , Name:  

    +

    Width:  , Height:   + , Color Depth:

    +
    +
    + Press buttons below to test. You should see an alert with results displayed. +
    + Load file:// + Load Google + + + diff --git a/test/build.xml b/test/build.xml new file mode 100755 index 00000000..2cd0b5ea --- /dev/null +++ b/test/build.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/libs/cordova-1.6.0rc1.jar b/test/libs/cordova-1.6.0rc1.jar new file mode 100755 index 0000000000000000000000000000000000000000..7358d17b90826c057d69ad28e7ff6153b47fbbf0 GIT binary patch literal 170594 zcma&NbC4&|mNibwLAx0m+N23DZj}NHBg+0Rbuf3kn6~`4@_y z(!*}}7jFC4(Ei$gLgj@Oq$R{v)fnU@9^_}H@~X3*L2 zU}2n9(D@#cpV+)QJv;x?As`?+cNd|*KK$ne_V>xu!JhFyT>k$e;Qxhiv~mELTN*q5 zFHq$F3N?1L{$Jq#c(;SI<^O_!{TIU6(b&|={C@$W{yWgr!P(5g-S~eQfcf7K_}?AI z`tJu>Slj)-zCi&Yc)JLxO;rAD`-{f?`;C7U1Ej)WW9)9sVAea&3>apD1OM4uaSLvD zz2P0m0Ni9=L@sVYngl}4eRfqtVy&oTP9k;t5aifY2vK9JGf6ZpLmh}pxJ%(p9^b3X z$P3bFORKT)#+{Ya3**&6b$r{5z|0gWF%S%Z4Olq1kK$E0X+L8c{1c4>*Rv15=07SU zvY9^As0&);^$-@Adkb6pC_D9YHG;qP5BdD3IQ~JPw33~hr8R)T)Xvz& zh4;x}O#lJ{LKH&59fCpvBI@u{?<+X=vuF8n1mtTZSk7-gFn95BhR+=WLjoeGcBDz{ zD|e*F)$dPf?eZatI|PRWMCWI*YvJO^VXWHM;b(EGZy^p@UM!s6;9HsaWECKbyDAor zPsx}+QCny`7H&ppW(o)-7Vc6gIVuSBKc)Xq-+z?F;4J<183Pyy2m~rUu8ghL3?|$6zF0oTS6ILjV}3$Nx03G~Pnqmc+V5xX+O} z9QS&qWG%g%U7@Q!348=XzB5R#USf6NKPXxG#yqdvw z7ocQ&yigN+y3?YTM8z=ZKtcD8U>qO)n2j}bZetF;7_r_dy|f<<7&R)`#5d0Td>JJr zHs}ahv#_9b(QTQ;CB!D3Fjf;zc2;6SDYrpr86&jnmt7K~!&=>^=Lz0!7Ctxc^;hrq z7X0^VG%;ZVdj3m+#a}8Y|2ry_{O4fK{!%c!BP{t{x z6*OF`{zO+xTD~%U70125sKivx*y|ct(g3h}SaZ3NBz=IPNf7FVMQt)otJ*4hThR}T zo_q(|hHX@8dL+ZFsaM;e=d%qlBAiW;3M*4e(O~)@0D#7?T~Dsnr}Qir^=peJTX7-_ z{dZ&%<7~`;)3?JzkhU&=`SQiuQFQulu?05^p}g(0E8LMj^# zHt9f;=kruWu;Y^L$aJ)UiwghvVfTx@Y?Cha&%N3HAmU#kEe!?5uukT9F*@8IpS)b) z4xp_e>x3q`>#AGSGf`(m%hsfOrTroi5$bReK#y~?NOku=K=8F74rSF{|H}R8@2Q6z zY}wAt{Hx=%BqWhZ%FfuJ`s&v!r@=`$lU(kx@956zCmF=Y%rz9}q+mZE^1h~~mpw+? z^Gp2wVICshmgv4RrnGFW5t$r2-f67h!dGHhm==@Wi0&iUhh)gi^zmo46a4poSywA_ zhYkN=r8ow)*4qNuwib#0JMy~3BZFbn{^J0CtdwWLM1=AIv0pVRl81^-alc7eW zUfXlykZJ8C6RmO<;0yA*Q28d|Rw`;?Xf%DVL#xcQDT!eXdI*V>+pkp^ii#$5L*A+C zXjmylopm~&bDT$;+D=i+(=Z&k_$3BjX;Kvrz6^$w#BpxJ7Ms>x#-$2^o0OLNGrWy*to2=x!t3RLR?; zUat4tr%ZaUKev@%(W98*=wNuD{)6W1m&RGjE)=5pw5qs-HC8{QqgH>+*#P+Jc0NJ= zU3I?fdmUIHfBz{EKtQDbGsi0CE^ccl5jj=Av_*X$FXR|N3b$Imw&SU5WY0-JS&xP+EY#3aY zN4fob1)PnjuBnLqu1mmi9-aYfY4=>+#6H6Hi6bUSc2 zF9BDW6SfR)+swGh{gS)w-O16(|G4YZ7VSlB>tVwaelE+&*DF=x=RVpu#7@revBZ$?-ZGrV@Zu8w| zKgl->uCvb`w%yig9yLE0LDc0-?N`Yj5aR%qzCRky!hFyijD8-8xFOM!-K^6MZk)=* zA~){VcF7b8!A~pBS`h?9Q1TGTbs|xnoTQZsu&g3B-7D_4eXT4Cb&y(=^sm8GsFafN z^&*?e*^)VbfW)s;MJE!;)r#5jrA9CHI7xbo&7(4rT zn_Ts%t6DR}TNaZGS?qquvO=ry3kc|dMw3&*2yKI-wzFXXX7uF5PMJdDI zP^%9E2#DgZu>KK~{VU@7k3dS;)YRNg&f3M*9Pl5@H%$xLQ*8zP+rff`HH(i(3`I^T zI?;p$7zG&}RW4Th+(^m<1!a(&k0Qa$h=sK;D@e?CyEVFaxsC?LU6fV@ip*HqhI6yJ zPS(TrMI&b0*4E=H;KnD*4mH&GcaP6?_e-u%`k!1M0|U>STV){2Xlg(y^h{i)KDoCV zqAMzasa!h*qqVNKMGP}!i&{};)03!1(v&# zq(BP#m4j03tAF@__Y&#JuX{6)FWXDG4y^3v7)5jpD-h4p{%)eZoBh1}y z*p*%*+T&QLGz@acd$D5xOI@iI5>B10Q)*l-o@SM4p=@b0(Nx*YCMVgJvAlsZH`w`T zFcaCnj^Kjvo_2qCO=S6SE(nF+vL*X`F2x0S90SL|C^tz`s%oNNX9H zHR`D8v0APfbHj}l>e+%H0?ged5&500C5Grpa3N8?M=PwW1y7u^gG6zupGy@bqqGoX zKxfoiS=&{z$oDqzrR|T;4q1?Ad8+Znxy~W91AW2;HWES-#8DIB> z+oA#X{HcKD20uIzv(hmW#|}5?Ny?@dPm5)9P#sD@GUN&I$HoLqz!A4=MdH=CVUA0#pb z-K=_*QKmN^7PPFdUfCX6)@od#jILu2ZhJg@tPD0h;rJEE5-9YN*nHQ73%v)*dy^_s0des{_ z5J3{qI)jpn3Xl}FLhwFw&4_e@7)pyXrNGhHLG3(hipFroUDlplqK!=8M+}9{&FIN( zC~h}aaZ+oSl30SRCrZIdl=5~g_W5iF88!oi8%jbqJ70JOInR0YFS6^tLgR*!ZM6VV zUG?7n@{(#DlKB{a=-jWK5D7Bvc6t4g%Y_5!Ln&fV9Eda|>vbsKUM{LIJd_E1Q}5)p z5Ypuy+tdcI{1rzqN%Y8bGspat!MDXp3(LHbzW4^ILtORWzmbwq;CZnmKEzuo#4;OXDUEvJgcZX<+!3t z^t5!8t~=HfA(GWKcdLLKUMJbAYKBp586)0lK3E{#4R(?v{09T;;)yuEf9)RpXDEMq zXnz-vdB%WAl3b7&9~Mm#<236X>*r8h0jim)CflcqhMy&!XDc!1m(H-mEybN^5o!~) zm){=^qhqqQ_F6p$+sr7{viSbBTgcC(r+Kz6Gg#Aj*YcIHlvWQ@o%MU^9HD;KDArQD zIUEP36bn1SHB9{Lv*__FeStG*^rOY_e(P7>9r9O{y(kT|yh3!8u_aRD9V6%+IKP$c z#|mMwd=Bb>&T}~auGzswbZA{#>Eoq@0ME`^t9 z>YwI^mMXR9A`zLgL1OnvA;pj!p#n6J$=zL1L>1Ov6;?;t0xJTW*O3h5;NR0 zQ*8WsM@l_2)L|WYk`8wn@m1HInk!D=^ND%A*}borRpUfB4$k8XY!a3(nWqUhLTm2O zS_$uMj#%Y6GHnzFXaI=!iHcs$Ts8ZZp7vXXO| z6>0(nmZ^)EFxeW?PmG1d>X{+1UK*`Dip`~_*mJ6s%?s^{eW8@H_RhYeqFUFqbM;)I zu#2~N=Maty6T+&U@Rb$Pv|d6XDA~5mzeLDeK`>Qocl*-PJ;ybwkB_1@KNggZX8`oF zjB^0okut=)0bxC__zS4V6|XtGH6#$9nC3OgjIMD;dnMToJs53RgbP2dUcqzTKr6xH z>p)}Xla6<02g>s4-Y+KZq)kgAr+Obui=!?}qh_aiUjnh;44%_0_bd=jdF1AE3Z5?8 z*f0F=-xtoFo;_&4g}3+udEdBE@IyDMBDnBCnT`YXspP$D`u znIR#z=~5gnv_)7CmrR8p!QzLkJ0TV5AK%Zq!tYlpyQeSY@|&Asjr8ejQB*+Ip8aG% zL$@SU;JMB+Z#%G1dBuFu$-coJ%6R!@S&q18n`%jqmk2u(0{H`<*Rhuh3B4HQ%f`+q zBPr-@9}o{-sbot2Yk56hciEHHKQf2z{oVHp>)WZz+rF!Vv?6Z*o9fOOej)u7zl|>G$sev8ZCmUZ{t|njhd4Z6p#` zsLTGS1mhNME)?PGGlZk;p3sED9*+2o!xv6)oV)s4RCpcQawX5rjyY6DCB0Z4k!9;5 zH8*JLmz5Vk($as^XFDcnh1u`JY*DTr_#+R27H9C^%6o>U+hK0rR!#+P*AkArIASEe zL-bKE#Vx~nDj!2tWxUP>x!w`g$icdhh;GF=-0AaNt=`&~H^yinsw(^E^ww6=%N=T- z5~LzWB9v#kDH+mKX>QAYLu^ zr*}=l8L;IhpUrI#zp>5ERpd=1Ga@23@VY0|@GB}6QBr?Xr-xN&yF42)JU31~HQ(c7 zsZ(H(Pmhpn3WEsBtoAoA<4I+l@vFG?L_cA_Uu-Cw)A4JMy{cQmddB%2?p&MUXC}{> zCzQHBI3>9tHLPI@COkwV?o|ZC`&2coJ3;j)KV8=Wtzd zwbZ%8+!VN&HB1xbpuk@iW3cw=GheyHpHQ1Z*w2H`5aI9x?vd`@A@PgV>E)mDd6T~R z0{zocrb%P_3J{BwwfC1~o@>QOK}Kt$RJs89LjqH3^Jgr;&N$*qsg_zG@DD;0;wJEk zfbLaZvf8)aKCJ)|Uc8Fer1X?FjRTK#S;o{wJada)Z)iVn?B?6!_8+V*Q{bjhiJ&++ zik*;4Mdz#?)-YU`P{=S6P}xw->9BB{@=uziuoV&?HKbKCdL7cO!$bxLMUiT#$MRCkUAnq-GNWz58lyH9Ix@h(`i>nOozjeDe{5~4`zl}F<`m~8Ak%;>Z zcY1H~ANpLbxljC0=5+t?f8zvR+%kfTgQPJxHyFg&7WwxIps@}&0@w9X6KL+DRnibG z?Mr-BOEt|$!l2D_7KgVA4Jhk3D-3L)z+Mn=DHRWenFK}IOQ<<00?t-uTXh`7FmKyN zMRd&aEO74myH8u*<3b0@?8Ee}(UcyA`BPgeyNkN)Q^uYmF|KNETI5K7tyu-MQzOT$ zGTvNTIk3pvS31>d$P>RdcWakWCL`B0f~6?e56~+40H15R>13zLRb~dm1Qo}lgScUu zP<-f@;ATJ#z!wBkqAjpDi~AoBs;N=G1`d=ibSpV=*Bk9V)k)J2Wvb`m#>el-dr#QZ zp4|xcQ(cLnM znTRpk$wbCjRH^#0g7TiEz112_cr2KI+~f>xNvw7<=SYa?u$4;wa?U}@EHP=@(hUi; ziLlQ~`eAaMm^!PzKx8f)v}i!z@`ktIi!My9Lj=lHm{X3tnp3ry(^9LYc5Pb}O~J;B z9V_BOCt;=0nUd2a+9fp#LYEH9zt~#F$0xB*CnO2MQY%^JToYZU1t5$g0JjHOVk~6f z(+YC;^5g-tP&bq#-yo=KQ;asg`zeLVqh2e~IMO3-av#c}k7g0X+M|`Q44WA>w53za9larV@6#XBT-1(}r}UhZaZ*~G+v{WZ z6{|CsclFN$Ly2+&_$86V1^iV`8PSLb0PJN?y#y92R+y@I?I|5{^X+M?73tCs@2FDGrp`F!6wb2sK*om!$)-bGc zAucpu5u+x0DIJMY|E%;=Lu%G0RB{5oAVuoeQXwy3fXbaUAN6jujjk(2O;cC7(o<(+ z#8Ia_D_zucOZ5CMHbnm6&^wo6yw0{~yjL7E=Q~jhRkgU8pr^s8ucs4Uyu(hm+7?hJdV{y(%sB} z_-aD^$hp$EG%R&kp1Aq8=rzP;GLc^DpN$mz?ClavzgcAc`fmN|>gW7D@bw-@(0ZSZ z3$Kc(n6mZYgDyB=O741qNb?P~m|DY`p1Sq-4@_E`5TJagsSQ_FxeW;&t0<;K<`^|In+n4|7F~P=&T|J zzHV|`q9U*o3o;Ikw^6{%{Lr`#TmkQVi9`XOw=-2pyW7haH|;*GniDP9)Q}97f!h1*E_h%N7yLzE$)TM`9ir&<>VhN(dNc zkk-Rv1wIufFL2v>hO?Oo&gi%E?I6%JK`4OFOu$_T_Odela=pLO*a}4gSg;yK3bP#u z$PkW^6f+Di^)&HEXcRM264(9+=?Y(SfndN@Y|2{-U2wj{3SJ{>j=RUS0T z*adQ}?~JT7A$`xR{2IB4Fs_)%n7`<;Gmy1KG+mMwTZ$~0tsf7++3)zyh08c*o%vv6 zZ*#sr+_XpeF;S>|9v!&G2VAqs%M?2(gyZ3Tvsc0p_tAssoIEBOZ_;fVR5EyG<(M}x zcWul^Kv&Njvb4N`u7(GHjrNyJ7|v;8t$o_N>$WAfqB+gvF;!R<&s5v_@%X zZ5}#qzgL=j+kqxT(cn)VlPL3rTC z%z5oLVzs3TPFo*x71zdgs<#^jLg~oh%#-{Pht3g6=|pKTqR$oF?F93(>r>nB5&6w& z^9OSCj)0L{e4Tg;ueWDTZct%wm_d0uo*s4=p*+88R-M%H_l(-#+fchUoMw#4b7T9N zN2}v5Z!I4sh?>>zjCjDGxSK^AW`2R78y88K1}I5s2Z!c4&3*09L{IX^R$RfMguNn2 zhU*8)ASaJra?YACfJf=WB(0y zoD*{Yw|j0b8-j@b`z9{@<MQgm@HRc#XugtOZBb zC3pcQAf>9G>Y3pE#>)nX2itxnkzXspAA0->9p8N3IThS}+Cb%z;*ZoCX?SumYy8oNqBmW;FD>pN12PtEKnce?&lHYKPPw!1Y@7^ThO#svYn^QU}Hwda*$x?&F zicrQe;;Dqv@A7v{vS4DrDjeu=_F?FVfmgbmWvhvPlH5}`aWLmi%v{o4>z!g};#vuw zFMB6av@<&-M~UHcgxN@Fw2E}pJEir0wK%udO67XYmM|Vt8$M$zkQ2BaW``eh$3;jD zO!Vxz@^z#oHYDZX8K+~>4E!Q1W!BZ0Sm9kI+-NZ_2eoz&58%b5%ev2&JBaTGA2SiIb^`&F?B0m?9*b9$K*kIh^}k4EHlZ z`)&-WktiG0C#1f0lqJ${bNgvs`4IRJj}^1#B|<^kRxJ`d2Pz?WUjzasOa`S?FFbHo<`{)V z2B}KpCavtb>HAsT7NMRZi(XuppSvS^U7k#mFvojzWBwHwif5@h*)|ZYC*?~5Wkxv1 zu(|nhe+Km$+>MFj#`eA09;85G(CNfXA&%LkE$*yR;IU87g5_c627NK5T#V(G+S)Ew z7x7xCtVW$thL+gG_hT6d%A{fPDt7g1(Ws_P>ZG%6E4W!zS!e4se#T2+t|kX~CC@xP z!K_X_#gQ?Wk7{1*iM1b(SvvNi=44ua9jAx7vDXWYS^#^fv72Obvx0%kmfjZz$Ng*? zHXt!x(l_;77l$7HNpgqoO^1efhK#ExB}~b|+n5H;85`+p3fpC#-JH0p8IX*{F(@XD zJV>X2bq<6U9!zC2jF3alK$dwGjj`P!O@GUr4zbP;_ z6(k2|jlo85VW*`>9i&GFq(^7qPZZE?YWIuib;{*YmKyVktn*wy;+CEJ7zL3Ha?Bv@A_hqqZH zMhxyd!iG3N!x0uxwqtL@RkSd$exBVj*CB-%!Hx?!ZKEtC_!J{H6zIF8v_SSY*DJ(4C+zZK<^0L<1GO{L4N%Y*B^ zHwKS8$r*{s9_*Kc=V;X1*xTEf(__jvJqZ@=N^dkeuNW!Ocj1^U4;58o9iP+(LaJBJZ_x@kfRaTIoeSL#G#5c1T;itSzP(c0 z*iZ|`P^_sU`=oAuWJ>zzueL#W=DkMuwtb2oYD)wW0AyytOYp+ci444c@ zUUA@N(@d3UDm0nu?!WRFZN280O%!4Y9_uqhs7E#_6$1ZqI4vsd*M$wQ&9qV`olza8 zmxv@0kHzR|?)ExNxZ47I<3eF`Kwt5+<)lg*?2dgxZ5QnT?s* z{r4W4fI&D*ULzAS3?%z7`MS2H8B1bUExbTmX9JD8V$IeN?I%ko?vYhC$sCg9R6cf` z4YEdlR|0e(FcVH`GrM4r z%oP2YdtU+xfOg_^&D_F9Sw~9YM~1KEWv2qh(>=K1|K) ziW|VV|5l9c>Bm8FIOiJbYs1?M*+XtX*6GTz&y+kbbI|-~s%`0rN>?3p#eGdR#;mIj zErt=d#^M9+E8Ig4b&z@oo^53SJz#`KXH&=)*9j}C9f9{OJ$m4=V(2EnU0@=7=S! z0wf0gA_dR+%J-6U(!Kg1L=V|rS60S(;NT2TgfDQV+=8doWDyo zbqAy{7*cD6n6+N5;%#rYg3;z29x;+Me8)D^?x-jHXEK_*3~^lE5sxdH|DvbQ;InZh zm;8ybp^7wi4biO7GngvhY+X=(dj98qbIV(9)KJc%O-ZH+D;v0jQ|hq3I0mE0_eoqB zrQID1abEPVab>ZGfJW-c*yV!}$KZQLCUt`m&z{t=5is0gFxZeG=cVxxZVuFLI*K0a zblr=1;~6D8zJkfI>E%xtx8A9jHLE9h|H%HVvG6sC{nm|J9Xl$qwehh|I&W$@-3}7+ zX$T{4y!x&wvhVzjr=7C&7pfP569K7aU5icn=BxC*0xpYRZkz6#_KbE-JxbYo;FJkp zYT??#BH{?qVhl231~_+RZ5t{%uOKGAc>qt48)Dvohmpm_ZHN%KZh`Ha*Yn|K9J|JLl(J*Lg9TE~qILSvGy7 z4$)#hNr$pRBu66CoxD7Z#OwhE3M#SZgB?x?4=YLD>Il*MCd&C}2k*VCgFT|NlwIId z=&;PnbYo@L8xv?KDEG&!Hjy^S(O@3dUj>n2A0eU|0qbx8m4dmV9G>F1#v;#=rr|~_T`p@~W${Vc z%HCgDbD`**s2YE6p$iJ%Z78!*qqInx^>?i=wECMXjC%`f?K6)6yvXqg%dj#yrVFL^ z5?6H=WaeJX%1p$PYC#UFE~>V}bI$g`Qi2XtL}^RP83~jE$tVLd$GK@ zZLXZ0<{8~SJUqNBo+8h_iZ1CoOX>CD`K$5ImtvNZ9yP3c*ACa`=cg!glkse_ytp_% zI_=4GhkI|~Zut8A=jFMb&&T;Y@%6k`ZF`;N$7Asn1bG6{W-sY;3K_wciP`Z~>@)Vb zu&B7X^vmYL9fnNtzgp-AJyq%3LP;-uK2)JqH}Y`o_Lz*RVWKZD+xW^aoin5tZFNPR zA|frROp~X4BXY$FvXDH8mXPD{cKtk(C(f0~@ZdLX!NSy6biu{r8vSkgz+~a%hRjxU zEedDOw(SbH&bCboht9TbjG~unIGI+?wk?dZm%6tHTr1X$jKY^}*_f8j*l{aey)WQr zoW1KHEO>i);bsQS21nW)mu(c`pR}V0niVH?S219-lIko-YR9h4?rby@(bd=3Cej=m zcFskKIdH8c^SXLA2jUQLb>U`0lpn()fZ4Y!b}42wdwJpM21HhT5`t*3sy*6+Y{1lR z2te5@)q4d%IR_fNzaWl>ZjCaGepw-`mJK1}tVRf5J`>SpW;dGAVcW%D!&90p5YyV= zu7^Ou^BZl;`;DQ#YH;KWe54KD-vC+7Zr!x(^uNy;)7p2B)2#g zsJsimJE#jZd)@(Uvs)pK;;-%6Z7ca^@w_GmMchHrJB%G@q$0FY5r)y0>&ahq6SCh5 zlmR#3yI`CFKO1pT-zGp8*YbM3*Olf);@|Ee37if>g0YT03V;%d;73tjX>CbT`Hl>r zzEUwN=(x9|VnkQ#pu-^UNrMt<=I}$)nq*1KUi}FTs#w;GBKeuN5Q-RaR|+W^8BqfU zE1@8fADYL1Jld?L5zpkGhpq93J9{d!c|-M!F#i2O?+KBaWclq@8t-A3%D$kJ+B|}E zuno)p5A`R*Ff{xRrUc;o%+i&Z6L4Amx>fR8AJq}S%1~_fLDI4i*Ev+e? zw3R*ClNl9q{HDx7&dRtpsI|FJ{pP!t2VEMJw#`{jkmmBD7=v5srRNkNiacD-?>RU~ zaH96ibap{W?&Hh2$6^=ud@6a*w_nE6)S&CVp(M&&2$)tPi=^j!ljhy&CVD{^rwsn0}=1Jv<} zu$(BFan={)=kS~~(aoZ^G+i2Q!yx>&m5gpata>nR^i?Y!yqHq~=I=c<0U)(zY? z$Q9QjVsV!E`7*O=#xsZ$>NnqBe?9|@1Y!g1`BS8(tjOvIaR*ic1P-3BRVvjJhM_+H zV7Ww;1S~j%oBK%OvY~cI>Xc(13Cq4@dt1S>O0&6{Q<_qW68E3_wJ(!q)Gt!lsDH3@ z;i?j;(KO0T%CO4|bMBGIj+w6>6`sf|H z@KU0k^C+gFLzvy}>^cWYT`D^~yhf1vXUb9#VhxaH@ScpY-RAj30m*OibKU4tJnmN{ zUSC$*l^k?zr84$P=eEtopfJJ_WI_#zI09ugV>e&u8jQ;zEI@Wc|goZ$V>ybh~IJl@f2}Jy=tn<;ye0?{1GT zuQZ=07phKvoZVwHf8EI;PMWT2*PP!k<6EN%u8ckSGgF3Xd_AwxOe;@iu?=^T0v`vh z?qJ6$z$#LSX3*Z?Oc}k{eq0mWEppRFs=>~*UPXgrc%c*qlY0t)$A-G?3!%M`IHhBt zpHuZ9jZ%o?jKnR0V@2(aKb23y3;(Hh1Y$^sn~y&37aqEdYo8tesOi5qAaZlw_&r5> z?p427vs?`e0l!hCwjaf9$i_sXFW*^LC!>(gg3e7*=Q6M1C9XcQ;wzUK6-2JkoXUee zA&@by8ed1J9san~DgMz|3MV~b5d5RMOkBIcv!Q$V#7wNhAV1ZoM1|aV0jEqT4mmB& zDmVHQC);z>gUVd!{Guj$m2eZZbFRxqXm&>5ek zP-t^>2IaKptFmstbAhM0XN@GGJI0sw{7^Z!!gkOT&T=Tyqop3KJ9K9E>Wb5=-K*bp zVqJCS2$au8nNa5C(fejd)FIxS4RSe!%N^QpK82akegvCp%NK7r2WS%VE|2R64K=T0 zS8~I$D*0d(4S;KH&YKd&6+KAh4+k}UEO|1;y*U42+LUe0_V!dpmEV#}*R^VbXOpDe z=nc7SOX{RIv!qQg!OUAP*M8!S-DB=CtZ{7SNIcDFQ3n3#Pg8$X=7-<_pWCgM)fy_l zKuaeSk6O}of=gLZ!AVe^NjteUwtQrk{K2~J4}BEG=CA9v*{)M1&U~J>XxoV2|f@lp47eTBEG|0+z%0!!iS2ryeu`$-P*z}t_;l!Jp zElpwCKVj;SNX#w$OF&S;*dAwm+TiCl#R~tP6;E77{DJ)FLk6`>9Lp9s-i|*)McN*h ze(D(Z3P!opoV}qs{U7(zyNLLf2HsghW!CActdty^r4Cm-gBAZPo-7^NA_l{DCCaK7 zNv#>d*=YGzNo`N=^p2EWV3n2;gZE(pn@^%UU%{?BpzE=amT^%!AA;j^(oa9Mgabd% zU=Gh{4bSXA?wPC--$J}$$Xh;v(DsgZQ~^YbpPFeaAT99pDM9!?zn9bbX5Iux3zA|? zyIxLk9Dh%(qcNk|4rmw(soB2Z?QE&lKyb8y1g%z6|f3!Oo5 zT*EFi%!tX*-zmy4Y)QUU%{C5P)epxs_#QwpTG9W=DLVv21JJX#< z)vUOJNxe_Kwq^)|A;yt0#v|cR8H9tidx#pBu*oA|IV5}SwcgA3nHsShT^>`tF*R)l z&XUAOz)EBp;UtXj@>7W-QUf>-zKvOHRXGcNdum$xbhWLOoxFr;+6`mI%0kN)hln+{ zWkGf3$fnvV?|FfE=3G;sDvV1m4dv0K4i9mj3{F%1w{}zI{ZxK!LN|t?WK08=_1*DB z%WKyH#ypc?3ITi;PytpZ9eHJ{bVnA)FZv^HY6nG%qse!=%?kZCRWB5m(TR~<(t+?l zguoVs!A`v@G|Yy_yY8JqqvKn6z$)6n98>u9K(^aR7jB(+MNA?X2NTgp3XC z$_xfb=kpr&j12N(l=VjSlohImOLHm*K}+p7L%3 zYP!&!gPlZ22d!N*7{$)5r{sfR1CCxs@aV^3R(g*MAMcp@+jz6D3SXjdgT#K2lKB2XE9iqlssZcDIA=iop=f6MMp`eAn`){~FdAL+ zql4x`fm9n#t%(4KLp#fVu16@vFFyVrWp!$ro8oW9{(7OUBzU6_xvDjIt19pT8ZV_p z*0El^^_aPQN@A&xXI^?-k%YC+PEX5v$?*II79*xh=AC)g-K4eLfS#-YSvi_Fa5j6M>WM@1n6mQH9#UJt8xt$b`6N)i}_Zn}cn$(wE zzus)O0CH`JQ^^Rce}DPP`L~P0FU=u!xFar5>clM=YuC zWsK?}#13mZaACu{Dwz|*O-f@(!&<8E`&@n2F}Jzx-8{^WUhSizS(i&D!fs|GMx1{j z72t;Rl`wy2s=C`Fxk4@fP!fweTyS`6;jdJ2#E5T3%)xN`08u+!Wb!{jW-i9 zm>t-Z8)}pT_Iju0evcGxfaAxk5^WGIk>-uCNLRaH#PVNmLdKEp(i)|T(@+d#j$N8z z3Yr9dK&3(SJ5G~(V6#wh5p7QD>U)lznqMfduTQZQrJQ+GvleNhIY-5^U=^x>oJ$>bG^a)GXLAKAGqZQfpK_|u^r={q~4=BN$l)QBBkyYx3!{* zI#*SheG5q{wnpb%tupok+aAM4Q@CX?=5-003VfM)rkkHSTYjRQcOM|Ing$&zUt;R!$=mK0X@-b9{(qrs1K@~vYQ=xz`vL9lu zXM6~{q^G@78BO(afmRFZRh=$g%{}U@MvbGt=>3$kJ}%}`X>glJMUXsR%-0pRJ;V{* z!;urJF7%Q|!}Qso2b{EF5LV7a*yn^!7zT z>8T8*K6z+n!Ma^}qVs17=VyK;cLE6U^LMB8zdzc1`v2BPeBT@>0^yDIi$X!MWv!~I z&{ucD>abYqc)3W(yVt~*XuDuHq_WjE>n(|jJRR*P3ih&WsZv%x) zVE1Q5krqKo^|M@W#5Cs}y&Z)L?P)3a@vD%YVYj+>uC9{}CTumZ5S<=! zjWeRfmz-OC4~&$X)g(FN=Ek719hF2DMX-GDQ3;b!puy{`NGoj`E3w7ew-sH7lTU?M~IWBnQ3!Cp6GECN{3#1gxINVxRHH<4dM2TgYYj#(R`s3eiB}tCF}fH>lEPP zt~<(A^W_UwQ1OKIN}a%0b<`tK-p-gsuo&i|{xNT=YC2e=TB7rVja_ifDh)0K;40>b zrqANH4Wdu)0h(o4EqaQ+-rcvqcs)U35%Vh`+5rJnXm8 z7?nTX1)=crB=go1JWk%zY9sLbNG2@N_|4b-iH$IR7Y@SAHv|OI??Bhk@eWygL6K_0 zByzOC#R8mzz94@}OTsEo(?zEm;e-hX1o!{&bq-yk086?p+qP}nwr$(CZQDF$+qP}% zlfig%_liG*ovq`LKuQ$3dxX|ybLutZf&vQnS+ zU8O%IL3I*?%WyDqCZA!mreUPmy;M!CgbCf$Y~xJaP^tqYPFKOLr#TDFhf4gWQ`VUA z@gaoS`PUgE5X#e7?E$tWy`{QL=FPC~BP`rkS*L20(GV_IDQEPQ3I*EWpJ?v~ zavur4A68y9K(#JsL?&83S+yExIwu*JP&X$Ubjxh;O)=GsqOw*W ziQO{U=yZyjCV!*#A`iAjj!Uh)&YU(EO&0{In;6H)SjzR8ZFL6|d%)I(-{~%TO{69j zqbFe|7w8YD0t!~gz3ZC0Yhm^pWX_FKv!Kc+vt#1xXH?og4G}AEa@cpu?3O?s_L@K* zgsnBhv7R?8b)cxW-b;)3#z%&n_Okrw6O zp>7XXT$%*hN$bg2zBB9|O%-TlN{sZSMERf8Ic@8kg4{~0*v}uZZcR-bTU$F(CNgOR z@@AVRA!a5oA))X~KNR#qzQ0j*v~+T!4XeD~B; z{4NY)Ld($UN|{QW1^Qd*m>glfR)~2dEbRQq*5o2@b79`$B+aLIBmNm? z!eNqDlQSMNj9jT(S|Ic-VYduU&I_{I%Ca#_tv0}4QMs4Y5B*e##hMk$0Yx}Xztwi1 zMyK~5+CHMr*t^bocGSId_cj9LMmiK0IVt}s^EP1bQv`XpJ!=DPIo}^3xjBha;tb=B zxL2RQ`bJG1EUISF?hWn99S~)S70pI>C}@fCz`V{~saY5@#pww1IRqBrABhvi!R-oF z`G?HF%aw0l3Ke~dp)IIuB2z==RUI`(ss4q>lc71B#`wM}57yzLPB&(4W7G*FD01b@I?zJ3-5X{GVINOktLO=%-gz>Fn{(ok7U_*UgJ|hz zPb1_V)UT+~66*mn8CK0Hr?N#2Sjoc%^eps-(kqNf@f9I^Q^wJpe74nr>n|OH)k|Bb zhrX6Zwdm6nYb}GXoZ@qdOfcyIdp^{`)NJLu32EOoP1Nnw2yBU-LsAT;pyM#f&jHA7?0JD+3kM` zv}o^%(QlKU+dQqHiD7ek`(~}>9b1{o;h)PzcZhf^y=%PGDl&4xtT}pv^}Dq4%!v5O z(}HX0uHAz?TD3)StudD+LBc$%&3&q}jpJ0K1t{+GS+ zk%8?RkI*bDvl7RMeychg1H6&2w>Hu7*KSZPyt}Nu3HbbVfBl62TCybutmvuIn&eSX4KVWAR&vc@N9F@d~yoxVTvZKu#%g#`1Y1QdO*;`1Wav)o!2dl^A2bDnkwKq6&g`Id zwg^Dm9Jqfb87y4CQDCaP?T{7sqR2v`xp?<)D412o21#{I|7i7V!&XNI2wuq8SY1CK zpsIE>d?tBXF9F*W(8B{F%#^#1EDNU_a;ytKt!AAMw2J0ow4pv6a6NZ1%r#J>z>_2^ zN*ry^wA;>;!QnM4fWC~Z{5JFI;l!96Ud%?OtmNsc{ZWFP^e+ySo%GKto#lX#W}d(> zPGeayAnn@ihicYXAV$zJ>Dw7Z+>0b(-}^)X!wSIuHxk^6%?%1o=56m55Yz1e@2VdI z4KnmY+zSsY{uk~7W-rP=C+4$`e*2?=qqELFamkj(yB?j5YJH0^O?%9e*WF#Qxo6cM z4poZBfS@*)qN&B~nS5%3Ps;3wo&lJO#ta+i+sur}XR&A<98uX1JS?m0{%yAtfyohK zE5pk*EmZ8a5Da4HY?xt~E$~vSyK@OkB53241mk>|aDy;>6gaKia`_z-IE3Zl&Sl6w z7+TEYQt8dbyr3~G)9J|Vx}JI%r++D!y%$W}F5F_fP<{lq8|rTT0uP_<_~Azg+djO; zX?AV5Ej!>>1-G7av-0`Mh#o!g(dhGJCf4(W2Yfs7S$&Ai)&ipzgKf*X;Y3gU_Nj?q zvtv=zz|72HK{hiE7p67!A{nfo79UB5x_XKT@GpQI#e(F_5Km%_w09fP3#1#v?cKFt5Tgo8)fKy){o1fm`8{1J8?iH4H-9oq5f4ACg zTBP2}0__h}TbS_7;8Cl8hW;8cj_x7S%wRjYDo5)>Yp~dSxQ|HU#9Hc3Z+z*3b@!9f z{=`Ne3$P$D9&rZULRUgVWPRlpM)-#d5v8_Dpd{2`ziHbN=Mhg>Y+muCu_?ZkDwP#I!NUJQ{vHnUFTKC>T<$oiP>Zl2vfm+>=5xv{LD;|K z^qNq}Q2fTse8093{xbcBVRwD%yp3=ePl>HV zvv%M}nXhn^YCILFh0KL3oe?(68J&@67(qFe>XBg{o|mD66)O3zWX|ePzn8{A+E&+hh!xkmuE%a~ z=C-@(`VEzxwUvG~S{w#2+8=C2(F?; z$J#d`s$usf8g`*Yl0%$dI?dYZp6h#>EWv_$DUIkCe?sA@YF|8?)Ke(ujTAbwcfXs< zM6aBkgT%v?j7gHAv$4w9Llh-tl}tm%NnJ`GQ;IR4&Xs})lC&oz&zIxhvrm{yUo!tM zo%%e^Sxstw%4%0RyWDJT&T6OJ@Jb-RM^Ejip^#tec4mtS&{~)nBgKA4v}oW`^9GUp zw7<%>1~AXx#SnR-LrrMmCtv!)xPcHjIb>54#$YeX>4cL}Mv!m?iREE4=&}~4R9vQK zCVpW|((NyLdMbB7r=Y$yn$?&h0OQCAh+Me;>mjpVbx(_t!PV0K6Si zM1bRz6WxtrZw_C_cGd$v>p@?Qv3HFtc*oRe%Uk(uTer#2XR+%OS)@)B zQGo_%T4l!b1dsX$Mgzsqv&5l2ydHRXJ@cFwl8-hldVoy>&+6Y~@^Y6pc{KMI8oR~Y zlrE&{*W`M>7K+ln8+yl2uIFSre9F#GWIeyGN(;SCUp;-eXA9@xE-+qRkQLZ-M`%sF zq|pi?!Dj?BLjlqAg5?As9pIwxHh?&Px^pD-9Udt1oYr8EPoa<{xs19BZ8Jc7X8Lq{KeWm2+%z^A*Vj>wJ~ft2DiNgp?hBJ@ni#yQF?~$0mC-)0 zC;rm_0cTOrx309;8k)*NR4!)VQHgB;Dawmee=Kht(uNkn1F3f3(^G6us_D=Jv8we{ zep~I#5+cuEjFqa?q;6y*Q)G-*#qm9tg zDo#9>3Pf;KmXv3&KhA_@C&hf<$|6e!>Kq>IwGym#a9GO#TvhP1BcLQY0|Rtfh%0_- z2jtR;8Py})^nrKmwpPJ#klQP7btxCmOSyeY3_IH zD@$bu%Z9zRoUvIbO(o6L{Z8n6G~!?ki5>jy@TP+MU> zISD_YmIoHK#~$S?xIL@rnd~J~Ou|*=WKaY0)k!H$QRm49F*WT|2x|ONiLKlJpzKW) z=CAJlBbS!Y{eM1ewx&*oGKQ{p|A49g1KLZ~@-|R@e&#$>8tKL_czXr?1fp@ zDn|4uQh;RvH-dx}dX{*e=9Qg2aFpKHOleEK)wPB76PxQV_bL-A%W4~o>oPO$iss%< z^K?eFy`9Dm(eeKB?v4GG*3QDP$>j^ZwbfAA^UMsb?9`WrvF^%lbI`=%Zj|{#R9S5v zjjQBi8bEt2NKw!3YzSW5%POZur-Ef<)QbZ{;xcQQkf!m~WkKfRh>1H#$%sR}%!)V> z9923T*}Py?hpni*`ZpA~DuXOu4fEZqyBHG!BsrLa0#U)MRV3?yf)R5Gn>Tff!|f@^ z`Jiv0o^1=BS=J&>MA(xC$8oF`Bz@Rlff~`^1_X~AtaEg_&t?SKr_$)Ofon+8(6XfJiw)|S;vFN1;`hssJH z@>qdt;b?N=$W9?Gk^F`wN|`)jg8a2i2$CenRJ7!HNlWhBiVul6$vR*;InyE`gIAVR zs)>_=(lE}smBn^PC1BbnWn$%fjX)Kvq7#PjR#c7vGTn|W%dK`%XtKYRs}sA_s$5}E zB`s2=9cERUrN%RARZ?S_HEyY=3W3R7f2QPe>$eWPR4rKt&Ore(_@P`hslQeI$XD|! z7L|gMH>kdUD(x^e>lQVc4iU5l3UX(|dg2ARje?z3pd#d;wYR*uvbfaQ-8n6RK|zfL zirXIi7aH%H0@*5-rSIa4548?mWH0SyinT*D%#&;quNf77`EB#Tt=4PejogIxv)H5} zWw(O0{E2X)E0^s#r1{ZE>J{&{>39*AMO<`C+avfi(VkdxH`bSTPwcHjSAhjJp~4Oh z>fe@q`oT4~_n~2T_K|Op*MiIBxrMZN4B0RRO@0vHK`aFMi#hv9T#c@xRW>EjiOpfAMfm#QZ#ZH6I1kpg1_+fQv}{@!Qksf(m9p15_!SblJjP+b?%XWUuFkb>Gk zaQF>eq*AFW2IlrcT$`bR8!v>Q$$ET`P6@6t%*f8IU@_LLs_519mHLS)%NzT4f!LGl zimpX2^s$WkJHbpmnWowmU?cJeccMvH#0L5~&YT!R8Y}MuoOU`)Qw!f+)CoN|m=y76 zIxNb%H08Pt%^M5VNwv+_B-kb6T{638DRX+|R}K}mICy7Ed0)8E4ByCZA$tW>FzQQ8 zSI3U@Tm$m{5heM1dc~=w?^?9Vt(qnNSo-Xm+AA2W;K9(4Yq{OOVbN*|?Tg$GUF?_K zYg=y5i0d9At?~i41I!H6=v9P=wi$+P>nU?9LHxSx$h%-K)NIES`Q^mP=?YsGl@&k_ zfz2Fr?6^wc^K2hS>Od-wXA8}Z+pn6*O;S{*f>mUgVoqPH z{t!N3YKY6oT?XF_QUsCi5D!f{}5o%W+g z&MOcP{Wm|L@F9>q9-rfU;tA|~L64gk_7$t}L7Yg-oH$a&F%B!9%bVe<7aq<@wcGG32MQdI-1IG`HGA zvNV5Q{(vwtgA)=}?Nl)`IWLL0wnz)S2WaD8UAjz6)USM^{%9GNrNyPGdISx>H#jcX zGq`4xyy?aR|Avb@P8`MGKhDfBF=9kcApx|pvA(vlx=woh{j+%KKKG1u5ifdIu?21ydlAmS@t+PAouz*kPZajHQ>H*s7! zG?0=;Dt-KpjPVxr8+s*(<=mG?+;2^(^pfcATW=OlMx# zz%1t#|6^MIJJmrtn(*hz?=+3!L0|K}Pzry-z>p0#Z9!h;BjqQydNid+IRo0X{a>H+ z=Ih7xh#A7bPR9NqFJK&TWmdZUEY!lx>2WXv??yJByEIpJQ*aqE;K1>jPI{^IbELt7 zOwKIGgwv_^ep+$G_N?gZM0M%qt}IonM1LvwszfUwguKcJ1s&R>wAyNG*u|!|nn~X0 z0LkHc1}wweg9;~IS1f1pi1Ubxf!nillKEIjO;-557|Gt$sBE%{#8Qb759ubI(AdF= zlZiHOMkOn9?x)oTL@47F>fg4T4hA1`Suvyq9oh!jIKNr91FsNB+39_QTi%>XCgJs( z@!?))o2XN?T!^V{UgGiS8746m{#Ys*5Ho@`Cb_{Gj>~#1f118a4tvIwez zplM!pp!K^4w|8dT5B*t{4^V!D3Tc?cWjxV9fNiq?{&4N|kfz!eaSDeuA${ZHgiOC_k`t7)yvRt@G@Cs;7Id1oSjt>TapO#HC7VIs??wM7^9s^jK4i`vypZ zI1`WFzaIy&aW2>|L|*ilv1TJbQrepp#!9vGzU1A=gJX(?PecTF2jVMaU4j(XcKI`j zgEz-Gs$JUU8W1HkV4Yg(76d@{ri+=nvbeRc^C?%t9H!9#v&zlB z9C4)JupEZwo|IDK*p4`gYu`p^(I@WK%i>ep8-7==kF*w&%1FwSq4= z%fg6v`}6bfD_!N{oEK*W7M6WbsO*y&tf9pca5+4=^X<<7Jrwb}q%HJvA;b@<{NwoT zN7vzK5fX7+Ii;{QvMN~NRpOgV#?#vmsM-Ziphp@nM8LMq=^}Hf^l7%`nG{lcNEIS_ zND|s*PNqE5OWY<5=I6_ABci??E5Bafpi=8n9I!>4YnBVo9k$;1FpGXB-(SXNZo$@0=wO zih^#lRd#3Chl0ddXPd7bfUEhFntvlA$g1z()ly&YY$GOo8*H`It9jAj%lixoifWVV z0Ca`GSavh%C#)g&6RzcYf!`tb2KE#@6K>g%kK!;u*n}RPmXP+8-nYJTZFUnn+_}l5 zuAPv|8O>K^6P`KW^(HuPhHMkGky}TRrbu5*n&83r;0tA#i;+STTTeFM0X1f!{bBR# zBv(z&z!kGk?J_P?EI5AGje38q1^y-59q7^c~YJZ_OJigGt2m$`P2jS|ZF)NQ>v+VWjpFGv_sO zHs3W-vWdNG<3^LezZrQ8LpKuwvF2y;fP2oBEQXOE95*PAM!;v}0`nNV!Oq0glIMKI zowQB%YEOAG4Rfn==DiB)Nlv;tgy+hloqw$1z`<855?%aR?^=;vqdzQ2Er$Z6s$N@U5Y)X9yR0F@ zMOyb2KIFg2Vl2b}%mlW-Q_AP$|5iWfzuAU>6SK#Yd?t8=iOhHFAAL0**HQh({@R_c zW&-V{-WCJ&f5H3B&HjeyANy1VfF2(~LFN8V{k{{sm$S4qtb9`W8!TrXG=rX43)i%- zjvZ>{$5gnE(xx%>o*JkWUyZDkBvjTHjh~eV;Du|Q$-i|Fk~gVWR~jip8MG&m`HePn z%$a(V1olkQ_f25nb5|GMmB}hmWDk_EZmhLV(AWX=JB-)<;S8)ZBq+qx&l3lwE``Wa zj7lk1Db>g%>a!ef3_)tFT4m=*RT?o>FC+5DI_dZIZLrv;HWi%jV#I+x2i^rUa9I#i z%`B6d`!XucG)Cxl@(sQcgN@QAjb~E!3+`8F)1?INy2QqTvKqp?=wizyh!rv1mvDN> zOHkyG6$$A!%A_*`DWtv6(@^rOP&loa^m+e>-TZrQaVZd2h*M6Lnq<7r!ii!qhW&OM zL;7s+(d2k>p5JbDq7iW#FUH!#h!im<{<@j+>PE(>B8_!upDBqQ{f#f$W-`x;lSvQ9*{7D?pB=ohJf41N-JUk79In z|LxK^r=@h(}R1awK%HTFPIlMt?tS3XrdqP+b>(BfH1OUVTs zYel^qeYL{oiRw`a9b?#6zG=sz=23|&cI2WS=t__3t>ZQa$i*va4Q82DwNFOng1Y{q zlsKlkKN#g2ZZWj^z053v?F-ii>}_o~#)s*mz0*nvb^D0g?kF-`vIW)Y8}@!v;=3&F zzTi8$wHyY=j9?q`B{+@+q)IPaKEoiJF=+`6<4Bi+8_4%jP)Lz0^xd4&x(HQmQ_A6z zQQ%Ag`S+1RZ0q9Dh3~p(ZlR?)*scuv+^rLV{AM^3eaWvgBrHKUYL$HeZr(=ga#0FH zAweyv6_d?to1qT0n>S|1H;fhT5C&b$Y%!Gupcp-1N|&PvfS?oeF&`KlE=MKik)ENy zBW1M=&=G%iiw=aLir!j3u?z^XNHPkUdxP0-c7$RAzd%@x2hA#GtNtQ~qLxap8> zp$E))5lMzxL(>{#H0XKE@bw!(J#nvnae6NpmjtT%AWgHY;tGMcUd@9`LP8<@!eF9U z_^BsNP>Tl|g3IUS^Yp4(_-T1l_-T4G$vphLLzB{rPm~^RVGgfmmt8F9b72d96fZy< zFW?jKwSLFyTz|NNL31LiX%qpd5Eo^zGw4MVv!@A!5Ya#Tk5`1>t`^gbIjA>nm!*>I z#1!QRXn-Cq@V>8<>_iol(&39Hpg$()3;9~g*D3}r^5++yXkASOr6;kdeJvxba|Bkv z58=lYLl5timz?AMY2y%V3)DgMx#a#4rN{RYgx(wg?;KI{7lIETcyNz^>k|>{ymWJp zpBU|v^WUO$OWYoyTMx_(U(j=Z%(pMmIK?*8miie166_jp*kZ1I#xh0Kx5d3c9qQA) zQvVWGXP}QmaBjj-e@HxPIqifZf4auQ_W>g9jT#jVKk5y%E9xy_QVUr+=MA>5>cl0m ziTH`62VRzrZPT5rM$t5w#iB;tlP;rZXq{DEI&7>s%s5O?{hj2lN|mr)H)vE-HChU4 z@Iih&#$TslpCW#N=C%G!`~!(P;-o%Ejc(AUKG<|0@Td=NlxI2%{-7j2F^2Dy*)o4( zh_CQgp&!6jEU3Q$KmS}xt&O0x)Nv3tp8MrzYm38|F1zefqPDj;;hY_sJ<5BMXyKGZMLBdx$+{2Y~5T#v~iCc8- zbFNW_c_8EzCzO9lp82QEt zryo$(N;)UbX5_x2H$-jBBdkL{NplB@vS^<;bX#^=MlOGO(g=U92zaj=0WXBZ+YxEl z-l29vOS`*M)XO|j&urTAwYNhl?Or*-9RX2OadanjhqiN>`}nwTA1avqTc^_>I4O5M z{L|z#7W=b}`NJ94PwAu_U1E7$l{pc%ZE?7#&q_VQ{~Qp-dwS>4MAHwH23?R+_NolO z0e#{O`J|3f4N@>KZ4Nf99jptM*2DP4?mjOb#V>RYSoB;rPO6%%Vl zDdc>UQO)69W4JyM?2%V~rFAKg!QgV&zz^NimVTwm=_|SsZ>;GKPgDM6$-7p`D|TqN z;2dkCXc@D-P&NPQufaRsQY_o|d&W8BHi+!WBiVo`t)yTn2rUHvxSuAsoVLS*EjOjZmS;`Z#GxAbe>Vq(6$d_^`9&1fdY=Ibo zB^!u02O&ZpXO5PY$o7^DmWy0d4(ji)%4Ai>Mpq8N6l&{3&nw?oy!HnE1job-y$hH( z$=#l#>(hJhC*C2^5pt_~)0$&=aY#O$Fsx4qJBQ@tK#BUOLUnSXGHMqRlGz+&j!B*~ z&{UCqwy4Pi-=%iI0&jZ;>H?^~gsLOV{&4R?oiE~kC)AlOU*_ALq2xowJ1Kpx$rqb< zR=QuEr*{VC&<3;3O87)`CfNm7@9bd5@~SB^8k zujFd~vT%T&I{hAYGS#Qp3HVmc4fx&t5$^6w_^>qjcUZe9pz?7HYV&SdeM96R036kHcBMZN6yI)=^;%tt9 zUjSe>#A7P&dLM1=sxr&JVF;7nCJefAIRcgj(Vx|4v>JfJbWYH2;2%@ssDu zcD5Hz&i!smWteUM47FJ$PhR#5`iFFsZg|Hg2P~V%u-c)YX=v0h^o#I8hI6fAJ)l(o zzOF)ovRKbA)nB;suzcf7`v+H6iH_OL6VV0S!rp77s(srpp1V)NGnr`Ava)om;4@e; z^h!j|hRmJ!qPviX{l(m9%R1ML0z0`#&^Gi7NaP(+7Wi|?@eQW_cJxg`Q#p?kzuXJ9}g97%k zi}EL3rwK_R>`nMC>o8vGT{#3feMW{V{GGoyC=vS)01`zSD{+Sgt&Qjx6~-s*#(SF! z3JWW$SLUewJkAfY>O;25oc%!huMAh8ZA9~;33s;KFse7#<#r_pO!Y>gc|#0nsI3Gg zOTC&rIfWdsHDH#}I=c0-_(by!KU4EEkhtELx!+fgilV zC%VlmAJ8T^3%WzqK|I0RSaS@2q3RcTsBg-bumAfm4)VgUez>fRJmL=I)YX~1cEPRO@!IB#0Kk1iY%v@pcu=^I^#)G zkx~WI#J*`(2ieq=O6erUG0F(BbqZ+I6>oZVcj&INRa$4N)``c7$i54n7I`9e)_MVr z&flN^APZy6S(>E$v!N;cTkt0MzjnGDTwI+@|Hlxc3GMUWvjKA1ESBvD2|#TsC4^F0 ze8h!{8lX~IjPofz&~n`@olSwPkYg|kXDYr|B=)`iQ)gsR6_cbQnVp=+o{o;0H9R}M zGP&IBrHaP}-?<)kONz+l-`}C|?Y+yd+4tPB*POk&cz?IsZxNO~qn6}QOED6*{d-a0 zAHkKQ_+g;LXFmC0`btux%G_!h=BDY-B0+g?3PuDNW=`+!SXoOFKjFHSC`wmdn_}9bM|(fwOm}EyYjkCnl$C1~1eA;0dhILPIx3V&#*MSs zxVBc-Hg&9`DmYO5ImnpG#0eCcE(axMfMfsHs>G5H zY33lYN7Js26d%kx$+fL{Zpg65cyT=Ux{L$OEMxf`4AdaOxC>F82_}>|%g2BLZwZz0 zJVE7^Sq+mAa8<&aQU8-=l|jY|K4fKW^hZC|_5DM*(nAoW@%hb2@FF`{&6WWI6V7(_ z+TOrSoxSoWB<$Ju1pGsZ?Hyi6H8FPN&y?Hw-#^p=^f?9dI+N*YxkBReiHls4g`O&Q z<)R#8fmb=r38zzyq)@5}+MTgbtP4tS3M7>iovlBtmH1^8bgybx^!1F&X9dJL$EB!l zK@Cxj)e3(ywF;nZ)^Q+*GRw^uMjoP0;IhcETc};227saKdl{4FTXJKI8j2PK?>Ytn zRkg7qVc(m@@=u+W;B&3Y^~xrUDN(c}tM&o@c81V{Y{^b-FZ0NZP%R9kqjKfW20*ND z7No9l`~nJb6n527EQ|6{@McFkXE;|QT_2ls`QU`n5u}1$HD^um#;rJWv*xEoP_sxt zfJ<*dl~vxiCrgGOJuhiN#vmvgzoQpUdrd~+A@Wx%hzvIXT5NKKjBptu8bA0DqM`D_ z1sPNM5pVwml^(&nL|yzdDu^w9)(r&7)FxRN%jAA~t`ooCG@V;IpXtIT)YZL!;L;>? z7F7T$&=glTdvi*M_~H{vR{#x&;;5=!Sh)a(+!o@XDjJ{L3+KOc`y`9~ZM7^=?~}i0 zq2b#Q*p7&D9?fpHf?+_l*atQqPC#Kd+e?kcnBqR%?jS^D(;G||P7!S7V4#p3NR8SV zRSQ;U0R-i0et(qH&x`v=gFA+8W^N(Q6Grwo<$rW@O9za0sStYov-zw=_ zk(+e^FmM$d^#hX^1k)kR!(IV<+VNBsNdcbv34#~ObpXl>1WJIJmdApMCjy*-w{{-+ zi3EwqZS_bG-pKe<^k~OVl`j8>G^m0SEqd5$3gHNgjRIQ;|@v5Y0hEAFE^rs zgj|}tC+K3ix|T#f`l~hEXUJ+=l77kO-BY%3jg$|nP`*LQoCNW)is_L(bT_4O3NN-o zQC|k%Tf49?ng*#S*6g1A=vU!9pNS9gsB=J`4e`qKBVFirLdDRka;?9_Uzlepr7(h? zpltclaVN#?0|7O<)==eOw-qL*^`Z)aQi(z2d59sE?Tp7V7r-Mex1jKs2)E??E3v*T zj5S{Umjk24tAkS=IaV~pvRZ7f6`8Ma)rEz%*_GwRwbiwajq8HB6S)OT8@1JuPv)QT z=g=uF99B$QV?^!q%W4P2t$t~?y>1$tJaP~jLp|f7{bsn?%cS;M&=#X5Em1l{ZaTBB zM{Kdede+bB7=T;41zc`>2(8H+f06{C&xQOwX>CnF{0ht%V^UKurS zbO}+}Aqs56gV-ZAO&zCyCa2ojiE*ypS@K1xnh`_!S;6)`6wr(@R2oygqGG*A8aJw} z9F{}i>eMJ1vPB;bpL}b5$oAJObav`??E}0C zwkSg~dkq^B_WW-#COspv%`}{h!~u%v>=T(;C(DdXW8v?6s+(f~ zJ7Ac0s)WC#^8dVD_gMGy8=xF25(k8kGZnJsS#!d$wl%u{s;ch}t{%C#M{X|Rdv)-5 z&3+it8X|w~D9euN7#_*m0<2_HKvFQWLkgI_N1j?MA=%$N0hWwcAi9i-(PH@+(g&|C5GIN=GuU^JNGLe$mWzG)-yJd zFooNZqtUL|!Mzh{!U7&&q5vn(Ck(0z_jjkzx_#=zl&@2qr6foD{TVubI(i>g`=&=V z4}n%xD1BlIqsMR}N7a(I-odrMqBK+ihJ6Mz&pySu_UpfhRvfhz1wE2#T3}!86A$pH zy_s#;?MsCpLP}gTqIzN3j4fu7iTA5s8?~VT{o1Izg=+_4+6M}h7TXnf*F+kHH;a@u zE{otk<%3;M;R_V4fnYvAExL?%4tI7bVVb_!e(_ayfJPt}`mhDrA=K<(zz&`@GBT)2 ztgfxOj@h~FR2J?Wc@bj7jIyxJguLgj{$jFxgk`nBNEQ!9(M7W!;A~v00eNjTRL5W# zrpiken~CBEybHso7iYzAl~*C%B<6n~oku`IMM0-Eh}M0*+`xrx#of8y5Fv10U@MgV z@|N8lIklx@m7p5K`6)>?i%7UbYTiqS<|m;hA5U(3Eb@z3;a_|N{4CQDbp z(wBz3EeXy~Q(#JU}1pJC44lMHIOIw*V_Z_`=**^`P&;dVDZ5`9s#FBf0x4 z>^QH_)IUrs?`U$?KG2${U2^aD_D{+iE4l8l`ygDEJbh8c#ShC< zx%m^kU>`@Ze$Y=0%!ksGSzIB%4a|2nbEyJflnXk9ZUPf+HAXetA`b z#jtKqc$_=;t3r+UAs*L4Pdr*JPT`36pI$0@N!XTEq{|_dzjO_qX`IO}jn%?ku0~0l z_1%jrnI$(hD%WW%<*J(Z%tF2`t-i~BPVAskHpIXqCqLJPX7we50;A?uOXENzP| zggf}Va>~@Y`YWHv+c#Yo!-yYQg5Gcz*0!W<4jgsEtgxiCXp@4L@HEz0Ksd@|A*PB*;b&P#Ar>~#2mq{+d_A5gr zDw4=j&MG&h_|5H7uM2UhwYkJD;;KnEQj2*#F7o!N)=;Z9#HEYR0!eCEcs!E;j+sD=8IBX(W{Fa7&|em9rNe!F0i@*xxI321#Qq; zC_DJZ7GyP_J5MPU{|@SA5MZ}+uUX(+;k72z;`sUEe-Wxx&4v#mUaM8ZSk%4D`Q@b= z)!M1bGSRFGXd^&T#_v!) zAnxey4LpMJCJSkh*6ZSQ!#j1-MXKbdH6)KWY}Hz|_g+@g+vfxc7H8^IVKq$eF%-4U zTPf{o!(i6kwOE=}ih_~(TkuoF?FjIqYm6RL#RlMUXY4N*@@hx!;XYvMTcPQzGPJi& z9NR)dwGRv1i{h3{@#IzUCw!b5fW#L@-=Jca3$I_5S1a0BMcq!^h^W^EbL!{}vGv8P z-t5QiRL_6ycd6ofR>iRw--x8ofP&Y{BpG%KSxGVlLi7ibE1SeV(@dON0PsQ^1`Zh{ zxKEEssRJkY;1fN*k_hv-yXv$_qCDl6^fR)Joy)XQyjsSPhB!pCu-c&T{s%;X=VF5w zjQU4NEgc6W`nWppqauAAC$Q<1zDs z5OZb^)bbg{YI1P7Dq{GHFATob{nS?+7yxH&G<>U$ynN~%v47X`RjNf@-;CGKJJ=$r zw@%$dvZfzke|@qxUucJ1Yw8n%eb31^G1dA=&L#HvS-N`ZdBCUF;1r@gEDx&3gxa01 z9mp!WZCD_i)U}_xZB3&YnsjPcyD?=>0Pg_cU0pjvKS6&82!I6Mv6`pXmc5pCOwOre zy(ibw0;g_?XzlIkJNi}j^cAxSl=+)A-Srstc7?c`a}0eWMNij2{*K)ehqPta>)})| zoOnFtb@Ez?q@C0^*3#PJqZ`>Ga@L#fpKz=#a=ry4yU~|Xc5X@R%}cl``GDIg;*N=A zTh3eBdTF`#JA{BDPdaqX;&J}3(v)!J__BkPa?@muHkHUooyg#P3ML&j<4W z<@+b<4YmdI9m58s#%nC~h0XE7&XIVb`n_W9@52gAXZQEFDgNmOcJM&2f54;Q7qj{X zLA<9taFSPVOszG>-kE%FPR89=5`b?=&NBhcfx19_d)DTG{2~k9Vxil=cyotHcY;j6 zhvCDiA%16g`=;RwJiBAco9e-cbON>Cm%=-x;)||&H+tC*;>B;<1Z}s+i{4sy{6blK zfbND^@#XECm8O}NrcLhHU<%fzfqp}oBDz^TvV$%{bWDljo-*ncr{64brPo61F%{V- z(Hj3$DAK%O;Y;zKel2t*o!7tH6I)ww_TlFTklB!wzmu<@g|p#IYrT^P%&MDb@k6Kq zIwzRsKMEfo7@|-Dm8tPzrDbw&9Y?O#q`|RAgXRXgpppg0JIHS5Gk8{5F4nx~-LYcoh8-O8Tu&B@4crQ$pVkKw*}?<%o%s z=4vF3f=wQhKJQIBUMu}3+q9SV=H`s`@DQg*in`G1B-ABYj`Dkl$(r_6nfA+?0_2Jc zUY@l+cll=-@rYn^NTECC(4EBE>4)ru^mB){pQM0tD{*uTuO-*%vB3Tn9@{tST&97t z8`Nr|NH`-!PG>h3d&$TxZ1GR~+oFp2TQ$j1RkLcP#-a3F9+FQN;)5pR3MYFo!;(B# zs_7#rX34-!yKdvR=77_@%UqR;q|A^;PNke<#_NtG%L?rB2dSkAG50pU45GaHfL3KV z-Q;-uU!q9)UHB>nX96D*_BWh=)E!R85}J1|pN8&0{=E;afcW*k9IYew&$9i5w$8(U zq%@Ukhz?ev{+W6I*?IpDYJ;%7t%ISn^Z#N#{)gJ|zkc2%O(stP3}hAq6a>;tKqM>Z zP(cc#G7&)`UY)lfB>ekhoQnl!o%}SSs23jqUq=;ra+mX$g&7IYo znoXnYS~taC=QGnrhQj{Wlb!EA^Y^(9bB~YMaD2dejSgN4g^cXxF6(JN=1t=jkz_Y@ zr)W*({Htqbz}@{c1B?o~3^zw0*Spl4cj{>5vUtrET+f%yRC<~snh=0a9 z6gAa4Wr|99H_Z_Rj*S3ty^CC<0*?*ws=dO4Ngp=+)3Gn5X3J2jb;up* zm>NN)dLhG^n?9r*(B|F(OEdgp6u@T%a)r&=Sx?Gzo#VSm(Tf7+Dxz%JJpahJJFK>r z+5bh?Hw9M~v};dn+cqZ?+qP}nww>(Qwmrd)ZF6FK;@RPx`Re>P-(PiV_3CxicW?E2 zy59$ga2iS3winy>63b*LmlsK;?}l~j)Nbk+&1CF4Xzrfs|Lv>ROJ zB7mL3V1{jUow#wHTTuwjyAUl^?j_*R%tNE@tseixYN54CtQ$0xbq7gXxl#YL3T`Y>Hg=si_ovVjz#!358uze}bP2t;9T{#QK;!#_zd<$2q@SZ@0Wr(&tiYHjHQx+tVmX{j`hR%dOoY%~vpX|5E+5;V zUpV1h2n7Ni4K;cd^L#2pl%juBM&_=sN(>&0x04kKLMHxA6EG=%j6eAd!qGolyAo8srWDfBg2k56^ z<|Tu&LN!N!GXyR0M z^|V-rR`X>H=)TxSfG#AK$dJ!o3Jsn@Dv&CLu7Hgdf+jXzi2y|1HwtO2xARc2Rf?q= zuxh?K+NnyCVdUTOL%j1MXZpK!+(rsUn(eXND;H6`fGy{p2-9C5}ke$yM7WIbOwW>1pQ@H$*&~i!%X|nlQ#EN zCFh}3xz_y5QgWZNwy(o{EK#@CbZD{#j_QiMOQPTm66X2CBN-i~tCa`a&3Z)itBdr6 zN6w>fbyT(LYVE9zs#`-2(%eBpwp6G<1Th>bP= z2e?HQzBs8eTQpS2p$H@V^=O^RN}}j|c+tby2#Ci;v0lrOSkg+92G`QV)=P|Rqg zWT)#K+>kOe6DD-n+lutuDDWEtd=}3(bqRE>O=L85K0x3+Sk?(^j-qbp z71rtiq2UmY#3`=_M`1ed!!ENY^lOc*Z7(Ec0F_xsC^$3h%j*J;goYRT&VRw_(uHSy zk?J$;U9rM7KX{c== zbck%5J3JRgxOS(6#!5LSiP=NE;GoY1m*iI}RF4^Mp?fmD{&1(&ysKA)A8g@V!!ASZ z@ko1Jg=dpGqhuJph0Q{An&UEe(XS{M>7Pmm96Nmt@Z}m3wmHOB0Uj8q4?P7L{n63{ z(nkqTqtp!^$pO@J=JmaZDkXX!2MeEUtn5CtPO)#otjw9ON^t>Q}ev{;@ed|EeTH)5R%?Qy8$2| zYDzE5e%uiGi>F%yDzk=6LwoYXXbt!uw>b$NB!1zmPP!9Gf0;jTGS>o#N+{)S2O`(y z6;V99<3e0cEGOH6w`#Z}$zsnpKpET~=WvsTk{ycpoKsd?99fHp48ZfyP8VucZR>!d zp*w-uwP)lY5jT{VDd(*y$E~IEZ+r}F1UHlB1r;q5Zk%1K%kTT>b4ilfN+d)@FMkr? z^t71mUt6cZyfggFos^i-D~>m=({~*M@h6(1$Ombf8NI(5X{I%EqB8Oak5l#a3r35z z&)`Ny{J zxOML#%lX9v1q8+j1rm|nvMBNanS1lSk) z44rzi8m;qR?}!yRA58k>za-OeDM~B8mm#sMUzte5Fza|6)qY z00M>2&+0VKZ9Xr1FDNnSn|7E{#3-sX7LdjOV|M?WS#?-c0HnD&t4EvE(+70~c7*?|;Asf_T``@Ncd}=P}^*>f-PAg(nBfI`cM9Xr< zFTc=>^?3D?B?Mv7xO5CQUGIeN|G}Fw=wh%n&T>%+J1Pq2W3KorGJCV1(Fb>-8iy{3t`=D6@j*7ewz9&2-syRzbs6Jnszub$sSk`V)oJe>!x z62)CXCu5Txz)ci)Kl**3yAwtJR8N?zV#RT zTyQ?Mu0w?e#X=`ER1>i;mIw_SY)@lxx<N-I;ifa3PjM3A67QQd zU}f?6ToamnJ%$5*XU1=wNfIBp000p(6qO^duOt+_q&pzE4ET6PdHh!mDDLP8rRmEnUC%+S`V_&g2eZx&>w5N`)?t1Jj}i@E;!F zH}1HWorwGch)Oee6L$j`KeGEoqJGx_4aYNRh{wz>g!W$NgZ}=q1?L({M9_inYOB?lQhoH>pm|RemNAq8)U4 zz6rQ31-A|A@8uM&zi;0#o0vFnHAfBr;9Ssh36k`5{} z<@OaRDz~s;uaO@8F|+c0mI>MVWNz(y$eW4T(h@LMEFqhNh_4MlHR)-iquNf>3a5PB z1t-U}Q_uJjo(}GMKmc*AY>xfbu%AZq@c-NkU4xF%KY_&>t>0b4mli}4a*W=@6orTa1X$1pd{-O759(GF% zZ(xek5czO~Lnav*k2T$qSI?QL7bbY(Ivk`?#4i4XO&0I&1%tR75e^&I}`1;~`F(TD-GTDTwxj<&jL zdaOM2R^2w?!KPqSyw{7%OSQUj*G1%<9Sv6c9eSHcnK$;*ax8dcKJBxIW%dzTfOnQ# zT*x}(kxD-!Y<~Gh-huaMC}*v3>ZN@W{6iUiBIcN`zLG|PLQZkg8HZ9~8}23OmPv^ya) z{dd;3+|c5Sb@TpN#QET5^}F+84XZi&3F*b=`RUs$dxhl-I592+#*|3idSNW+zss)9 z>o1aq=ugMoT%j#D`fC~tc4V-cOofF5XJ#Nm7#SqI7OB1_`>lFrxj`I@5{3%A;Y`R5 zW~+0+vY3~7U_bfv*M;8vq69 zWn^#uo|CmuF|2S+!^b6oVpoxBJDq5-MwFyA+?{>tf#%VU7jS}TD3J2Bx5_~?@9A4~ z%4#T~Jgd7S-GjsYQn2Yh__I_}+RhKdh|y-fe@?dJiBiyBD-XD9H8EXdvRP}AggJ+n z-odzY!NI{3WeSQBzFcET%rBMLS^N<)G_qvj4nx9+CU{3~oyK z{`3A{E7nNrV|!%PiI{EuqiSki+BfwpU58>K4=&$=!3rWsb~vo z3I-StO$*??)Xg-=&n!(7nR>O)2b0C@5uNW$TufB}Z6Js5& z=f)ZGOR*&jMj!)nR4an+#;9EU*y!;~*#@-)LBoVAVJaG%bKi1)P435ge#EbqL%Mht(!@rTQupM4`5z!Egu z9g+bikOAXNJ~Fn0B(Q_VX}=)IdbnZnG)V7eZD+d~QP=P_p`BbHQ= zA3!B8gu^k3mGcJ!Lh9+C1P4MSf~bDq?-h}M4f(x0b&`G!O3fqbWBxvB?&j5{@T-U; z8hS(aja-46c`Nv`Dz@6ix(OtaxI|F$Clw!k- z%KQu6e2E&A@sFy!0%Zesn!Ug`h<;UlGWVSY1(68tSMvnL!=*)kpe}!b zK!CrmX263ax)83{ziRvcAHA_gEn|#T0#MX7+z=-`L(zEcKG;&bLq)EzUcUbyJ zDd90gb>(Q)R!6Rlg@_`yuOnbZ8m&_N5DZq2wq%An{%VJVrp{$9tcT#gFR>6+ zWx_mE(+fqHY%3}SiOtA$Ks!`4L%s50?1N5-WPo@sZ*J2fj?gX2mDAqM9M4M2;OLVo ztAv~ufsniYWN&C8iV|M-VC>)#5hT&v&t@#DRMM*UyN7xoqH;Dh zy%#&&mj3g=IaqTyYQlc~mEm9DA?L-UVriZtggmL_kJ?a+ zIET7Kiul@UzoO2D7ItMdJ5jXnTK)=+$`>e_%7roPQ*%){L#8YUQ`;w2UJ z2gaSDkxa!%^hj&rIO*>;3hl5v8UHk$4_fK#;h`tJQoDfX6SJ!# zR8ioaUO&X$eC0=28+dIiPDdA9>?+TOGxSzTj?UsZn0We0*sMOtK6MQjLuU)|mD3^t zJM2J9vmROVFrFz-PpqPLWTdju#$4l!{=|O32DxuV$n883&H#58YAnI6d=y!GpbOE^ z%yVe0j9nM@JQ7}f*;F5J!8m2xkmASL=sNuDTnfgOJVUr`IjG?LgQA*l>K@69Q6vYAy(m=4w zKcd#OZ8L_srp#bYZ&gCpSl6KSVT4jM$rhS=(UyLm8zu6qo)fiXoSE zOUyghL-<141ANnp%z&n>yhK?Rm~rLAD4ONl$` zu7y*#{#96tyz7Aq8VHgm(fBn*j*3TSfp4O&sRI7FaL7r`Pm2h`DE3H={60MmZi{xg z0jr*d;r3IOJwve}xmTCmb*ME)+OE)g8Jxqs%o=NOiWGn=BkO`3qXEgnn}lvGO5VYk zNC_M8#fD{*Xxx<$^dS?(YGXPl3>e{jF8ch(obqwUl3vTbaIZAIs=%I#y^Ky*T_7wM z>*1fnEAcO2R>({?F1k)XwAR&~oWPPexx}>z`Gan+;9hE{@PxMJqHAk?dM6L@>(|Sv z$ouV>=fc{EqIit`lo_>;j5j-;V9YTi+Me_`t|@>4({<#IOc89t#?r(@%20v#A`Q*q zD+Se+5eAaah}>u7CibZ`!I=6AHO8*^!=kF~$MorVPx5b*e_q8F zbWt2KAEByZiSLxSVnoU0GHBz$rs`*VGm1uKw~IM;%F@Q%%slEdJuVlFp`y9rX^M5%U(+2zixzpSqyd=2lTW(@eJ& z#GoNEZE}syA5>$^tAVbSwYpzUzH|1GHCVU9#>42o!Elndm z)%6aA1Q74-5AdKB8^}3_rn^4LV85MMQ)pkr)A6ln%I#r5M3Jhn-v*oW5w5DTxE@GL zW359n@$0AzRIAk{vl*C}P)(I4n|D{m9;+q0(z5~hrFLHYPwwy$?7rLoHsL>shpaK_|bTH3s)S0U65#% zJVc#?#M5TY*_ho?McpP(Y-3&kP!>m#CD*Jf@mH@qZ-8fvtNC8an6ivzv@B!8+g6|M z=x&-C#{N-KN5TE}MT~HT$6v@V5Byd<4)DG?cFXD1?2dAwISDU08ecHkR1@vl7?LaN zw_O|Ch62tEP2a=uo8%aty|^^lKon=!$`4A8HsyG89-%yE+A%|#`ku)VgTL{C4LCf6@FW_RL? zUaSPvsG&|qTpe0rBVG2l7Oh~rCxn<3`7`!b`{*dz#CbhNw4f>b=7>NtB0y<6xRrej z75}iFmdP!W%NY{@;-MB~^kNm1(mBLG{q-w61lOsa|Y`G~v zOAg*%IyS_{!0zJ~e!~oNoehBpuLq_cTkqbUD3GeSqf>|O4Sl69PsY5;f8=H87+`3V zI^?jFD?DO}dV(hwE~jjLNsd8GS^^j!oe=s{zv|RiQ*E&o)hcFC)Dz>D4wb~wurkX( z>D>siulB`WxDbLelgoB~L$*3tA5(Ul4my3Pp;yXGfDlM{lf={q*@t%5^Cg<2{ocOf;ML*WuN@p20N}%(D`HF;vQcYv&n;h@Vgj4Z7}t`XX=*f;ZxH#a=30Fdy;?); zn+BoD+MLLa*?XzA?V7=3*-`6-_+zfH=g$J0$fDaWbve3gfs7O!T! zuFQ_L!a?&1GP9nssFf(^3JuN4KWPEVC8AEu>`Pk8b%D-V&bX+y9WvOtGZh=erOWcM zb)|?@9qhn`QP~amFaTh$qg)XCSUBaHYkA0tbkf{>@-f&*=3YN8f8bO?6juaq(VB#1 ztQ7mzPIkftUOgQuP0U>&*Qq)67|u93knBCWO{O|FOZ`O`7oMq3*;Lc9`J3K8=t2Ba zdcUCw%IjsK0V|oQMLRiPo={B_gOsa_du}ApyR0b5y9GW@gUzQ!J#s1xK~vl+r*OjZ zi{Pwcr&?b+_Vj$14e2IVXo}_rWsqt_O)-BZra7fPbK+O1Cldx=;kVga z%jvQloiWAcjcR&wboX79&W#JzR6rcS%UgkSm1J{RmrHMSj&noDyu7_AlbX+%T0?F+ z0kdILv(>H4jaZwrw_6_yWt?4$h{=$XJ#3xB70@0sMO0+xLg?`CcmOfpwCtQS3}@ zlP@2^Q!wP%vN0Q$QaHE^ueA0|g3R?$um)_|%FYmZ&WU->cPS(TBh>@`$o;sW zpi4r+wu_h6R?%=MqGtT*T{%i@+#`J>#gl`nEQ4@n1iAdz(Tar9iv_JR`J?k23D^g54iN2DK^->d1rkJ5QJAp;-y~K+q zHb-RBvYxKT+uxBG&D-Bit$oo*ruTPt!YuVGg=;qhc%SI1nHzUHQSd|l#qh_}rVDdw zfH2d;O48U8xh|oh1&PkJ(Y4tjN|1-gXe?k!Svbq}yvc56C$7~?*Ep>@WUCwAm2R_g z$@y=5V&g=xvcuPkumvq)^wzN|oWDsk3!aaIp-0R)iynW%T!HWiy^X69I?leVIYuA_ z%?IbLd0ZXqRFCB^~HcwdkK_Jj-UQ***4J+BC2x@;VO7o*|K zgrPt@;ga^~m#h8pYub$4p?RoMzl97Wg9c2LpT(}SAB&rA^=yFst@H`M>;fzibsG?g z-7c`zgDAzC-BjGv>oZ!3*@r2EP~Fz9B0=(6WkN(gbAu@hjj!V?N}}ysE<2r<&i3qN zf+Nvt8AXghB{VjqZP{#svp#q=-5U#gb;~>@S?t8?)5fNZOAdo9EseCWWQhT>8DG7k zP0Or*vnsc_v+F8fjRdsVt11&6y+RFw*7_vFdvO2KtN^|7n4TUG$;s}0Y-yQ552Hr? zR_Cy13U;BShPFyHbo7@FP~bP|uq21AQbJu9MO5NYVW!r{ z&sz~aHh_X|%@yaR<@JF;e`$-;<%1o=`x`H6Yr|Ngh#QkwEF-e+VQ`nG`#P;4qUl6?hWqra5We5G%=ijf5)xpTh+5PJE+E6U#$^3jFrIn(};qgJMN zuhy-+w`_VHGa0{i)^h!sLmRtBbMRbw$qTLS*&C*}{o^XPc=|`xuJyA=Q*ZPK4m0xg ztX*d3pqL8gJaCL=7?2c)e%(aRsl{ausJXg{VK-*1%RJnyK?c>QtfUNx;^k7B%E>7c zBU-G!u)faRODoxXXiva!QX9#Vp97htL;rwW;~JB>z-3+@bDIZqwwflD07+0{#iJgp z%o*cKt)PpCm`s|75xb!>nQ^5;Mk8ODIo{>NT9D4t09mD2O~jxSx`ga;C}y@lhiK)- z7bC1@x)m?BVuku@wnQlwGdcs7Nva*cVAIgCT{Itd#PRdv^9OjG5iOidi4a*Eqw>3^Whw0;d+!Hn&P-bqPKZlxVvz!)MZS@R??BPTw*DJ4& zdKAtiBaa?%MhVX~jIm|1=2L@#O~yeh`-9pic|AkTG0gwC=F$-`&wC?{LDp^8RWvX6l65oEKUnxwVzO2qe)U8H>;$2;Vr6I4X{O$KP6kaPq@od1tt)cbV#r{Pb z1{=>zTEuNZoi^F8R04*lSeB=krv$7wALtSIFn*}!A=LRM?E~%k32hU1{trf%I{_xfx%BR22bN7YZmd~ZH;h<5O;_`Gmb-lxY!VD zB+_0{smSkv=4OM5L^6_6w`%o#-=`GCk9$KRCS`&L9tIV_?%z!=5iQ(~G{Ka5R|its!peRaXgE1O1#`@YPz_bZc=Zv478g#%2Lhf-}MD z?(L>N1A_2p7{TPO-)JoX%sB^@;9mC7PhC{zUYM?`o{@JKePxoM`hkB|z_6bptcjk! zLIAmxN7HlB{&m$0a`eA(F)YkfDTdH^&OGkH4AFWG6=+xc+S({)`@Hx*5b}`;%HX*% zcDLkn8_-zJC@X`#O)1>Rh@B*wDmz_GVbQ&*Mf}17UaB{a8&D{NNB^#QP?81_(){oW zg1L-YfD#_Rhg0vc_{%$7+j}_{>p!rONvr6b!=bj zzBTqtq*=LzYe2mlUclsGymb2MQ=Kqr)%&EEkG>(6BHWX@c1necAdra-`?h#4g#&>oD-ZJs zzRuj4!=?juE3KePX(quo36PhiOvRrplVH2>;R68k2sV?RuS0-9?-)8%AMw5IPWS}g zKjar+!!+>j=x~d{0c*qLg$%#WUZ`FfjapbnGcV;H%ehR2y1oak)5E{G9{aCwAyOql@NX$H6J<@5Bb19n!NoQhiTD0s~^j)i>U#JpZ zm`*Y;-!O}rXX*f$>pnp2#l?=yr^o29u zMejQ+gr~|IZAXOF0t|~8pLdkvr&1Gy&1vEtgD3f?KW2CHkBdp-^FhX?RDo*h+^?&M zhz){qQxbl#q``;{luY9w{RjvbCgh=77uH=_fsRAe?HDl^66Eoq!)6d?;sA>?=2v*> z{kKGuNpC{CxFc;VM$_JVZ_Q|o4cxp5#St0C=u{mhMH9Q`aD%Yr4d}eNjzjql469}< zXHGw;vnD5J;&&{iW5P4HL+*kQ3m^jXv4HYXL}ymg7`z}H!z5h8K8+~{%Q%&6fS`SC zd-U5e!fJIGJ&gvH8c($}53FINRf;Q?@xv>3xGTQ)F;`%(-%XH7rf#D@%5SN z=0V@_fQMEnn3?9IhAvalfzF$^K+cxGWZ(wNPo$u`L! z6KyxKv{|Ix!*o%NKyX*W|IR;6)$VMw+mV;=O_kEO6R|$`a`+|*>=UkyA`?`|Q7{CC zTvHcr#2n8GAg-t0h--8}tp@*`O=J2g_wv&}2j_Qut!~i1iH=8R-BhcHLwb?4*)9fN zkP2}Pm3Y!P;Bxu5+CYRAYM)hT674S1d?;~vkl=w<^w}^gFc|b9+M>Lkg5@h%HzcuoBSXx2k5I(bd^cE$|R(bo*VH?O>itnQdrDjcml&7PPS9pgM&T+2 z-^MojVM}Sj;_rjdBwfI9NB@0fz;RE4(8hp}tk|CtxUJ{|uzw|R%i)acKH^xhCuU51 zGG^v{`$%cR+6G#e?w;M1Kcl$vw=21_ffwQIRQfd0=>@4+&-`IU?oImq-}L~WSS zp0APcbL+cBEKbm>3z%i^$iAnpg9OZn2P%u1P4a=_vbgp4lqNBZ*hOI zgQ++N79pEHoWQD%Yl#C%gX6xigIn!`3E+%DPGH)$5P72CwCID!Ka;+t<2G=z4o?(Q zcn$|O0AOm#P&CDe>mvEJ%RN@2S#WUugLO~@0wfKg^9LIzWF`hCSugT}4AS<*JyDVT z<<{ys7aMk+_bm#kMRq76a_9c8%K#DN1qU=x@C1JhpJ3oI6KGD_;!L&RKhq_!IbeO8 z2wYWKW1vt3zd}A+F8*T70uh!SAuJFZMKXivj}Pq@P>iC`K+y4HKa0WlLUjFc8baq(-UoCN2n9=ipc;-R?W@W5j|2f&9=?Bs97FF{W{KGd21;7aotX~>h0q*i;+C{w z_Yb9mIEY^Nl8gT`?Mm5Dd=dQF_cFf@QlbbPFrxj02r@?uGL-@Sm>xBn82FowG;Xx1 z{gI$Bw5P-IH8@xFWdDKE^X*S7!<~|+5V3KRN_Ud|))`*Qde-Ew74r+8+mFzZK#PlO zrPBjmyU}HBXp#}#N4Pqs!a@HJ_qD`E6C%(_9YueV$6=CccP7zjp;`6^(pq-VNH^?Y zH#|$ZgErS+9HSbkp*QPL2KGG6z3wS*Y!^&7Q*_OQQSxd1l9YKXgvswFzeRxM=!ir<1 zI|4!Z&bXuQ{=W379__9#NWH550ql#$rlKzv*?zOQXCoa8 zM%>E3Xy3PJ&mfPUgb2+xR)Pk+qWQSXu8j8m(l8bbgN*Pd@Yg5reT;YouThAHP$q2H zo|4UK@ZP$VqexONtk2KHj8<(gS^fpmi|bol{tYix&u6ez{pA)wn15wvp(-RDSwSRd zD9N-ZB;8`;zRPk zcDJ6_9EHl{lVn;?L`L&x?-CCODF$+#Z#=WX)84Exlfy&)gX_` zc58XS3^VEWx+sk&+LJNPFsvusjCrOgR1e~uN#=0ZHT*xG0kNSU(2!mS6k!9dK*Sz8h1HQ8b%GcbLBr z8=IJ1!~>aRkJn4Y14Hm)CzM9fUOQm{I!gFwhUdpWP7W@Xy;xHdl~`I2^WU|5q*oe7x7s0ZeEf<_ck(i= z+t3IcD6K0ECT!zEvDLAi2h9-MCOy~Xye?AYo=t#agH~L6Qrh2mGutc zoc1sdH;T9u#KA`!%v-wx%2ULltsBEl00Ho%7O8`P*W^@z5ate?UV9Qxb0t%h7t9wE zr6blCL}aV^!~5&ktju@}3caNNyk^>Z?avO@_BGv~=OGT--LdRQ;$c1-Wf$C_2#YG| zWqD9qdvP9E`5ot1)Jk2<@X>~)X}H6FFhwpyqBdtXOEDy8s`lD0wT&f4ilod8uY@$? z?_#SVLh@#LB}*v|6{SYB>OE3A-&E;OY(xvEVZs;W8H?Yl^M6dfzkkbUPQrYBs}>%N ztvarYmYqZQY$M;>riH@}8|7_fj>T0g9q}F|lf3&)Be^bCg-qZ>a51M2{engIiA46v zME2<<`o<^v<|q0FqdgHAtA;U1+wyM&t{st@XMb>h{>6_C3YDR;qe)x{`++;fGjjlb z>WYNzdelT~$su-s{MU{4;h*wfjMf)!R5RQZx_Bc;*hbGEsE#)Eq31ApQ|@BWiA z_5mHnBAaiygPv?6vIKZZ1aY&0%ljKrK9rp^!xbMygrJ)2HX^Nw9ZP9=@m#(ZvaD$LW^~#lU97;$QFH*xB6!FpGl7k>-ZqY=Edhe_9ZT zl{*I|N?$Pa#e*{bq|{nSYM5Lw^2METMR}(h2&;L2?~Elx+;I=LFhMg!Y>1eoyz|4K z{v#}NpdZ8zN>qw6dPU?Oup&RAvcC7p8ay-O3qArnznwfgi*baZAoDDfS z|LTG{#vvtPcc6ih)&EqGwY>S^srRlE-?RM`2$RJWrcH%(y#<~*zl|^{m`Rh#h}vOk z*)dQ0C^6*nzU?VzRLHk=2w;-wqwFak$i#GzNoC5IZ_$GW)mh6iY^Gexb?8ODrj#<( zTgb(-j5^|7$N`uHcg|duYob=bQ!#@x4f?}&xG|_4%?LImeN=jJ1XV(!1K3a(2RH=~ zwQxFHPdI+Ijsz%o$F0sgntM%H_~NX{$i%itq_ik}Ym|ZHY;o~C7dK3?=Uy->xmKn9 z-K^qy;yWgnW+0d;y2+&CY0*iPmf8{^!#NdhPBnp;rsY_eKOIH7X52^6 zOEM*_C0*gy%AiS2fU^^%g=v|0ni}R575XSfk_QeNVlMP z3Z~?Qr)7p!S5PJ0r%k_RDn~6bnU$&_Jd=~gq=nohhTJ4HqQRzRhC>0nt6~y;on2=? zhk9CX+1zC@L3${jGR0{tTF5Dd08qwh+SrRG(^VkhN>MgoMonV8O7WJ$#%M*6(i-E# z%gqKv(UjmMU(LktN2|7_u#|}{qyI>u014n-9MCDZ@9~AprQ_1bahzgCRiBcel-Sww z8$irn6n zjAVq`T2S(h$WBs!DUXmpjKJCEurL*9+r(-=Qs&sWO3-~5QBadEYon~Pi9%aZmq_qI z6H&0CucBjuwPmxUOx=ouw{?|Qz8HY}rCLS9Z!CLLoz|C>uTomdE7Ta_ax&MMw!zIP zT`tzFl9E|fIgv{}nVSPRP398#mFbwee)Kp3SigE4OI@#>=n+m?W~fdkrfAe!BEV^8c`)da{b~yk6HA_^-MzsuR&FFl913id(ZzA{O z>0$ySk+ECZ^Kqq+5OwBbt0C(?cbDIyH)06qu zmk+3n$-jf$k2pF;UrLXOBNOB0d~Ezn5pKbSEz5 zzP?|3eu4F*28|FGJ&Am=ydeI~>YW!dAyN5N3Hb--i|RcgXq4wK*ZS)p{)oQ=y&qDy zM?&|GA65nPK_{OeCx6<%`AKI%cNZT*|MJ_=xzH$v6zDMWwQqVvMU_h z){7UcX&l?_NI2Eg{Nshal(s29Elb9HZE1g3&Q-i%{4QOK8P={Q9?~I+X{!}Sw#9qt z7It2@LnUdgH!AH=iCcSvebhEC0eDHnZR{mYT;D~B``y{2lBCR-=F|FA( zOgj%4b?+_ADn==53tj@GVaM>iVSd*tq&~f{NMlB&xitB1BxICV)>z&lH|qUqiMGHM z3-yNW($Z(ZxJH7B^)_508&t4_BOx7Rpnm0~^66Ki`By&txltnjD^NcKymyl7A5_&wlI^U>NRcT;2A5xLYoymOe4g)>)eB>$A%HkYa+$8A)=va53)G4_2X zxpR+S!k%j$4e2!9G^$JSnw={aW~SaWvrFxovk(;}hb1~{24{5mbULk1^1?4IkeryS zA5AH1FDBp=>^?j$hQ=Vndummd|HhVr*sC4qPnYWmLIeLj%DV76vEO99=f z^E8IbAZ}Ezf$GpftKNIO{eLKXry$*;Y+E;N+qu%Vz0$UA+qP}nwr%H1Yo%@5d9$i^ zMV#6<&b?6)|HGIs^XdD0Yom`jT9@cL?-1%b?$Gi&=n(msY?kpN#MNm*6A@cs+PhJh z_Q{dvIDBJFSDdC%$wH)QgY6AnPBLt11{n>w^4Lx?soj338!y$qLZ1YsA0Na_DCIqqvw! zorrUfo*mh~TbKPwzD;F-xH0aNaAQY0rN@^j(~>6hcqWZ@k7csE7vl4g zk+_P0^Lt57?z(ZxcmWSHp2#;v0rq{fXeDyOT#gb$UuxQb$* z!o(Ub13c*?Okp!X%(9H+I@o&Qij_(2(l>emA6~o)?QCIH(XxbTY2NwjdDfj?%yVAF zq3#*EOg$Jwu{PRt^gX+(bO~ZH=vkBols({r zAHO~Ch?)@j_*HM2V32x$6D+}__l|6i;$g$$<5jxhE6WH=8P;kWW2bJL(Z4pI>h|ev z`NsN(=$R#mvNz3vI4v<_6rIY6Jr1($*I^hnhw(cw!Q?p7r)2{Ks)N&U9yuJ2cxtuV z!>L~Nf2qK*pzbftL$bi|KyYG$y|c z7yhgbCi=+qFt99_j!IEMR}g}_;^I1oSQ412^5@2 z6r6|@oX8X&ekmCBV^ot#Ej8%(qyVF8&{oaf?I@jjmMl}nP*)ZhsiTriQodWT{qsTm zQ?g6bOKhwAI`4HZEpc&JklqB4J|Gce3G6gS1yvuUi;+!r#i;2SW|K8PPt zpFW44J%>K+H-;23%m^abaOm*PC>n#9ZHT|u9L=>&h>@s@#I(jO|H+US#kzDNud+_T zl548!^BOg$v56p+HC)rmkpSBz$k@UWKi{PghS+29+D98#A%Q$hh!6utfeaAm<}ck- zU%b%CI0)K1**o@DvEVx{P>ag-VV*{8_sVcD40VRn^t$yVdj}9$o^_&1bNDEa%G_;i<2T6|0@kx#1gESg)_Z?78Hpl z<09`A!SoiOiRNUv>g);#=Kx|#++jq4rCZ*Kx`glE@^^RLxLggCTf-BKL!pNHuG|hb zE6_oAU)tP^)=+*g0DQ43PHCNiTmHpbtwXTMbM{wNegk}<`7;ttD+e8d=s&l2K#yZ} z%F}SXMg{wL$a|wUg`}@m&fQ)`GndaLr=2fte}!&tk;_MK*IjPK8<GR%#T z%#Y*$)`ytc10GnSBYD;a=dY32M=`KQT&wXa?`A@s)e<8V@#od!@JjP)B={!HngAOT z?PkbqH1NLt-XdF+9(AGPVq57s4clMC;beMw0HPUP==Ps!pi7l{E!ua&T9(QPU9U&b zCiQOg&hYNs75Zj=7a2^kSC@zk{#hOgq=-}~oReayi~M57^xtv3c)_n0-IO+Spa^^g z=*C-nZGzbhuf_PwySE|YGhl(s|N!~JBT5(CHQwHnpSjcZjeHz4j!Sf0DB)3DLxcOwynR-)B(us)O=atYkwn>3` z|7+2bcp37!u_O3mClUFIglCdl@z5o96A2e%T%=k9oa#bUWXZ;_d1=Bfu@3NalAzrQ z>tUX$=cfWcYSB8#ehHUWWKBwSEyHNv^1IjtJ*!|7_Be6hDY^yLX5q?zy?k5c(x**y z9j>z}yH0c+)U){~mf-1ESJ|ciPwvu=;ly_l4_L2RERlt5!EBC*q$k)yvuS%Vbydgg!R6HI(xNPnGjYege#?_6|cg&)q3rGj*$e z;@Hab_HQ-Q-BY=wvMT!Ez1)6Ddcy4~`V6YI=-ugDt9^-o!uF~8jNvo)-SN3(OR2)u zD|Z@sck1Un$2!kHr`Ba#1=utibVkRn>{Lfwl3r9?h2cs5v$UX=o--}8%u}WE+>q=+ z<$|?TJ-^r|9Ja>?W9~&26ydOE=3OPWB+zazPdE= zx>BFKFw;l7D2o+I3g`TW$(|#v64T@FnB_y70Gc;tfSz;tz;vr{q$1ND&c^kr)t3DB zSp$S9D;xm#Ldjc$3Dh!7VE+7# zBy)Rp=Yak2dfd@O*6i}Kt}2ti-BXh<-7Bsy;2)ke6i$p#Wwq|+)L2|N*s8&6fH^zNvwA#_4>Z$gK1 z8&}mv_|V$kIQ**H{*ak+8(%Qj_7q|LohMG#Qx{qbJ}`fUpURt}X*pF8-5b0NVxvqK z4Eup<$L3R_O|%#5>13sk=#A4&M;D&%Y-O}>s(*jsc8d}#gzxlmy%&n<4> z>qF!=@1Q{zm$q~EbzgkDWxI;~iK*^eT%Nix_wa!zUkBt)9lLM*!LerHTH>ue#)ox& z23%$n_kjrZT|`*gkL=`F{mnhxXN!11wkp&y44Z-@+bt=!K7-yzN(@fL8a}wl2Qobd%nyQ3@v^zxkm5I{IssoenT6a?rbpjCi%(&8 zSzk!nMctBWZ&cb9-N4ERHofdGQmxuvShn-)KAJaAx!PX%%tv_hPQHT6FN~J++&;KZ zrqya+IQUcD0mC=dI@NEmoaNr&`o(4NrLNBmvqPck>jZ_up;-(dL1?Oo(g_!q5j zw(T$tc(vp%;tQENWc5+vnps|N6EtWg@X2_xsBktjl;Q(4zsHxvl`xvPOgk~ zyg!#QM|hD(IWb2%QAawlM_Z9cyx~VZq_zvw46md9*^WDi$MB@dCqq@=N#Mcrl*fx4#m;fQ5Iz*U^QA#IPMf|FRz}_%)IEF@j^&*xS=1sxkA@C&_ zxO)aPBy)er?GK{*lghH3W5+PNF2??#*Q$W;Cbpe`gkz~G3pJrK|>M2Dfj)32KY55e+=4E&;B!$5f!W0_8NStY0H zAbFkJ@H4Y9V`k%Q(Z7?W=fcq0wNmqywo$t#xkv4=7wb)q*BEMWlez##h#Z-{4vO~y}GNPU&<^AJq-;1ZUJNunETR-=kT z;A<-**3ChHT<3w@ZYDAYMQB8V*bo7MNhm-|Ah3);Feo&}NqBHaM0#)?N?a5*a9a|@ zeQg)S9SPB%0pSjZc*jk6fJJx^EHoDRjV^Epen9PozFl1;VR+oA{J|gRTkQbvn`U+g zQXD&0yF>1c;&lVV?+&x`4fvngCU}%~+!SB{0P8US_Zjj3x*;vCZ=-Me?-}vMDzA=6 zt|;GLj&&d_R3pIE%S6gz1#T@+%V8kMWe2bV|3;1U*@J?&#U-P~N3(wkN{JLy4-h#x%Gwe#a^_(Ip4vOZ8Ob?q1pw0BuG=!z_)F5+LA)~A%Z%P8En}E9reUW zL6PRy(_g^5i1%L!kzd5R87h#o+iTD0B?}-k=QGk_M35A8@7j?g-MdO_v1FtW@+dG* zNISg-DjYgP2O4)~C`aSMJi?h~<@c8sqhO!ecZQL)Mc=@bsgtDfaps*cxc@4&b89Nf z3ZLwlIAv_?$53*Fsk8}j=7_|xFjf*jf>n@YCpEOrz?d*sU)eGvKUs2qEi!FLYFx`C zg(4_8xWgP=2x75=vZHU3=I>&$7!%-^j(1(h3;heRqaaYC))ee0y3ws~69@Yj7 zJ2}th;7!RePTvRhCJP+Ys+3!*-!kS89AY;2vPdJb)lJ{zeNUu*w;^Y|IuurNZAyi(M_&YCDJ7)hLI%jsMBLL*q!*LlN0 zeES$({6Q1ZY7C1Cu6>mUMbRS^by>JO19sv)ybVd}Lp7c00~;}SGd(f!gf)I_q&QHV zlC7)_E<&(4BLs>tOYRIPxN-IBxi*T3cZhlBv?fHw;s?Bm3F7PqaMm&mH2R^syJdCs zxmXy%(n5<|RVLj*dH4n#%jkZ#YK>}>XhGko5;Ym#8aoIxFbq-<<3)*_8}`^pb}&l$ z(!!A1M2!SXd9V3?AmnsIseIo zT6KVHq#Ic91$5PnT;*7P!u9Gk5MLL5c|YBd?)By)9Fh~de!gjD!zbU_;ix)rzs>W%J`LsI-2MZG%wVbnm8bPot8W-d!1nFe00ivdo~{0 zd&|2v{!IE24j;B6rXuVm=78pL59KAq4c+ZYd&^sb)h*HNh?a{`3zwS_e2eK0T+zq* zw)YOC>mLgO-?L@@4ga5NQ*z2eK@0={p!yTQM*DvYU~@3Cb;#vD6A z9h{pufu6(S36autF8~NhfCPSB?JzFzGe9)oV66|~f;sib(r_^PwG}PuozHjELx({b zoG!CbRERnLMz+J}hK{NzQat zI~oKT?Fj>l@+73zJ6{|m_w4@pN&dl8K}uuVH#ov_J{A{6YW6pIc%e!M7NCPgl5;^%;hiCiDh`D z9@22vQ%xy2goTqmJoQ_CiBV2gq;JxznY<2h`Cqo)g0Eb7Q-}<*TJstN2B;O+GeCdX*&aBDINsrlxLfPVG zy_}Jq4Ew2JO~;r1u~1NXFw!8aYWy4{AwY6MeJ`1NRp+}C!zee(RlbD-Y6N>6Q=Ec9Vir%7Re1uCdkD?=zYOt6TF26PdUE%;{){k1z88qDMGP;MJXqQ-YQ zwW$fyo1Y=uoB0(J9;?D&t%y=)9EaM&xEqajsrvd-_N*z5Q#1qYDJ8Pekq#&!OW`lf zF)4Uya$PCv{E?|f-N`i2%?HU)hS_3E-bC{`G1OHIRnn?$(Ldb+N)23MIzxT48+`1- z#ocI$9jGQ)gf2+8{`(Gg%w-d6fFn;>jbr#VU=tQ^Po?%pu_yPP+fTA7EYuAowvBV# zq~3qDSOPD*r}sYr!v*Q&RQ>_1ED1^{{V*I(?Y|e3CDg8okyOBI(h3rh|iC# zNKcWI5JuQPWaQb}1U*{)mrLS>?F*nMEsWIX2K=QksuA3PnfW21JAE_V-Q?)+-`w7w zZ-6?#Q8Wh_mSRo3@3Fv^8=zvrrCps*rR8;v%SaDm;Vcz&8WfByZJDRAQ5xIscB+6y zfq4Cx(R>v~Vn22gQ(NIXv1Y8MIWBI5rN@_G_B&$%k$lVub4}7E(WH%Qns+3@_QApm zv~m6<#;7-6M!bll9I5W+17{P$(Y=N!+T9O&U{PMi&wQuw<8D_Tf7LxC4H`}6&J8h?VXSEj03lS+~omjUY3W1_uUPzi4 zU_S0S>G^?EN|!>j_S3?Fvm(;jJeoK(KI_Igf3G309gD-YGm&99nab|8ZOgr8{d6dO zIiP>#+@i6GGx;CH=tmhH7q&Trp(dF67crT52VDC2-=ntPj|T5MR!Nv_7c{g$9`k_R z5)3-Y?oZQ4v-*!y#|C<~&QSHB&lg5O+XW_c}Dn1(-#S?K)4`*0y?xl@|SeIL#N3F z%Lh64dFi}*Sp#%7a$-k;SzY-QPE*A9Fi`YVvirD&fj(WM!lu~^uxzXf8D_`$Z@J1uvCAn?j z;MX<+@jMm*ufVBNm+`V<=L@wY9s%Tj&PB<0qlacF740QWZ;{wVA!4;u7r%3K3nH7C zayEV{Z8ewC&%|6WsFLiZ&K;UfMg02k0sNo5&E}GB0e8U7_dH*eZfe>73{A}#UzS;KIpd808%5yu` zYG^m|t}vJb46Ewr?@3<7var4<|AQX9CUayQM_IMd2(>On)gO-sC`gMnF}qgyaOLp& z~pN*CYp8w<6}>>>Ft$LcObUB}R{FyE^7~trn3~g8h>oa=(15f#19> zHR2m(n)rK1lqCr#;TOJ9!|^1{hC|%pn^+Fc+Z{OakoBaQ$v?b%&F8fYo#?X zJeY)oCY##yKfuk=?9pCfw~f{@mU8?6cgPV-CHrFZfQ&Eh=g!o?Oku9i8_}O- z9y%1FG_QQ~@q_`5yQY|)=lSTI&di2N_x1*-ziOTeP#gI&bOxFd6SMz|IZuft z@dTjPBQ~X;{b}k^Q_2I$0r||G5}bPFL6L#XQDANMHp;eTx4Q?=8 zs$w?}AE5uqoF_bO8RidjLjN6etpBUV6}ixcqyco>Swfc-*_2O8>Ow(`gO(@%1G?Lm z`qptYQ}n+w?@>FUapYp$H-KI!1{Yui!qrHU=jqw$JdS@Gd%r(EKz9&XrIIk#I8WU_ zh~VD`pq-IU4X<8J=dZ~;etoDxC39$!Qo=kTlKD<4&#YhLh0`<<&k9D~xan&8 zYUwq$(AHIq%uQ>O-qmo%jCyV>c)eAv1?%y9MqDp5(}C3aQOD}ET_?{l%Qb{9Zw#`E z@fm8SYFYFU9!UEKBS^P}QkGyO>(h|HtJPVw4;K?)Fb~c%L9NM@UADCZ6x$KinQ}XvbjpTX=X zJPKtstp+(gJ6F~PqUt}~9?`$tUM2l9Bk|9!qOq0Gy+{*wZD{?+?KwXx;k+>t6o&oF z?ScP~+bbU|w4hG-Bsa!*{5Il7_@kZfVL2W-B@{Dk{IjV@`#;58#E;u!TrQ+Gj18WX}^Du=!PGWDz_edA3lp>7rg<_u*UU|9nts^fvX+Obvk@uNPMEpnGIcDwRN08T#Y$v2`1t;SWmkRJ6H_6JO0p=6O8Dk)m(ZG zkOHYDG~NoN#i&xn@7boK$<}rb8C)g_|E_JHK}d8)EV7kt(U2H|-Z`oF(pP_$|r8#R4Y)(j; zsZg$%e!*uVo-(UwtaUO<&4^{AaA?YTGDbK$OV$m03f($FFQqjKyxM?-cma_7psM!dEf7%mQNz_=EC}v(ZB1uxuxQ5t$Jh!}Gb5RpBQBk4h#p<` zY-80FxWKO*e!BLiW8qO4AUrcSnat34HJ#!mmMQ{v{piD59ML!3F23KkJad#j-3Z%XC0ow$YHNjSml;)7FgJOkkft^7( zc^X%{y!u3L2o8t0ans~@`k1of67kjOGj&Ljp<-|UyGR3;ZH1Hk;P3O_6={xt7in$V z1$q>oE7djHS-GB(Q8nqvd^)faS`o2!g_Uf25_(X(B6$wSCc%fWyIk0DQsw ziS{@zgOmu?#KLPY_Z_c!IKIB#&)EQC>rH>`rRrSYF3}Zi@P7H2s_BNg?C2A{LTLf6 z7$WIYk3UYJ^OQN?&Tb#a1wJ$#gPfk7+li>en-Bsih)a$nUKxKV=^XeKf} za2`Byo?M!vCODWsB#}+e&2SbKr2jCWd0szF#$RHz*s{>>{Sw5+S!P;oKD!X z_}GSrqxgDiYwErV3(Yx}KeL@ci7s^V4@pPrSX6&59kpz(vIZ@D_#X|Sx@5K;Jp7#c z;WzTceypdB0gHBT@H$h4O$G`%D_{Rx6xTftUwND^g{XBzru|7-NOV$b*t=U?icx7P zTfML$9Q<4#oUpRSxD~5IXDOLF zf8!t7n_h4AH9!YJ5>xB5P0>;V6Hx23hVxRRIgcR zST-vss+3hPS(vjlmxQP%C?nSwh$k+KSbHxnn^r|Hx0F}2NUwdnUSC{Tvcf>|9eL(l zXWjE1a~*r7mg>5HC<3sG>kI<*OP^ktEl#D~GEia3nj)Vjnlx=%u8%gH?yGptwbjDwp(me8#H#Su4gCh_2LSwi1NU2+hAoevXqU4;LN#8*TH8EM z0G;}*L2>!(<5r()-4c$Brr43whV=bURrScQxUbEW3rM_!L`r|!TgdTJ0z`>o_H;~9 zGRbUc$xd2>aIbZ?MP{UTdb)a3_B8+GI2q(&T!=`2#kez5Vt5CR>t7Q_p0zqATQX!7 z6;a@2$~@R5OUBtKXQ8!vhj;2x2GMd4O(U%JCkCca+=e72tVp3byI?Psxnq8yLamPfw1K9X{DyExo{Em=nW@+OT^VOn4)b*qZ zhW?reSWdp#Pl@n#m@Y7l0O|v6kWo#bMn&?k*BxvIfjiZ5>Tm zk6~8Z8T#kPv_hl>l_BvKu#`6Xd|V|MqF#0PrxH7mFn0Om*T~?5@Ceq4xF{9Ug?@KC|~Xh>40W zXt5G}kka*+rH4}txMIA}e6Y$I_0T6yQ;&Cq#%kEp$#zGItENAfCCUhMd3HQskD2^o zItv3wy$(e&=5XQM3g1?a|KPbd+pKlTV!H7>i>i>PI;JW6yUlh3?uMU#d@=3BX`UXn z=+j^y@6+oKzZ095$T!4l zwQNpB+g2Mz%C|iwr#{6Sz_)Ni58a~bYyga}TxVfV=X3Ic@g*=w#QX^(dC800%E-Z$ z&3I$4Ttzbx2d&S#KkCs4Gf1E%HW8dg6y9>D%hjv8_Bg1W3saHp=uT zeU$SzO`GoEG04g^Z?Tf1_6Q-#$pRQ}WUqtmd|Zata-Z(Lts4PGU$v4z@_?}vb8;N* zzAY?wsT0KE{FVWPZh?pt7NwpWA*GD3>5gO>ruRxM3<{5*M&D_skeH6U&R>3OQQ=ECTCgNY{*?c5a^EU z`I}s!cBh)`ys)`VNUoJhMvc)(wMw6_^*-5KJ`{1(WGy*$&#j0hnq?ivn_joSg(t2| zF6T-CaunQWMW)5{)f=#Z(|dNOf!K-`?EQR+xxaN5zv) z>aSZ39;3tG-rRUIi{m$(ZAnLU8fNN|iaDffa^+Lq%+*ts8#EFtJYylnlWGL3L@0x-^B6~f4-6g~MKW@< zF6O3%Y=(5Ld+ZcdDUw8277G_-Sn09WPC!Uf ze#0u@4*tzCh3(ME_~O#KlWB8g@T3=WHx4J*0=Yf!(eOYLY;q}A`{Bfk-OA|#X_NJn zzpAbdcGjTE$=vQ}qtEDA=?}=A&wW9A$nS+$Q$6OXbnraxLvn7T>^T)+A)}N*g0C!A z`lNAc#A#FEXWuu0*NPj;QyMDUJ03c6<% zp$LPiw98~xD#KXHWRi?%WhUlsN1xrS9x<<#=&x9JYhhgS=&5CRUB6VCd1$OK3^ttG zvz6cAa6f;jW^X@43I^lQwJQwDw%Zlw!El5S`1$XS-q3y=!W-n{nsnz3xAvHGSk zn9RD*z{+^smCD9$WkazJ>hTPj)>FBLy31Tm@!*m0P#$TRY?glYgIpzQzeMd9jv2)- zMg+LU8ah2-O<%ywMY~B54e-ptFZ&IR-`J+4b(`4N-1)OmsXKu_(xuJAAT zw2-)i0$*1J0G;(9o^?pB3VCos&$nKu)kLA#O5$T-VtkztPYE$7X>0yd449_bALf02bk7e_j1i z1C44!SlxPAB_i&$M?Pi_c@U>rFChoBvQ{f4utaWj$)sfaB< z^b!ECk9;e5-;Ip|FAGez2ju_!&8R`nTG><8NVIT*Zs8?+Dt&23b;wo6=i`?6&_xO8I-8i^mm*&}2-UU} z-es@m3+CrrOM?1CljyON=%rDPxbS>!kDno?_$qAxza>Q9U0r>7al*_Oyp!KLdpP~k zBOUn&!nkG0^nxCGQ5--&tbXC#waefr$b3L)C&}Mba$N6BuEZ?(CD@psM32bdHhO^s3UZxFrs4cuhbZiP=rQjHOG6Zc;_vP}9P zzFmp|5^n z@FnNoP`o4QIMhxgmMKp2xGS$x>7YJEs0MfMDaWUh4CQQRa|yWvR}uPtg;ujeuAS6Upv9l311`UI*owd*rHv*OoHf)Bz$lXuBOpdjpIq(^iwPCKre1| z-)y_^bVFN#kp3H_VV;vxoSNE3n`*<6*U(fU6N&RikseT5;=cK2f2!U)eeEgr_K{XS zg9cKJ8VQlg*}hdsk*!7ajPh6>?|H~e(u|`*HiqarZnCPmD)tJdPYnnb0hrZ(oQ4c?WemDMti#@_J@Lhm z-o*}t9iSodhH)GihUOGG6H%Y_T8a4v$!21S^MaG^NkWTD1_V|@o9BYpBggATEDz76 zxQx&5_2X%XdPsrZDXs4Nt>ev{=N?ttkK@A?fQ?`_6cCUnwI?-!Ny~J5p7{EUDwc8* z&X4DxA&a^7)#5~z>rfRSE@mdnEm72{(yDCQlpfchB>p>nw~9cpr;%9t4jCLNC$83m zIFgV-YcLCTvGQbF%;a)Q`o@nC0cFbhzi>pd`<9_XEPvIB3$qA#mBK1sQ%FUfJo&LE zEEJPa6&`}ItjG0A4p6#o*n#YwMhA;*52)y{6-(_Had#sWmv@FYw!~}TN-L_5Iv|-c za}^#RTp@QP)<<_){w;^t^ofnI4ucXJaax&NY@)K$^s>KiV3z6JaKg4xz0tAJ78D-F zT_upCLNwMQgCX^1BH%%Xr6Sn;HT`Z^8jwA;8lk3iF<=82{61rL)z(J??U@>a-mk+< z5r*t>$cFl7l}v6QMFdCo*DS_$g&(3wq+dte%8N~?U%0VfHxc?{ROJqBNT-9RXa86| zGa}9q0q8S=xw#)D+$8xx&7q~FZ){l`ym$y}`5~0YHF-L&Y%Oz21;zznlQrZWPc#gI@OKx zBzCydH3e$vZJb|TxDhCFCCMPF0e;e{Rbnh2YIlODGakGZl2nPZk9%(f?*kK|_nMv7 z==pN!AUl;@ZoTs#5*KRART(MDTt#~wGy`P)m{@j|nw_%*l?FT=t-<+gXdq9vgU0I} zaAmKtd%e8`W@1kPMTP*FM7m4%7~0P@<@{KyO>wvFP8LP%d!#BuDZp_APd07TeR?++ zu@NZdYHd-6y2&YYEeU7q0Pfx)ZjXet{qUHH1{pDvG%ARCQb=@&{9iw_CMlLYp>6)E zfS_58D~0ru^mH8>Us0ndNf}7wc}%cs;h9KywRKlY`gBIcQocaMu0k=CxuM`2o@gcN zE^RC+Wzo4XxTUujR+#!wkwOLD# zGjSbux(N@LB9=g>XC0m}=27(nXDK6chtrY2d?Y|NjkHr$z6kqwsv4DA5`jOZ-YSFY zs*A-R>m56Z%yfnrSGY-VwouF?fL=stT=Sk#Q3;9a6~ma+CZdn9Ce|eoKpCbtnqe;jOOc(EJHi{#Wkra%YS&iz@aU4$qu?9j>I#WkALtGx!0K z(wHgFQPy{FVm&|aZOzK{W8AjNI^_nd<{|6W%n7C}s|RUqi`KX&?RCG`^396;1n742 zpT;m|wlcc>FHT>uy7Uk4+6G6}|!V}Vnha*CpOLGbX z&jt%!#QF-tC*sOXT_NwmuL{*UPL!-s|9tXc*O}cd^&*|Vdcqjd%2)D&MqfCxV|zO@ z?PB$!#C)@|u&W{@L&?k2gN~vrDD6fFalj~IC#l^@M-ath?lycaniv7 zv%L6Z71O&6kZ(gU6^V~?YlOT^fr8_2m^fm~)o;I4o!KZO1YvWt2ajvUlYGqaWZ|2q z_R_JXUZp>Bda#FG?73?8NJ+TV!?X*;FG{pxaaqPI(P=OAH|gkv$S|5@q=1DVxmZEh4Fi$ug7}b2&1p}Jc+Fe%|@SJn=`(8 zgYo6i3{bxN;M)~WzH4uYKGK4`vv0pan5K?0i(X`3NdkP4#&tJ`kY6}_`n|dY-}qvV z^XFSRYkb6U`IEjB@Gp-wSw-^BULD?pxWn6vtbq<&URi3AU7irjCAN5u?7ho&*&5wW zN1#AP1S(``LVYbE^+|gAyfDvou5kbZ zU~9EB0q;(b;`A_y)xg|g*(83!D`07@}<#T-0i#pf2j%J7Q2{fFH+&1 zG3ZtjR!HgOWyx*7<&xhcf1Ae20QvUoO0v?)m3nAr%6hO~-!?CY8@2yYpDFppL9({} z^}o8*&Y_opl|P;t;`6(Ku&O_q2~3)wGVsK=Ttuq}S6B2@);LNr#G@@mQiDthR^E9U+Uz@Rf0_DYopMwD`4N z_aXY1EUHIOny@%B&z-M^aIBFcn6XI>{*}#ibL{o2U6?r0cdMrk01FaSBd9Bwm;-~@ zK<7swh$)6qyrzwUKX=Jx&00F7RMD7xvTPyfoy_Jnof?C-lA)0S_SUdDbh`h|Tgw$1 zUDYG`|4{Z0?3IRFwrHi|RE&yk+qP}2*fuJvXvJ2=wr$(CZCjO-eRuD3cK377?Y_TZ zjXCH0jWv+Xo!Q!EqU?rTWSv*xNu=&>*pYuHT>?~ zcj~esqGkVz?{F`@_PQ=m<)Lm1Jy3*`F8Q8sjnhX-oEp4+W)Jl!gYf6DxvKi!xTy{4 zu@VnBp#*-x;38rKm{ownMl%N04moWnUkpW>AIu1@;@41kq&da{COhEb+kWmgG@}9g zyNu^>yW!uhju=A;pn=7HAyn>6cBkK3dw45TRw?etBD~#spb8zW8P}k`dW;V{$Lsox z4fSxzk}~BCoOcxvA;Hx)Wb-QV*gc3iA{dy-#Z`)yW@e9Gt!ZUt-G4L+5-u3CEilO; z!32smN0mg@onYo9KgDhP$1moeHuu%Un7FRC9v(~Gn+*$#O`YC4T`4)UX#|&561;*n zPQa%#-394P*5dNc#n0Ku(p|hFey5&*7^OMH8UWG{8b^j4jG7Qc=%y#JnhQ|nPR0cy z%D_br4wZ88Ib@AzcZPFn3N+5!mPZXr2_-2DO*iAxCXZoR9C#Y`j<3_UaZ{E%$>ga` z$VFqK?9=N1@z^jubXz2}&otbqGWqeVlW4+pudCdeD@Vqig2tb4+qW=#4IP}!a;Zvq zBF?ZihKPwr8`#jEc}%nHk!Yt&E1$}Hi$t-{MAag<#f&K}!^XsN6bRLmA9LtD(6pas zA~-C14eS2>b)SM%Mg6!^W?aV)xqxkO&Dg<+l1e|<3vYz^p*VA5K1j=|%0KlT#Q`Q*CQ|8wSsC z*jUGtlFj20>BXIK;RIw7s=PdlhjM$Q#s0>6yQW`il)!FG<0V!LvjsqT;;FwW- z(hy?ZTIpqu5)s?r6v&!~50SukN_+U35VV?Uux}sksYe+6;#Uzw2-fmr3 zG3SZxHe3p+-Kek+AGHT>vtO3jHS>FVfuzIWEEfLx@oAiq-Hy88d+lv~`i3D`*PtDR zdgDk_mQ!k*&@*jxxNxJ*3ggh?_i^{{zR!IY_<_+w=oK;qPp^G3!(Ustey!0emlLxAv9Q- zJ@9y%G(!I1G={2yk?BQ;KPdfbKeuqoI#-~*PbukJ=^a4C8rUrdT_!rWLdtGHUMX3(Gg{X z-<1nXj41 zTOnFc?yU?({-NlLgsZqE>(6F{@ObN}`DKghfb7C{=huy9vliffdz?9Sc;xHJ1od*I zGJ8s1r{Jd67PnWi$wmPf_vI->)f^nWKRhEVt&3s5a7Eb;Xd%cYq^$NdrJvk%Tp*(= z@QPE1+%)&|gvKAFkcVFGaq|Rh`V}hAxu43R^*RJiE7dx7z_o1x9mG7SwF91O!%oy0 zR0g-E?56ym<*DA^#-J9Szst92M3=~bw9D#sXoAn`f$X{nw$lwW%$mgHoj=eWPh$q5 zQEM)2*h92RO&~=iDT*@C+>Ub2uYVk*HnqL_wZrf*Kw%pDl1*+*-u1h z-NnW&eCJMSJIvOKXRV0(^;b3r;sr0YEb|8DVSIET*R}BnQX`QU(s z7cXWAgsrP|;>7lgU!k4co_3&DO^BWR-YD+Dh9Hh(P=jP*FbyfA9OZsBoX0sZ0Dki? z{0@_vA&ST-i_igxVBbg z#QmiAL6Zy?imaewz%W_m_w zx;iyIqT4Z&Q#3;W=__ll9{DRtY!%`QRcsZ~3s)>TX3SEEPvY?s#~arS`HL4Ih@uGD zVisqXuubZFynA$r&#MdgRo*aSg-Na49-C+5T;se}Qo1OC(C8a2Z%B0efp;8yftl}rV z8}HA_^U z_=nZ(FB`POITjX7Lc%OiDElSH0TdjbfDWWo3PdHW*TbeNj@Hy>Meav*5NcSzALO^<3NY09i*q%-kaWKgy`luyezxGwZz?K zT#1}nsWUvbbvP)^(?C3gR-U9+J`kr? zQ((nQe8lM3AgE|}18-n%|<> zq7|(6Yu!naWH_K}Y_i)?er;^7_EUr23B{pB6!AI5cU&OqyhjC|6zvJA3_-eZ30Uko zZ0u)Sgm%i)?X-EWHj^h(v=6gSuvT@=S^YWpZXP0DWuJ`97(8Jtieg?*8Z zpaDcS!IxMyr;+md4^zWlI4?Q`DdhOu+;nmE;;li_8bDpFUq~oG@7u*jM{g)L5!aA) zM6+7*VR=6k4CPg);kb7}()WHYpATWZ%xSY4rrS<`RW2vv4k^WKXUy3lJp-@z{{pK{ zFHKeTFIWM;U`7A`2Uh=**ZtE?v8E$~GY3@qB~OWHp4#XDdZ5)Wt)&o~6Ou%L$NosQ zVz?N)H~klBDsfbl;0A=}21Vi;?ERbJBD5uGDOC~=Gj}GZQ#*5;-e0eG*lhm=*xF|E z-rfS#-Jxg8+}~rE!@dM5o}2E1X!FDwp9e6b z`@knMSgFc$GQV)}8-$fGC6b!=rtObgntSbf1;X0U>O6^`tRQ05b(8Q#?pbBPjvOK+ zV1^n=`vb3fJrO2_6l0UW+;P~O(%c^o_?B|UWBJ9zGf0~ftZ0#WSRT;EAQKfDSi@l< z_;`p)t!5zFk0pnI;-`srg_#$2xb<3lY&Q&3xk6dobL=!iH>gI)xq#DzDjWnpZbUX|QcsjOI zdXL|41kYcDNo+X!>nAOl1z84}&C+its8_y<@d(JT!!P=3GA3x<&YMo|b)&isc<(wM zlb6|Z)3Hu4ER>Xwo%eXrT>;ZfU5A~Fmz%u;bYp1t?T_WU4LL99{U1frKUQCjQ-M`A z+_!JPaKC+{{hwp>p9sy+@buDN0(|~8UU|}LaWy2Z$>T{Rv)C7DOl7mdY8lz(ps$LG zUkycR(_XbYS?!FZDN$dNo1+7q;K^bH!9irSftX-3N8b!fBw8CpfB#V}Xy6jqM zjrxcg4RUtO_MBN}wNi7?e}ItTiP!b?^3i#O<9#Wf^^E%4h6%AZ?Yc*6JsP3pu#d|} zb4Z*;26#>VyrA`tH-4|N)qF>dZxbZ@_w&h0+_? zDm}C!^unbNzIJ=|Jb2-!n6x{7E;Rg`6y>WzZTvw#@DPUeUI+A@xxPSz-{mI6>Fz2$ z+(KRJ3ckjFt|WSw$Nfa>_1*Kdye_rutV;b1)PyP!qGzs4Xeahvy;%{ZT!N<&O8q0FPN2D>A=mbPD z-IR&c2vwPsJQ{AE8d*6BFwN9?IMERwWXceB?U~>-EAbXkaEi`o*x2wlKL?&qc>C*% z)5+R|x1E4n;;_f^qa(DVjEXAuW_LWk4(V$gUXH~*(ByTT537O#GLou z+A^o6rofnnN-k_&B!f0(6sBb2MCUn=)A$Q8=TK3<-F>!v%5+d|bSQqVLRhopD*oZM z033HnTN`zslpd<3DBnUL#_-aZ`!Q}5Hp-^@gqrGAi zuiykHX5gyR96K5Q6XZV-x6E0ze47`VXL`!A=es;!>%yj%Ft0|4W|lU*UMFQ++3ME- ztJRsWK#2@?E3*p6-c%-==*qX1f;$S$rj~0rb;RsrN=?PYQs^{vXEE3CdhS0lPX}su zb~aoMf~L1YcdvnINa)tW&VHExrxM19IPrJA>Ig&3&y8*ZB?!Dg$un=Ip3@fvw#Jfa z8Vx3!-q@bt@`N(U3PM87{7?f4TqrZyx{7sfQ?pqZ2CU=g-j?G^fZ~I!7+gv6K&hso zL_lC-egTjs{veeFYnFt1UedrME>#3pvjiBK2%=p*t7lGY;8~WU)MLA`w6a;S4k#G0 z6kZ(G5?+LUs7%&&f2YCN34p0jgPrcBnnNU6w4uh0m9JRK!oiJ(Bl-yH8 zh`qNyi^;XLO-PsjI-EmrK*_CB)( zxXTLC`O7<7UDop&vUX6P%NZ`S(IJ-I=hNlx$Rrnb^;E;ip+n?2!#n?V<<9v7W}`mW z#Vv}Sio{AqDra%CS;c|Dpy`=zoyOUVUmgV^usZ5&%5*@O(@ZrEgEr#3>n|Zd9o=w0 z(ECUKCLUDdD+`bEMc#G zd0k5K{c7*Be$SILXA#wfsZn{|tv{c2%Tr<|$SAxF4*4|$LN;w>^Y*X6< zb{Op~5do$>x3&RjPobA|H9vIt8GF|x(do%gAInNWyNz1S1c7?KHxn6((fss{kr84+ zKf1C#{XjIYL3bB}6mRWwC5L__DYw3s%qVWkOvQ*+KMvC4LXchUD<#1w8kvmmxv;xz zytQs3958y$@8(E=?fRLS!qhz)!Hh!8ZzM#Q^m*~sYT3bHGZR!tRTfJh65xOPN*Za) z&~2r;zo-agnNV3`PMSz+s$Hd~;_6rTF^w^ktU8D&`(s^Pyv;>)IrW-`%-HHR+AJ5< zNKYgtzhu`}FG*F!i#Rv9u!UD@iCsmnm?Z?b{o$d_%lm5sXX>|xb@@AK^(gAiC4{NszG8q z&7w7cDdW~r$y_PyAPg~%A@Ai-+BX#g(#;5EM4oQNZ-R|p4({H3{Lc$5Nx%WukUZja zgzGl(j%nh+6NC6z&!?V1;~r!Rvnr5b4@Xto3S@#5E=jw z;|{~RFStEo&!B_*PGb35w%eheZPOB1Dm~rg1Eyt<+*7)-v#mP+s3%6zUJPX9Px(I_sv~)}$~kZAl!yxIZTajqtE49|EyQ z*6|SR?!Ppp!i6Mdd(xW<{e^9oNlRdv!T=rW-9_UElFKlwF{`j;neUdemPmB{alb^m zfT~Em>*t}CAz*#lM6Gg}M2(pt3A8K4u*I3Pmzc7%&8bSpJ4r-ZX3bw9X^s8kxYyWX ztIvYBDYh|X=+a)_)`adb1a`XcTV}1O%}vg5O13xHh52Fg;H;oj;u^*kj6cjWX(*4Q z=#iP*<%v>zcZft#>KI(X;t^&RZ)!?G6JTK&?<)s#<+L|F3%F+P zVfo}yk!z_at!I=+spts@B$sik#?$25u+;)~t>Uu%$25YYJ!h5yamr$i#|hx)8GUX7d zWHRR-Kauc(eHWtVsvq{js5Mhrw1!=eIH{Gp0-vfl=SMg8$4p#pnwNGo(0{sDkxx37 z6po(4j+Huy;N{y|(507sG6lV%U7m@AKS=TL^m-t?BE?6SG&Shs53y~5i6=%xy< z7zuR?_O{Ff^zy>_X@U<0|I%#_b#wzLAWwuiCD7jqpf`iEuA8=xN?KC4*zkllST_ml zUtyx|A0f4Wy_FI7lz^7tWW_;>FPJqXOFYSP&lQVELX~0M{GkyPN+O~h;{k0-o==#t zq)uA^7NtCZR6WJ}Y}W4-wYMWZ@cY@FQsbPxHzvy*OF~Fz=q8TD>Vsxd>}u4KDLFw8 zmEmXomWw!R8>Y2ui9m^Gh)dn-k}xq4bA#+D4g!|gjrgh2d>rby*VzyF>@E+BwJAnLYkx&xpyBV9pPLWBqyPJF=}J9yUIIh&Ci0D-U(^KT zw{L|1@1K4mCaxAnCjVl&B2~53u~kw3$_b~C$Pi{EH7b-T7)j2uAXPjFX~Pi;kdUy7 zl)LxDj}T&}Pi~KQ=gN=9YXMG`@XzV5HIoO%0;2hzqrDtjreuVuNLG!R>W9SW|Ee+Hbn1YIY7hBn_W7&Q-g)yULwow1&u2W9a|cSL>^Zgt*YktZqLq zH@X8(0;;H-4bGv04W_LyZQm_w)lRK!frPbv6VDlKtxaPw=Ry10Vr=-sqK=2w_Ih^L ztp=EzvcRBz-(_FpfDu)oU;73k5<|Lz15SVvmg1LoNEC`(RV14+5E+?EiHSyWvr`#e zE^Cp*zPBdu(mao^L^LBO%wKF2rk#$v?JroqFgIh6vJjGaEKZF4*}GWRokIS*sV z2xgKw{UlP+0VFy;ukhNj)ol4^--$?V{Rkyuy!OO-*b#=B6In#4tqU`-Ds87z>~PVr zKu1Hb-p1c>$&8q8F3 zz_b9`hqna*rgnnwS7%6)zO>LL@n_<$q4&Me+HflAx zuxp=5jIHm=?i9PjFJZ``*)El~5WGBC*0c*GmwO<5*UR1ySOwl7_l-n}GR`c9e=(0# z%{>g8N6tx9Kd5vEsbRl z=FqM^Bn6!zV}4>w6}6Ye?Z$;25YMX~9-&hw7BEnK8XoGuu)?ftE}O4BzReDXg{9Ub zc`l1NRH{G)q}n%I5ool@;+nA-?@|7mW`;HLUJE@%#jyuEeQ1S4q21a~I7Gv1I1g;P zIy2fypbHDeGBbH&L4ixN+ayD2{?r|_r6`WS>a?lKB@7-ZPB(xQujJ-l$Tfi`w{u)V zqa!m%3^M1z4{IE%oL{)$oL=i=#&DefmS%Jqwb(4!&*)N(Qa)0AdDx{R{mXh;R(y3rBwZ zm(lPU%;-5mqa_%XFOR=sDz*<@qc^#DmwNt&RmKYxeQTH4>xeuRCeDJKs(`)bki09n z>6*>sPq(Lguvg&mTjiBghMK@H9IillygSz8yZHHTMm(TM z11eT)eO_-I1Hq^qdf-q<8I6h4nuuBj>RA$%5*U8F3XrfQP)P&*-dJrlZvpHqYjjzFL({)T9LJ47pw^| zn+Qkq$6;dPeObp0vSTd)9&($JB?nR?xuj3K#DX|+h-=?G)CZNyr8Eb{9kK!oWA~i< z#QK}PKnbTg0`2*g)9_q-lV^(}pzyl&5fP-8b?ibS@-PgeiqWa0LPM)()sr(`%#UavPGBQ6Bl0k%;7pZ`g#95{ipWAr z=p*f)+d@!CYTY&Rdw-yv%WQ?0A$va~RGu+hCJDYu%b-mkfl8L@<&IL#J=@yI$#Aun zM1p43CR1(~Gu%;pRlBoTry^Z*`fkp}L+b%X7@O@rP^(eKNYFV}ewgET=TDmLctIYz zol7`2Xw0nMq7^yn){>tMOm24fY2F*y$2Yz4@)FCc@+q~!!S%?5#LXm@M;6d-&Bh(6 z-s@-0EpGP)TKusi@TT$pk9ACZ!BcZ01qv9>pgSiJqdq`d?~SO<1@s;hFTwm_bW)r< z8KkDCEuk`W-M_UFRoi9O%#pU-O-N0wG35{FX+cknD8h@2h*HaUU4A6bX6WZud7||& zPlo6aUfP3h*8s83i!^e0Eew#Tn<%-_oo(XhiOK^bj}S?bfNz(k;fV zz!xISRK^UuM**0+;$-ockk5pD(lc@-7t8Pbe!A-ML)vEHHVPZ@Ku_}LYl@&7<#yEm zDU9Y)jyxQGtr;nBOn!8ExX;j75hmJqwSv#Y2)*$5?c-&M-Fbzi&UB|=mF7bR?Gfq$ z?m-JW(aVX_Q6|fU#x$$%MkCIS4DqN1+L=|QWS3PkyUk^#0-k_DZ2!)bwOvsq4qp@p zwKUZ!tkzViFEwGAVEYKcs!y?o7Nst4(#_9JvNmsCIZ9XlRbB6ZbrDVidmrjOw_UND zc)rB#3~OGx)=WrNMrN^r@iH04$LgO&KEJ?8>zE79N;y@OMokhk7><7tgmm39HrZ-b zn{b5^lDVP`;GSDdcwxWIjM)7yBT$!Zzw6sA81~TMfxA#_6b~`O^JR}UMPZ9K`k@ZV z87437`KIbzZ`T!uTeTw4bkj8P6RF@ghTxMyk@xr7^HLC;!>HdO{c6?RWF3BMXD|F< z_?J0YkTyOmIfWo@s}f#_trFxTq|;6PztpaKmYFU)!|-x9oj|KI6om5epHPmW65YEY zHZB=jvkeDLCcyZZkK8 zA%~^P>s4i4o9ch6V-myh1^QS6=LrMRw=)#oe#4AG3$-9s};fV{$(Q#g3oMP zL)Hg9B5h@TvmiyFwI{nE^}AJfsA;*S(+zG*{)uLh^AIiRx(u(RE0lW0sC zutUDGt193jHN0Uz$fW`441fRih)ZLPZcz%(YI*=hudjiHdxZPJ{*!30YpFZP%HF4S z8<6&az&3?{LmuUJyKkaf=Sy~Q_x$7UV3aTB;j4v?Z;hBS-b_OCb6^@T^%2DD*;Tn#AmCM6@nYHX0YT?S^lq_ z8QLBjsWZT$!{#c2KX{#9-ZUOftbD{hJ9MbsY>5Ib#S8LTpFD6n z`}gmxz8``-pRn3!W>itxu`5{YQonqh+F^2-HWhIYb}{l!)Fx{t(oNADbggEbt;_T^ zD#K9B)$H8|?LCuq`fBdIfGLb+mT|C|<|Q2LHnRKfgb`qIg7p*%?3HEa1Cro`OO^U6 zh}w1Q5&;A|2{3R)Bi?HB^OPo}9>lHOV>*+zeH(1nwgdAyyAj!J`tB;PG#%ZB5ER%= z{Vhx*4d7x11DUKvuQYpyA?u~&*xpfsFkyF?NxH*?j4Mn8%U-GjqOtpa6%i&Ffwf*4 zl`yU&j*;oz^A)+`7+@9z>*42~s`q|O(Xz~85z~1`bp`DSJ@BiTP&rx9=6`)V@Ui`K z$0wh((NJMdOE2B+2||#-J=qfg+h^23#t6lkA1S!sBg0YbN-&007n6(I?p$5@j5gWw zS>6U71H&Y1a1UH971{4{E%sY-@o$feQuzei{Jl?T2_)P$=3Cc7{+1&Q((0bhWax-3 z%GL|2iNZ628@xKN@2V;@q;#7jCam~PXgVj4drjI0=9C!1-|hPC0-bF zMJnD@t1N3|husH(_l;7TuSGS|O5;JCke77x%ceAV8bMmgpAJU!3N=hot>#^^HZEh) zX{($e?ajhtpfr~lN|D zOjIaeU5(8sIlY{)HFk8}YbX=BB`>tJw4fE0r91lD5P=yhl!HqD$7IncS|st6{Byi~ z^&5f*Nw1jz9a~POe1qdRPo%^;?+}l{t(*F2BSW;e4C?a>TqLZqO)3a`e_CV8i8l%jh<0!D9-~Ec=a+gZ6^;PW` z#F7rjVyj6|WBq z8jX#wPKZ~aO(06X0X8$%zz1yg7rV~`4>0cw30$S{Sd1Z~nVF~nqd5LCtSo&0^QYS% z$g*J+q5@)hMjpY*Et#ey#z%sIqcw!dm)%Y=W}sD&3x;CK0LiI+yTrOK4O#FW4~5Wf&RZB!N)_Y_9tk8&A;STsy~o~aPV{vj2v*Cn57jg z;;$rkg<)PGcRfSs-X%;vL|8v$BHxMbLe!_Xe;|{ci(jKLhF`vGO?JKf+Xvodpqs$r z<1tU-7pwE-3HI72xEgpo_awIilWsT+|mpzjEq?sS&lcR@&AfA`Dpf;bGhqKUdh z(!OnWIPp)WdtUwhxU%a4E#AgPf#_QhxJVLJ=kTmO2P;Lv3B3hHYtDe1nNW2^LxBd) zcM{Z*zi&8pbkJuE_j>^EOB#^gI?X-fcD(A3fGsejjYFoo#7o3G2k?}p7U|TSrVV*0 z)TAH7@FHf~9^f^utbcGuF;3C%s{`O?eJ9FsO$d zN)=#Nu!={ z-?o2EY}HIXERQsR>GOsI-w1f!u?gJ-~bVw}4_z05o&UG&(* z4Jp?AaJQX=c&qrlQNi~Cd-~7T#fasEnKq-9z2J~S&K9)((O3jP2RJjmw(6_{Sm`OZ zE}~MaEan9`E{fjFn(=vR=WpP(i6n>(HPaF^1n zdcPd7?$d`9ZM0csaO3=QujlZHF%y)7J6+LDJ^*ZUeM>Y9y^fc^-XE6Z0Zh`?kf)4s!f`&Wd z2@vvES=)J84%{CnRn7d>*02alpZWactWN$DX3i^Mvww<^@0ypB1%RDp!o}d;F2V!` z^|3@Lj9kN5$kM>@+?wdLL6A!fJT2f>*J$sz%WEplQQZNxta;PV*ERE4nV2DEFIlZr zYiW}94eA;^Ft&>|dXeyF^X+0`ZIqiHYZ%U;C zDOJ64XiDvsgKDPv$mu6zgJUT-;Vp(1?_>Xg^A(RqNMTadzfEp z4rM8?X{LsA!UBwoA3}!a9A${g>Jd6#9NuaZ9D?%e+f>{Q5zBbh z`$rUeshK?RI4GFj24|%|=}R1k8mX};%^RsXob(K^ZYm2JAJ>cn87Q!`zf)AL1pkge z5s?&!L}+Dckr79j^+M^lz+%$E`oR;bWX;2}9{ijwWxZ^}kxa!D%~GI|Js*>i?DsPO zu-4^z@9T9tMrxIdS|OfcsHysmX+*=J(ido?PtX5=rH%`WMGL<9VfmVV*dJYH;V_F& z=Blugp6^wIy|m zf(;9h3au>n-Io|NwI-wvugowrKa=3ovP5X0H4eJrX@snaH1Ifp8eS&!N@i{?)d*%? zW2}%S8g4VbH)0pYC6$q%doU_xEzp9+rsia+hMLC*Q{8zb-|bxvIM}tz8t(Q19!5zW zkRt{#!9$5eeg$_x|3Dbwhyd%G&AmKiF_K_RNN1?7i1U+D43DPiS2T_yz!Hfgd}VQu zO-_g~h){sBw$XYhV>C<=U2vphJTKlh z25-VQ3%X{qpxI&-5_@?HviAoeY?tDcdkwC53ljy5QAC+yb#!zXr1zc>=xWbrdKECC z?kGl9VsVnw|Hj1B3^C2a)O^^z#&m2Vo=HIz51bS>DsI@QzX+X6#0?bz*9L!2|9wVO zmWX6!FwCHse_9uwYEb-hq2+*~o*xiMCW5BHWE~@u5i-UojlTp_dV(B4>i;LVQK_L! zewR$Al`3`2s|!r5UMOW+3rC+9MLzgf<#kE536b>HwUxpGV5Ti|R@aNO5@JX4C*Lk!RQPO;5PA z4E;8&~O{Pq^R%IQ&%mZZb}@p&05P$!9Pm4|74!0^kKK< zC+6=-t#EG5mfh{Nf8}B|5{|FU3>#_mc+N~(xZX@0A8E&IYdiSciDzB~4LtSje1(BR zIz;04Hu3mjzeCyHlGxs$b{_Tp*&%)o#UH5hLiN2i`g;0q)ANOPy-2R_71?K@-~7%p zLvGRtT+@XS7gek-bcDfO@Ag!|gJrKlxk4Fm__1~kq6jjsQ1u+cfP86y!bcRg$9Kaw zNbdal8)iq@ORNaQ>+rbUA-19n+)y)+GO(|k(!VHCNa(R22#Smo%M53df|pSNaA=q^Xs2qOh$@}S z%Rvx%Fjus#DuYD7@r2%cAJ#iF!=8!Cv%3{zGN%kP*=`p`ssb0jw}!K>8&`mDe>mKY-J0EWW>8Vbboaou!S9FlYT0|fG4vatt@<}SE`E#ts; zMf20N-qC**KZ)15(*SL>p86kIQOhND!)_I%&{T%k}AHt!mM-n zx?ktirI*XkVcySla(v~{C|$4OMVCt#gB12zd#gqQYd`z}jB;NI4>O~v*dV(y0Zyu3 zq8r%-8EPc%CX__fD`CwRy+6A8y=eUEK@M_}@$f^}GjUh2)XrXgbT&JT6@~C7a~4G} zuJvQ#N?f$c{()KWfO))mi_4-<@WmN|LOdGA5UMKe@HV1{ct$3s#{AHp7+%Zi`w*q$ zHEBw3Jw@!>as3vKBEm|F?N{nJ-_3|hX&>py7&@B~I{+(}oiHc~+_9lrAo!`oc3NX^ zrpJ|w=V_p?FG6@;f->gLcQ_diK7wngIe5Y%#|Yc#XP}RY1}yIb6@PXe-VnEBIF|(W z4#7qk`9qB0ii;>Zq#Lw<$he-hes`Sg_Am~;?!DI`r(;_GQyIim_@l5(wa%FbD}|*f zfI;`?tk?ZC+md?%4$M+{s96qb;VP*`Sh9;ej2laUq)dUJ4bCz+a+N3A+uw9Q>TFd* zx;|qI^45&ZqQ_4=p<0fJLCe((NI?mvI|E^^-K3&Lg10K#JgO)%7Hke548_DYB3*a@ zXkD}Dr5YrKN%L_it5!cCMhy)n4+~6a@|h=01T3D7RdfpPxFuc7j38NkEPePgNj6-@ z7aWV%b4IwyDSv~^6JZ3TY`vfFOabMsVonyd+@~WHbdmhNikva{m_5Fq3AMfngJ^;v zgNQMrFLbM4pZd(rnZ)f%Gx{Pcslo4~if>oqWeM9k+4rM*4BsI=JqS*ts)WMg9%s2f zg&jjptrYqUbn=k?cq`^tx>E36T64V|j*C!c(YVJw88XH6lgN*p0t~CGY^$qSQqAeb znIiA*-;I8`i~Y@wp^_KOmzH`c5Z>Ap+OV$_Z>&1|KS44f|kQ!HuU}OJQic_(X>F$A1U;OK~%4s#+XF1M7LX>4fie`SEi0hVX5wW-qtD zI(LF$+XydG1knQJj2aIIi*~Qc>-?(49z*LWJpx+2Z`;_OE_Yls$RN3F`IbV;M98Ek zXFn7VZ)U*jF!owrCAv(4Bu8e19#)tXdt`pAAa^IC^i8CFH`JF9sy#-^lpYhFi&@x| zt4R(sJu^xa4wjv_xmaudRzbKSifI+^w0T0|Qp1utK?+At7dG&v8xq=O2HvGVUfDLk z16^#04`|?`X5kx+r@Rn^2;}5 zgS?8w!-_3bu0ms@b3b#!HYk32CHMa-sw6xF#{gIeQKAVZpOl$k@Cojp5{uAPM*Y&xqA;(i#gHGX$q7q)CNFk z*>Ib#J|kyv*~TmpI}1E9eWYz%Kx1uWKamtyaMLnR@G1t<%9Ge0V7_tE%omT;G0Cy3>G(#LG;=QxoaPW0n)Tz+m; zBnJR$b_*kIEWv+1+-|} zpxwRyJ{vy|7F-MIsphGq_02e}b0!7o421=l00$WD5!kCo836gGeV#KOV{IzruwrK1 zJUIQOOk;UV?GjCr-{;!eil}hIlT%LY4-u|FK?{4>Ow!Bzp&CU~O8fh8!BEv4)%%Ig zLXGFvQH2q$BNyMhdN-32gzWa)DMb9x;udmU;MM9ZP$5%k^W1DCZGNSq)borZS|+t0 z)i;ey2D`nP2R^+vBW_+9(Y;56<6GUEytcXgY_RklO61B)!Os1PS&oF(|ibXjl1Nz^muoiyz=6IzJ=@N2%}2Hc;)pawn~z^9$gga93B)_6YVbKP6+Ot!10Du)~y@XB+ZpGc+J7L#^ z!XxI(9u+%hBWmQlCqw~Edn@f|uo+k?{ROUK!qmu0++{oSIaTTbU+F>_bJJ0cV1~y_ z(|$i-8HInIQa~lst29cl>v5)M>t55$QKojrxK5M|*D%4de9ubFZs~syTMMIZE;S5k zWrJGMCz!}iJ#bXK1^_etPgZXk+s35rME-aWNZ*nscQc5o=olSW;^!EkY62U72a6(w zAls07iDyT?I5S2$0OynsYKdu->6{s^-ZHCpA>dA*t&6C8Yg)3pY1h>lZxHU_iCNZr z079~7Ro4S9K*Bux^o*AKkpfbCTu#oHw|dIFO{G18TNXGhCP$?{)WT2|7M#mfSmFmI zxn|32Cx>z5vboyXbl{M?kTXI@9|n*v55AKlQ|W2I40;tH*ylvUVBQEd8udblh0)i+ zh4FW&j?5!T-K70F!XZ_w9ZcKx)>4?rDJRH|{i2!5p z{ZluD?W%P>%VC^g8wBD6%ibh*n6@= zj@ldVPMqD#IJvWTH%aKFyaef<=dc6-|1IpSO7iR_BJHiYh<~|{nCVU8nEAdbxSfwa z{^|N0>Nh;Nf{&1@PmVHYw>9(M?{QTip$3ej?taN6Xse&dYQ)bpVR>72|9OD;nvF}@ zzWk0vUw+5`j(TSQ-_*16hU2UP;$Jz!d;vs}Vp{Mu%hLB{vGy? z*IFM(e>ve93E-20H;kFE*#D$lILMV9M5F&rPyFKexU%iu`h5R7AopjzzEC$ zSi^UjfY^D|Odr=3OLgVOgE`*>fuT4j9%`Cd@r;(jqpzOrxPpRjJlHD>@r$6>FQXAe zqJ5J0Wb_=oZS5`^9_yEm;T5Vs;39$zjRJG7qP$87U}lu0!XE7(B?y=Rb5u7IUqq$Y zNz8HQz=RjR&4AaoY+HS>xqkK_NcOpwrliDhMPsvQK1+1=n{r2(m5A9b&CH zUnR^)6~=BY!CJw^j5Wb9t&PIwtYNaIJss!Q38?RP%2|!i8b2kTyBU(X|JS7~?GlekE%|XasgW*Z@I>7c}=| ze#1!%FC<`m@}nibA3=0xE{+0aImn-128JVrMfXKP%LRQ!+r zhm^XaV4YKO9n4V^l(ZU)d^;y-2AQflz*M^`8qF4oGoXuof|oi$Vzb|7leAip4QubF zc>XYx&zko8fBPYi6m8To{@uA5e}!$t{~x{4|0JvwEBiSuh$8re(NM9b4l}S@WE`Wb zM9=_}eH{e?hp-dEQUoV3+kWnd@LC7_Rg{oDYdKRpm9{Y*m*(T=Qx4-9OQ$#4pDi~# z^yyglY5BNz_WOA_(F0JOop%T@n1<(6`AyKPsap4)eU1}x;knIzE@5Z1!=S zuf+rnCY8fE`VaF^yv*zf4u`h#DKcD6o*c(8GV{zGBAKJOK|FCBX{fSg^Ih)Q(%2u#fuK6@I|csS8Uy~ z(`GY_qk3q$X1RPO=>^HgbCd4A#s6kdBtbnmCk-vgv_Dscr7M6FB@USEt z%cg2jqUMWe4lz($An9dJ6C!bBrK&|t&rZbxB zm#+QYjY?#woUjMn@CKfJV*F#sff^f!XB}|kvUD4^>-?5XW z5THZobIu4F9kRM3AuirV=a|`Fs$UK_S$R9Zd7O9lrAov62x+#XIM*cvVb;{k7a<$sd0dp#U0OwM)1UTe^$sERQW|( z1Kkc7A*zBZnLV^Mu66F^Mo??ZD2F&D3H$*(4%Iq|97RW}WAAV=;Ct0^Z&e<{9o4>)t!*uNkd_leukdR>np+ba!5&ZnJeNKr!302mv2iKtkh1*S*7b?ktVs%T3T2)=@>S z?`8b6joeB?I`QpbrCTUcYZ1S~cpC9)J@1OV{p6D{dJ?S2rj=?bQlh%&w?J=z4hBOz zbY@c%)8Z@FiDmH$+r+JYJ9_g|*U~kFnAN(ZygOhRmu;i|zgM{NNnMNygS(1mYuCyo znl0?{5Lbt`cn!4kc+kb|$o%%A-3-w6oXD;nU4^zX6rdS~59kK(^mY+o$NqTS_t58SKnuJ6^Y~_aUnlHWr~L;lw;d-Jf;Xsj2pk z7OOK%nd#AdLbahfbtuKBrr?C;P%g>`)9UQY*b>IyI7bGAe;GKYfF1SSPHL;JE9=+l zFrz|-3Sn*+#M!Kef6Uo~Y~*UCvG?cP17GyrDu6R^Entg@?pEJlRk>0wE7z*D%H^dN zhb>D_E@nzyJZ^P2{Ya}X8a;_2KzqK{37K|~6Xu+b%xM)hzWQZ#D8f^pmZfQ7(_o1d zwz-6g7-cV`MGeon+h&{0f!u$b;^bvDAOblz15+6*fa1VmPIhU76`d8mXUwk{NOU;u^??h1~l%P&K{WQ;PAjyYY|okASH8pRj|IFN(G9Z+?z|dkzh3=`@S>&3e_}4NHpS|Vb=Nqw#4)dwC+_f zZoM^|;>Ec2=T=Sy=;3u2Om}$Eq@J-aX<2j4xUJ`iA1R^@D6cyQ-;+I59s!$eNPdYsSl4_1!WmDvWb7b4n`}?g%dKw^is?e$ghvQdU2!X6yDJX z*l9TZcm&>s?pj5O2swb@6$?_qq;4ThsB+Tv*WxQe_jv@m8UFr9^N#q1fyZs2H)}(# zG-1t_#Y~x5(foR5A`sAgZNBJ`;p>?UYf!LZTA$L82C-xXbT2JGtF&{xw;^ zc6OrA5`A26UWU6cHC{rtj4xoP^$7h=3X>^Th`t^(BWFogL{+4>z{UFx`)IVQfcBNL z9RdN+HD?P=SY#1x?_Y~-;7#lP0;~SU`?W3BGa>n>en;yO@C$I!Jb0iS?&>(xeI7CD zd-R{W?!=Y2m)N+N9~v`L+_f?I@Y+Z7oNQks$f?|;+P0^k5v{v=|8S{3^xu}RZ-W@8Dm^bL?6F@A0}iZ!#9Yfr2Wh1^tk%(D9b7hO21Iy62waO}lW;Z- z12T2Sk%=g51$1K#oco{lq5)z@YI>J7SFyTi&gP`Tg(5SdNgR@o5f&QOrs3J1ogX=OCA0+L73N)6Omblaw+pWD()fo4apSDXOo3ruZK>@V8m<5p> z-hreg;T(aiFZ)@ES@=B2GY_m@xUqwS5%QWdrcA_Cm9-y(5@?1C08F;sq-eEiGU081 zCV70n+1HRt!-uA0#{;6O*zo%~q?iI=Q_NAM49IZ_)M4DM0A*Tjogf2j?+HHZvwwQq0jR>x>w`Nw?RtwZX8K zM>@1{f!jhxvTY-p3~{|7Z{WC+`=7<1n;yEtO}C9MY!NcO4UJN=Z}`TM%;*b<15Pb& z1^F50lke#_37XaSrSas~%=m>Unz0n34j2+3n)b5^WsIFq5FDD>SIGZPgMjNUu}DW1 zUfl_kEX`R&JP1Q0*+#&X zZ~^#F<=ez;W&frHbdxqavi)1Y5WGi`T*tH(SmPI$9wd~D)#zw1uzftc_B|EC6UtqNuGFk=2LXeodLQZ4y^oLAYB|}(2sSS%Ic?>;87h`VQGa%7zp$4MDK;Rk@;dLO) zQgQ7er9JMQ2bZ@JEQcd|L{4c<0$$zI2sYi;v5lZ&lw82L(N2vdM_@GmGo_N!ngO0< z*jvuZoi`9lJ=8Odl)FF0l*A@Zf@u*UOkAFQd0f*l__Y5EvVjT9uHP%;zMk6JWK-W4 z#hcV^>ob7wd5X$JEID08&@MYwnyaX~kC=hV;7&VN*NO;+(ME=N6NtH49+EC5mHEj` z#cvh`PJPD$2NGj^D45x_M<~TT>8ZF*UZ!b9ey|mxx*^x_PlX=k?L<~bm=wNPc$3<^_G5xeglK!+x$esEzQvl+Quo+x<} zW$%^HZnu%cE5;q<<_iegyK68GOhMbP1l)hMh_7y(_-%vzyeH zAP4+;P9BL7a)V2?g(KezxyQE;i7pbK@Kw^ag=A~d5ycGaEn%W^NGio$qZ6pa=AeK; zh*Nd{M)o;s<*(y1VLGZE!58XiYzchDWr9S|*Z%K9#zb3Ib0#lnMQU^n^@)ih{3&eK1#)8A`HO;rFKaK1CK|Jd%K&+6t#` zklrQq?4>jo%?}ZEbr?7!*KF3tKS&^}G9E>8eNayV#kONZC=9qrOdd#k2 z)};d!R9_T)SBOE3Z@X3 zqf6RFRlSF*ybrSBgjy{yt`Wyr#|m|A&l3qknO5k7mle*C!*>7Gah98Nk27|=Tg#MT zmjkh`m`d3ec=m8B%`RymN>bK65UpS=J4RwktR^ooF4v)EvYU#Psw}npTW-AiEPYC8 zwrOfus2SK&Lk0{CG^)uqxHYcpbdplh#~z&1<|rH30du0-K*&-VuGVc_TKLoFUde*) zn|Z()xzhRZ%p?%93Wa#$SOM@7;-xx7S(-B=y8sfGr6)HUN2Z%_ zG%#&qA;qz*L(J`SrRQ9wT$+03>8*UzJ+|h3YX$aCHv&@JPec(c$wTj-zoVVrtCCrB zc_qrJ-z!!FxKd}0;i=>9k1bMir3(+cOuoC@DMRO}Y2Gt>a2S?~r@^PhA3Zi{Z*yn? zw2|lqhu^9s^A~O<*9uU6{9|mjjV*JAi_9WJi{c8|B1wg8h|Xg(5H!hSvojN5-O?4SaXNYebzHB4ZTIT03-e|GZdgJSU zZ<|rO+Nj0yZCspNwWH4BjO-QgU6P-dY=PGUpxkUYXXsLSD^z$ef#;rJ(?E?PK6thC z5H`s1*#1n{cPk<6kgZp^C7QUby?&=RAnHf|Dlz4=#QI1QHmo<@<|0+j=pT&?$v)(i z#4%(-9aPD?R*JW(FSau90%*{Ev5(Nvt1BDR{n!bJ%F%v`Kt4x~=J1ezG3En^5u_cq zP?-U_VLrvDP^uTd;#OQQV8AVINcW3yZPQi<5&74Qm&i`dTuaF^13K_M=o@jaH$x@k z#?N&Uso&&qLL3bz@mP^uw|BJjS+Kvi#Al2_kLlRT5w^DI*>2$s*KeO@R1l59#}GF) zzYZAeGOTM9^hp0grH$-gEDJmOusd+zKK0YMm%ya7h~lJ zXE6;@l>K_ps98vtlMwm{w2V(w(5YU#%m}pBs?hg%g58APE9w2+ng$-@0q)uz%dl3* zTJyO@^1|wSvvaB99Y!bSzi%z6Sd_}I`!0bX{)P?Uz0@9LW;1)_#L+KJuFi4-=gO`` zI)MPG^))Cg9)LD)(UdNM)FI?)na0i$h3juy!xn^FXME0Qvohn{&XnvzwqCj)sN91k z+e0+8Gre*y%IWT9cQdnaJDKS45ww>!k1!d< zwMFJxYx2m?)r6mfAGI=Z-^<_7<=4UkAUx76>;Nn`ze+cT+US2wu=W=A^9&M;DoeC( z5qmhg&FkR>{p(ftb+!uxH=N}Fwe=n;O8v?yq;g3QyCO^UQm|^owQ#NYkz`I;=44sx z`$|J2wX{w^72=&&O2s1>Y;1X=6?14bYDOSUI9=uqM?KW*F!od;O4p+$2zBM#rtA11 z>w@tVp=TS}p_)wNpw4+p>+UPD1T4i$RU0*>mhR@}=zW|Q z+fko04|e=B%1u8Osc%op{?fPvW(2JU%0cyeYgN+pqpQol+St$(pt0;A-OL_DzY0pxD3WuLTbVhFa*R(aN$Ydo zvI>o3#ZDqUKrb0C?J7wj6vA2t7Gp7y+fB0dXb!XWYxZRn>CuQ`Q}lDwuP#tG2~Imf z@kc2UU_1{g)2mfo+saDmpgcX}1txbXmx_okw`M1?;7KN~>DOH^q zloJE0fD<>`P$a~)7}u_)}S0F130$SLHKMR{6ekRiPwI!0U@N;KTW0gx2wqlOAhfHHsa zB5Uq>=%xoRN_8a{R`mvJqDVKGjM!!ldDEh6ta+##U~*FTWe0D-?w>qY#x!WA6=&kR z_L3zH!0SeV3PNlVIOwd-#W3eCjm!}P%oHMq)QU_lb*w;Ejv>0c>zJAnLT{QwH!Q(ofoYnDS#1VworKZsXs~|v^uJ>p;A5N#6 z`X4zaYL}q)xd?!EA{;inBalBc@LWKRf?JbB_?0q#8ra;G&F97?4lTvcw|I?6tlr|4UDOHUC7nUs9j$5 zcommwqXEDt#x#xSfz#=yFrPqn5bSjJF?zuRsIi2z*!$bjp5_S+i-pc6IoEIAq+hZn z9}_9?AU-d zFUJFr!oHClYJ|y-!557vuav;=!#8ma%kgN}upxd1q$i)Ew^wLf!o7TO^Nkz2we#Co zd*UX=;E9?5S%BU*(r;&`To`^dNuA>Lc&y6p9wMUp{`s@w@1C|6 zkvK)UG$9B76MUZinFoHk$E^2^bxNQ@9IC)qKj(PD<-c5HlDwA&;M!+Ur`wLx*!?;O z1-mtp>golMJYaYsExXV*6GKFHbhvEgX1|4q8Ikh-1E=?1OtMXJ>e=B%6EwtB1-gIm zP)f>4us46nDr}3`EF}_ee3MB!ZI}HS+m^;1w6!!tz!d9%Pdg(Q!`OhB zI>{-@oWeE_Q?;;cncmDL)Wsb>(oe?hFumSO%8#A-*wTC3Ba`d{C2<^VG$}Z};J1Ba z5CG-?zF7MG*CnX#hF^a6Mf2=7D^tOl+aPgors$42*e^&(7;I;6VMeh2HtBN%BO0@2 zgZNfWcxd|tDH>a%*c|#>CfYYPpONQ>opNQSu6<{BXXKOv`H?fh5AdKbJ-kPvov*hC zV1B0j+9|_V^4kUG&QFClN1$SP1`9U#^@YJxyZWQ55EJh+9fM8k1^e>={foPA$O>+1 z$vyXUpHGet-7q<^3~%S;U;~N!t!IB9G;W^gi6YyOTT*ILto+UZ)(?|cEFey}W$!`Y z_LlJW%HZ}~l~W~7e{_P!{b$yjyq$SfNTyGy(a;ILnv;LZyhgz33Q!YW8QdJ$&l)Nc zxG|k?dhnv*?tK&3`Iqsww_;%1bSDPx$HS+N!^5AAfjKe?4JRMyrPNn&{5zY*948NV z(}B=Wdo$`&lx9$?FP2At4Hsd13t_PfVc19i^-KR;tv43j9Fa#5b`e;yTek94LQ`sH z7W2`@viPJtNVkZ+OYqM-@0j0^>=~FgLQ2F5?U4(h3v+RL)~9PH%xd1N$0|DV->CB=5i=^KDA0xiic%ehMByMs z2F18}1$(S%#2vGmbRHPPpC}qBp5RnZ2s#(Ul)q<|bLy2NKF&b1S z0a%#IwI}Cm#W)^#E=L3(M6D*_=Gd}S2F(Zw@V9wjoBV(*f2M#RQCydq)Ei$nI;CCU zdC;X7++vt{dLR$ERX!E(s4P5f*pltt;sst)OLDJ)N8UPeZ{c_Dj;cq_)B;rnC~j!_ zN5Y(7sqagt`W%Wy;lGXmzHoQH;aY!o$-g-l9`SAQkQ^J5LU{Vcq4nr#pcV|>yEIJk zN*GK`BPe8|6rMm$K*KD=YpeWU90fF!Uh0Ve1tlg+1s$MZ(WT5A&GYIE|HvSg&RYXY z5oMSY=D-?)W|OJTQ*y6_vowli$(}?u8Am-OAz_~y*2UK#W}cEcfNh1IoD8Nr$FWCs zlT4R{4RSd1XGw(#Q}K}YXKYR2ih5r9YDR}qLaqy56$s+MUrraJF(9%k$IF-r43+Q? zzQ~89MLUpP>gG4!t}=L|532;BUc+IbbCZfs`TZp;u$SI*M5jCW;NK#X>FjSg{yfW{x&uNLg zq9nZu(AAnwi_$XdvdYc|{XMp0+b*>!@e-~i7^(2Br9Nh3Ljl*E~zQFWbv_%6WRUH4Byq)7^AqIdFzC#o9=(?!@nnN2aiu zXa&4Yp!69Gv|p-0)-tQrDG&aq)17ekaELT4k@gjDRcyf!-)peyD&qSe zoNiJO4nu_Ag8Use z7V&oR*gj7N@ph@wAU;75d|wc8qv~hKG@{=Wqs2-4A#>j*?jUWT#KD9HEh5c2HL?r{ zElrq3S=7mvzNSmu>pL&^8*E0GJ4!=7`cFQQG<6~vE**6Ja^`8BUBPz#=**jLRY$z{ zUpl6@;d7)rVNGu*_?Sh_H<|;;yQ`@R&nc()9Os71__@<6fDKYkRC@3M6JTxAl}AShq`wZ--F_m z^-UlfmoxcuM*<%qL5pM_v136(q6g`c`dw|cs+o;I-%zV3#TORWb8~dC8nh3e5eGp! zl*tHI@)5E+ZK{KQnRS`4xCPrQ;hmF{iT#YjavQ=m$3}7rHmG+Im38nl4!te8PIzE zcYO>H939h>oV+0NU@e?d+wnW_`;FcU`xHKk(O2NJ7lN!~L5wlcM~=XQWT94zA`^p} za9@7jH*VB%^fKY@G*Gu9aJMq>7i#otVH!vdX)TAbz4i1kmqk}RwuO3gC0RiNy&=kf zbM$Y>l*xQUDc($0#Sz<*#6y;D#n_uMdNBl9C-?+2@D>%^f=oyFge!akHEW{f+e7AL{QzRIfp#A4 ztu&4fRQ_n=5*+sdu9=d?eU!J(1^lw{N=*S$QF!RfF&G1o3n*-?`}Qk19e$kQY0pV8 z^*c+rCI~t*bP@*~yb2+QYG@izZRJ?9MvD+wrIF@=lyeigy8zEAxkMM*$yr2Z1nx<% ztg<6iP;2M%97@xHf)L-y1NwiF@t*~3U1=Q;0yaSi)Bq33fZ8PZZ5jV&azY%I917Ud z5|5nt(K@cQkIIaS)*KTOg#DfGt2)kSJjlmsGzF^G;J0F(%@8WKq{S_jEvh>&qHZK} zHZcp#Hya7)hw2$;9oHRO|;ee4TdyOl23`%jZM^_%`)jph zj0fR?8V@T?>aiw9Q#_ER(s%fPR*gKX1uD`#^Njina908T=>q^KGsLVC^QoyPH{EGQ zqxKg3;~PMi3qqcYCFRPv3!b^qhX}Z{iDu0WI49`r)(BYjo84`U3i@MpO`A5-WxQFh za0q_>aF;RnrMk(922o4Vk%svd=cGdFYKQ~Z{JpjBWxl`Br`9-o7)g&w+J{4-IK^zwtc*qEMhPB~ld{rs86F|6B?HN_8)FBCGmc8zxWP(o zqzi!pT3Ve^2%KMkobZ)>xZs6gTqlul(b3RHqf>Vgy3$qEB6RPght zxb9JfTYM*$0M1R8RqY?tKn^hH>SsGa-LR9nlrCPkH9w=ZI17+Q%Afk&yOgfJty(ru zjy_2>Gco>sHVcJ9vv5}ZiIu0vLVXX%No5Gwu>IY z2a;{21XMLiZZ#X$u?OJ&6Am3skGy=Y@IEE&!q-cEr)8G0`wREb9UKx86LeQ43I~nt zoP@|>;FHyg--`PwPv4w;%qn^|v?dnR(c__ODD?ya|;~Z{onHu3!ukz9E^x-zNv% zt2n<@tP0ciV3!IFEzi>%;U;5Xmo2V}9}SabM4QdBQ&F8%JVR88f?Oh~$FQfVbf851 zOGJlwYw$+&<~ww}te*p-)(jBAP;Wen*`<5hrFGoXtnG=>W|f;@b7GT4x#cXM4L9kl z=T`simbKPyJGgm;84UpU-DlvvO?(}7cQNC>+OAHSH>`cIOyc!FH+q|~rJJ`(bqt7A zZC#L1lHThy$E9CCc`-fgtUNRjy_?XZ8D9eAa0$GS=6x`7PPgJ@^#uN^HRqiVI4hWJ zi`s@|8fROxv7&Vv$6s-(*{+LdhILR_uS-}Da;Og$_9V)LzI9UxTb}?KL0Nh6iIo11 zqKH?{<}yDKwkYQ%%DthN^6!%7h({moIAVU#$1vjo7Q~s-XkY&hPB~kjLs5SGalb=6 zB>T7gpoc45d*`LFcxWnDFP4LM>N0r9X!5>myLtHoOiIRXkwS#8`v+aNw~Q_R;L)2n)FOqZo^e=9rLBcb00%sZ!#DZM`1~$$vuDF% z&arp!?Y+tx$!Ec0Qi92C+EQf)n+w^&lq;oNk^Ae77_&XKP^VCb9Lfc+)JV2kF+vH) z@_r1L^j@6|0%UK0GXStAGtSS7MdLWT;bS!uWxO*6EE+i&Dqk6f2P~q^4u@Ms;b=(w ze5>z_9^b*t)(1)`}*TDdDThM4rpo{&QXjrCuo&AjaoG zNk&EKNl=}FV1N~ucq&_Xnd^cv?gCSsKxS*_X9hB3@93J;c9XX;kl)zlThjQT7;cze zYS8phrLa0fbF;8*;k409k4t^IyHDGv=3Du2r;5q6yEWRdPcRLycS$8jvNXt}&#axB=stu5R!nRw>=fbyQvmNsun z%wt1ad@^P780ta!HEdn*GPQ7u@BTfZ{U7-Kuxm6F`;QV=;VA7}BU?*P1VO#9#jbNJvV6fv}=+hfNym+epA*X6O z>?!4o_KV+#fy;(*0EOO$l3~NV-h)>qLm|V&b>6}>Ykd;>RFFwTEq%+mv@IJhgX;|Z zct}22>h$EeSR?0{W`@197?jM}DjDuBM=b59s$EWuUk`1jmF$eg+YG!8D7d;(wvrBa zxemBYy3(ieS%Ky8r!p`{afMB8A{bi}70}Djp%#rg~G-afKa$ z-QfrJ!IAV6$#R(>@3+ihd? ztELM>L8TVm`mSz3E4>z9UQT*H!QQ6G>-FIt^x>3dD)BAT=ng~P48e}$91VP->2rC& zCQ}zD@V3T_JA}LX>0`9rcYr%@PD-`9Ds&fabQ;|S|c2o5^;M&DNEMsT{_qu4pd zjYB;>8Q(=scHu~SNOf)5K{b-UypO2WmwXC-&1W;RRFdWRz!aVQIsvqQ;?LFIA6CxU z+->s(pJF}Ly7cIUzhr&#cuBs0tZn4QWd9&1e3$q1l&=Zy&s;wcpZw8t%&8dliFM9J z&N}%4{(sc9)UHna`_cmzBx&XkU60t z0YQkRAlCc|>w__x5yE*+4?Lo%VlKmPJz6x4*$CE#V)QtOx(gCAyy zZHHxtI+#xx7MirVBxYc(D6fny&i)3H7D6&{l^9HyA+sPGP@%eE4lS%*2U~TtVN{n> z^9LHVwiUXO$&SDYp5fa2*dCW3Qwo z3z@EIhzU8&a}TSKXQw6SC1yw46l-%%NzBELF>ExsrafLOXfkieKCMGSoe!8&rZ`-x z6Icvcx6R6rH!&8PE*5P3adE7v%IaE^UAtE0tZp+&lfB3{8fSo(g5{2RXEay0%>!xR z&@{+XE=UG*j>v#b`rRb+vQ{?{R!tZfl-lotnw5Kp1>+d*3I)Y3uM5KB_Fc_ zup(Ho%aYA213Zvy*yPFQ;D8@U*Ddq|guB4dBpWw+mDC64@PMQ0!rKv>m6p4;9S6r@ z(upBS2~_)Q)9Wz3jO%{!DlF8Hd}-#o>QJ z7AZF%gWt_^k_>x7hvdw4I703HxtRE&@QWY7q|xj`l4ft%mIyEoVn{TUMi4FC|8+8u zvs>=^^@6}ZaWv5WbzqvGS*k?pF6kK+nCNfOUt)FV>VewUgwO4 zjmV8q)#vK$6jlF@b#5*b~=axWoQi=)VMxG53@v#w-0J>oC>pvbbPkJOyb*27cDey?@B4AoVDp zjDCqF8*IW1-*8H-9Y%y_8yV@|n7qQHcl_o!GjrFu_Xahi=Gi^|u#}T~@rE_C;^~`n za>32F^8n4=GyA~YJWi+D9ZXpQkF;h6@g>nI%DdzVFQwV^uQpl+I8&5W##(c=u}))( zthXe4ijx(4)w%Y}cwxvCI@89weeJOpvVLud%vo)zA@x$B0!`U~VM$dKRaMcZNqI}K zq6SZ@7DsAMxTQ0)z?E5_STzqiW;He$Vm^__T$E3l_~m4Kj>Kg?eOloK>dK2NGw0<;-|y}Fkb z&=mg@a9z%IO{T3K{?j`>i*YnoLSZsGLLbfi zIPT?$8OAU(+^$#qR&KdX&-~T5Y~@dXJkZi+uELZ_`$rg-ma}+!o=)k!AYZ{N?VAZ- zUWUPx0oa0jvUbo+I!v(DV;cqVUWWIyA%S+(%n&BT%CQqG@Sf_&CIeVMs5k8xf2(V* z69z=f^hqoef^E=@$?udsCl0WFm-kH);JtS5YY^bQ=GRRLuzs6|wgs5ri|4k6-{)Q1 z157aV`=$t3e@KY~%fINEvrGW>M;^RlyE>VjC5QKRl2fXLK~45kek`u|{3eZg{@Cvc z^3yYvd}Q{p#MVHi))*#te6zbh(+AM=GcB#ck!{kEZGn2HawlxsL-?(toNWPq_DW2* zp{h}AO~vj~R{b_MJlo6dx3SIGH}X)?WNPC0fBW_nCM1CwPxlv>pbBY4+wD_jjj%D1B}C`CURi9lA!&bcWs;ptG`t85e?Las zPL4MZufC2@d%;Y7P#~g)S%Do$_fudDjj)eJK|UzsOI6L?Xs_-=;p6Dt2{FWjZNbQ& zpfO8%C4<{8A6aJ^VY8$Hfe#dEXia1^U22L*lbVxM&sg(Y>otkpJ4y&AC<(V_ozCKdU-BUfG~K-vl@=_RJG`>TWc>MBn~|QCUxTtnqMz zeXv(FM$N_nK7Wp2oHMVEX)(=seHy3UpND0&&5CkOQezE^$D-3mGBk@spR9q9t$C#x zawS@sOC3D@7kB%Al#sO*aGUYBeBQst%l|(m{LfIDWTg#DB>@zj1ri<^X&bDY7F}!0 zL=^5Of-= z?y4@cD;_>y-!HgbJXK(6dTO$E{}BnJt%Db1cPY{_yP6x*)$4o7r!e5rI(nkJ%$_cDSC^J@uX!686V*sSV!L~Lz7(k zq;cXdst%Yl&G{4!dg&8HeabKt)BDka-oKPwVd?FWM^WD!DT^}Okt9NOIS_bPj@6rQ z%IU5mjMOobnwq6VQMeXtA%A(OHa3PIi%Vvc9gkeLn2d`~txVzs37ejR7schhB<-o# zfV53odDi3Sz&AY}rylpXsKz~;kr zVloy?pk7TFnV6;R`)t_YJ#p{&EjhZjgf4W1m&694iQPh z2waM9$gBgZVjPP#QpZJNhgn?ATZ_&;462{2`Etb;*NALlSk&?pClw?EQlV^;%sq%N zj1!5iJCX48f_(AUw7+A%oug;*l`MdmW>0HrKXRc+j3-_;qTA11(Cyv-kreM}Fj3sG zKUx6LpQqY^2Q>rhTd~jXw0#Z4u=PwUZB(50`~)8ahp)3YD4rig5J(|$$}vDDMQ2kdVV7!s*}QsP zv#GjSQwuxsJz6wX*xRbfvbsq#*T$xDX?Etap zp!D1A23WXJUgwf%h?xoLs^V{GXk5rA3)uw}XvS5D#a5b9r4|O>SH8QH zl#moj?Na2wTk!q(QvjuM-m%zF1f3F(>2!^tGn9#GzecM~PM#dg$QoeRg3Fe!)CK{k29`-0RdDR z+B0Vw1D32V6m=*fE6J#rYhWA**nr_g{a)Qck9_6YS`@U>S%gxFEoLr{Sq_-xY}mn% zj3}N@W3kyb1l?bH;DQl^;phn5FPFxa=8Taw8xKjgEZF+$Qe~f3)=3!~IA>~82a{Wc z2!nin@2DM$~e;sjaKoz%h?c7b7NFsM^VgMf+4ptX!-!CvI16<8^2DYNq|E#FD*VV$(Pv zvcUvCuzDqpmDeCIw;%7EoSK9ydEnw4%YNG?J;9d^Y-UK#+lgG>!Bo#w_}$umBsj&u1P21<_}t4B4L+kFRrs!P?zcjf9~z+gVaO>Bq0YQ7=)*}TEE#Vi)FPUM!&_8wX zF7dH3DhDV7CrJ9>t{dZ)fxvSWYBm3p*b_{!e|rKRG}eq<=)-8YPGAOTteLg3^^C)F zTZAvACB^1d z#{KE@hCca~Vm#`s{aVE|A#{Q4X7R_>3Re|!70J=* z=Fz+&gUpA{(?+2`=AG`t_PIFqx0Xfk; zhmxB3`{cqHQb(c-|<5$C~7qS z)JT#6oiHh?Bvpp3HbQ*=-v_Y2DTFfXa{1t|q^M~ZM$O|GT~HZG+><0yLdl|B?f|P( zv1A?w;RMxfDLT5OGz*IcePz1Yf+!n-@PLb~K;X$>O#SPN&Ercm>$Nex>~V(f==}g$ zYQ#i)Jnoo@Use=Wabkp`R3bikOV(t^!eLQ6Tx-fpjO7Tt^UV+X)O(SnxYRXW{*5J~ zvF2zZn>!~Kdt)EFsmhdM0@jz`bb5t;%9!d^2oW-4=U90? z&8NN?I5RhgZSsq1fFLZIPJo;Tw=MyDvCr|4<&Mp%8V37;v$5IC?$jeS@@RAp%&b!P z{m0F{{U@a~MemtI#Qk@1KI2ImksNzv_Phbt!-4~LU&-PP)5bi`sL+oFae5e3*|03$ zj!AOM-`eK{MqMqQHca|zcoDXU+7nCBG!x_GB|kn7#w$bg<__seviO`=n1j8eaVlb2~^o|~OnA!Fp zHoe#m6#7d307*{?E9oqj%(M#|I1!Fbc3?mrRqj~P;Mq?uL7kPc!1ECRtX*0MIT5=Y zcieA69hj%+(15UuHAY$OU-Ef$w!KRu_F@ZUoybQTXi-B`oyf?3p&G!|5O-SJnOalo zNLq=ic67E)*o=lj`Qvmr*P!z4&)_ z_Z`X@yu(P?UU@(C@Yyl>CKm|10lPQEmWed7Ngde^ES_`yy|C@pLd_a~#vy0=)a3``-y(!QTu|+dA-BKyCHJCqRf{We zz6$%n@SLYu+*LQedG*6O{vJM*z>(a6W&Q!hP!CjTjv?ZFh5ahf``JuK|8@n?Y6YY| zQKMX(?Xhd;TgZMj@LiijiX^0ys|qr|a`P`>oX0(mkFzrPfiiGz+jTmMI^N&wp6;hD z%mt?tBg%zi=rg~n`Av({S*bj^$WZv~A7i~@83!3e7O*5rHoRh3+cja-D-QC=uoE`z za2Tt*W|EpJb`oIG^ofc!Y$BFjR*{ww{ zmx)h&R}KXub4D&QlY%*vH%I+BUitrCe5}57^re4jIF)ZUb0-|&7`+8deE*ni=M8H3 zqX#%Dtnm;Z^V>8Pz6{jxn^ob7j8frJLTmL)O%<3@qi^_Q}Sc&S#`!r$H z$f%ygk!yHgdAFu%`Rk80alE%9V&41QRt!A&o&z}&pmwVKB<9^iLg7t-+D}Z+rcJf8osffitNfQHQNiRxAa-&t@|Kh6<5Oa}sdDvJm;Z72(OJrK-(gZPp{U!Kg5atC{ z-SYl8emKwI-(NYSc2qf7@+a(s;22d!t+ME+CQ~a1uJ#J}0Xu|=Q`P;Cv{)ojUnt|6 zYP8#`SdL|8RKi+QTkLbLa&OPO6csFcBI^Pk!U-XI!l0i>5t7Oy^Cdo3DdJ1)l?&zM z=McrTE$H$2w$17ZmdmJqfEsz_N!?0{PaON<=<)MP4lU~QkS`ojP|hrRzX@CIC*?FS zkzDt3PP!NOsT%eD&~o)k71`x{^^N!f2K=<=KOH6`0G}o`IT-rSk26|5ywuYa=)+>^ zk`0`*N9ZAY9;qCfzRFI3qR=$Cm)O}8p(CN6Ch(fy=%MybHr>5z60!7zT49tAnf{kJ z#x*r!7>lUe9i&q70NX+Qjc*|>{-bL=wC&*@_?$AHT#MAlEJ4&kDXI=u^mF^N`SO`E zXz?<-Gmx4Jmo25_k4=+fMT8dVIf0(`X!Shtyh&yLdSG!OXzMmXg#hZhxdF2TCb?J@ zu4ph5Vnw}-FdD01z>+EoWN|KI+PM-&LA7nRWyVE)LE*%+mVsJIfujD)FQsJ;6+4Y_ zs9MAJ#dTs3L6cx0{FPQIk51p8;Wy5W3Z;070@<7}>K2t-Ti;THLXx(}*GCiSK0XIo zd`dQia>mN_j7|Et={0$Kw8cE;IMkUtION$V;J>$edUCGqy9WkaR6Qt4hZUTe5=XD@ zi?ZqNM$S`C)J=Eu4eSep0vN>}{H3~eY#3+7Mu2a= zYeRl~WDwyZI6bwl(A4<6m`$9yAs~7Gr1F}RDGcd{DJokyo0udI5tKAu%xHM|yK)H~ z!u>uh184-n$pK&_DlP)N5>_S>!AqoL1R@$WB&7=HYG(t?P1h$+v3b;+_+l~F=m`8F z^aw-kP4bd_wJ>5K2yR@|xk@J1MOA#(Ld5qLz+Lw{i7RdTqSP@N2#S~AG0|(K6z|zx z1>PIiPK@)E^b^$D{o;9i){ZdNLM$X_)%5phHp%#l1|{eIDW-`Dy9ah+cF@AR^AUK1=<)?I$j@Q40OAaHRhhIK?tMnJuHdj(;>y`mx{cP0 zHRr}ss}p^pKAJX%=%uTTlcqk}HfPVzP!lafd!S)V^dA>WS_l{lwrns&uF)l%ach@g zDu6%Pp}saGG3^TV?-m)>Wp@feeB*c;lEj`> zu=s_y9_Sto$LP6~!nZ+>pwZ2t#T*j_7>ZdvDa1Mgjk$!gt19vopsw{rH(p)WLC>JM zep&nl$(imt#h3JDFpxX>>tR)v`o@Sl>Z8L#RqW9u53cy-E6 zo%K9NaB8*}P1u?ERB%(&bSmGx#&zJ{310(G88gJP7H$=l=~(Lh!?H&b9v1f($vWgT zz7Qi;S*|SfnSSso+OEeB*EOy)K1aeqeI&~Vf#?oLZJaJ56O18~Wz~=dXeRf!TTRJD z{_qC9ArlP~WF2L4#_9=MvJiH!sezqtiPzdwHAo60W-;15a57~O{9 z`oGq_xP|Lf$xgALPc^)${M`xy;y7uCnQtJ5z_el5zc|h?o1AP5tC%|RuIr(7u1lQX z1gPxAuR9Mr^^g=LihJZ?1w??3M89sE6KPk4>v;B&6>NY{^fnf^vfRr%@vk2y~ zf+)-?We2{2G6;aicLoynZMOMl?g4TU^&uhq#3@s87;v#9#n7c3`hs62CId$mpHuPzc<0tb+CCuJ9! zxkP5-M10&2AzlXxjE6Fo`3(F#;T!hs-|N+V%0RQ&t}nL?zu%yR@+@>n^iU4`>o0|( zFu$+itvmkA!gEFJwUE{o7E4WZxUdJR(6N%VyGCW9KdYyjyGz!uorDyd=EFM$TD6yrQEtC(a+fR%9GHnd%_q(=^253RV{_6 zyHEM;(nGEv*G4u_2Fq^F!J_v*f8k9vdBWWv5DD=-zCK0_(Qc2yK#A#8SBI^I^CA5- z_qdHZJH3nf5g91OCCmRd{qBi?Bmt7k)&7AbYd`l+xfSF<_F1+ zX`EAx<+MujF5@-vq)ztk}OyLACE$%=Kn z11n@Nol*STa#5wl<@V^6)K;n;cP-xG&#m4rXg>Epcdl7`N-uv?W*!Q__Tmwdvq05C zW6Isi-l7xi7Kpv(e!L?X6s%m)yZ*jI`?xLa&OU&Dn%mz8Q`ipqI)Lxy9)X1Y0#)CD zP>3~)?_Emr*pg5Pbai$vA_A?tZMyq+66u4l_=eyx@3mX>qY(4yNcgM60YI2}nZ@&~ zi}~~I=l7d%-3l-JK%dshNQd9Xb=KRk#0>_n*at5+eKic?r#=y%gyskFfWL?W6xv5G z-D?)Y_trsY=y43prR{qIq-k^+7nX z^$@UZ8LV4~&Tz^FGrovgbL6f55m$JH0`K26{NsyfR=L7;`QMmn3pc+RdS)dSp!tx~ zl4&Gc;_qKAbEn2`@daXiyJ2eoX(}9y_+T*ZWibnmQ{D>e1LE$bKHzJW*;BUR)nh9h4pF z4SGgEACWvNpVySX4;jMt?In<&x!|}@(+5Du@UPvHUGj<|XI=3pmBvu7J(m6=N#G%K z0q?b9L2g`akM8j|UckoWzp@Wdd*_@mZk%;zv3Ttd8F`-WN@Ag3SpEsCbR2N^ia2u` zM0W=3W&yTNTQ=r~|AKul)-qvtEi&w$Zk4#SJv`Z1{v#t`Pma$OLQ1=aJ!GO9`^)wX z?}o^UKQ{E?@P!N_#ccW#{~aa0|L?ri_X{b@GTws#N9Hfjxrhqv9@x2PQR;`gWt|7g zBSm={MaFr5wN!vOWageE6_$Ba`IJ)?iz?FF)!|+RAjUd!6X}mTve)xGUrNJr`8Yu?z z*oE`&=-{{N&1BT`;U}?CH=>@4X{quf>R7j3O(P3aUjk*?4QREV*(*2E1+{nAR;8Fk zJ6w1~!(vWaZy+peo_UjQ(%7zsP+lGXFuwu;H><&TvFeAi@Y=Zbi{-*E$2kQO|K7rHN7;UkR8TvsTL81_1KxpXV%g_GE)^# zko=`Bu-6D+C&K-u?fr7^ULiAQ7#H~bA}U|Zcv1}t%sy~)0Ci==r?EzIZsqqarFSSA zSX93mYGIm|PuRCr&fy!wIu)-LUQo*8F8$*uHj+^Iv2qSS1^+8#C_I5X6!af!rtv?e zu>XS$l4XYx_Q-H&828W=cW zq9Xa;!GgV^)D`d=C>i}Ni6&Q!E%hIi>IWJ0&CTdTX*s+e$JyT3Juc6)I|hBAvcx#S z61%->t1A!PxdKeh&1&PCM6P!KpydwtS~9b?c<#&>5PN8ryi1G}_toGu8G2pUlUb$Z8VyO81hRK`r>A5M-=(%qzS zrfy5MIfN2eFiwmYlz8>7z@H)u=ZbT|^+Gm-Q#cd*UHnD2;yaU_!qv^WTl4Uxn|a*6 zGXYlc2;{X1wCvRHp-sxu(Ew9>_n1YjjbyJ+dq}F__^Zsr2;;XJ_nsZBjrjg!c#r@~ z+h!%F%&Vw09^2gnPX2&9qt-0q0Za&vE~F1*#$^uia9Np8fWZb z2%D`xBrq`#kGSfQ<{T#IBI$*@3Mp6(KSs&SO|imC9u)`hkJlXd^EjPx0`xI&l?5zx z|NbC^Z;m$bk!LW_ZKQ*fWuqBMu|@5mOHeRfjrk7o9i>qlWI5zg$KV^o<^Aln+05q* zwV8s}&pwQojqc~*n06>Pz+Rb~FJ{Lho^{SG{tII)+|NTP=fgb_{xksDV|*bD^Pwo` zoxv-Gg|N*rt4fIT)671`((_ouKmW=mgl?DTMi1njc2^&YDkzOwmI77row|~SdW9*}h3bohmO)I))} z1JBbj&}yv#)tod=S~FgZ)`^6Qt! zOpYnVUSlW-Xuvp$Rzx5Pl$Zz%_7s>DND#byA}j(0tCRWQzJ6P)eT#ZczH*DU?z?C` z8XMfYwv*j5!@7D6kO5fvuWEhd`#sm&f<=m=e0E15=VsHp^;u{3IVa=x;hS)sl0-uD zRexR@304A__S*GPg9m0-vnQ$ZJE_mss-Co-2JV0@R$N#y zNXe09_mxh>dVZb-q^~hhYcthT6AeODs~NVhuGC#t+*-Qq22^V5?#vxFOE~=&RU1i+ z9AQ_Rq3x=yZS<3J+hRF!Qr7$I)aGNXsjarGtgX}0P*PFpD+TEJxw>tgM`oUrU*KlZ zWNtz>;$>ZA(#Sg#QjkGC=nT2WXmwQfRv7CoOQoo($t1#au-BDqYv^og>ddQp2Hx8r zMn+PwDOB3qTDxjlR#xgM?I_OAMPI3_va=OdRn|&H)D=`V_^FASr6d|*(5f%BZi?v2OYm>J|yK6Vu;T$w0wULimO*fcTFY+v;>Xxz3raH;n^wJ;X zsCUq#Wdj>p54meXT4i0eqiiz{n=v<>!xy!UCrxoc2bLj313Ir~QiX~qb{0_bQ$ln; z393F5e&%hZWsKn-H;yD)>!eP&GGTB02o8{|;7$(_W!dge6|(U_h^nT=w(U268nxt7 zZS8L8ttCPI>!8QJVha!|_y=L)CD0 zNAtEk`^WjTviO^BDGV0gj>rl#F8TYtgro z5w!Tpy0$=brF!a>t~a1zSBmBBhis~FA-KMb{Z33keN1tWNx=B=zucXqx91>&~$;JF8%Wd=L z1&yN(NO?jvv9~Ry#0%o%Oc*E)QBXj#j=l;;P1DhzdVgr+2yhk89nD|dwMvPiDve4} z^&w|2(IRy2LQmKZXooQJR})24@*7H(Im&{OKEo#b08plp-r1SQ7tPf*AJM#GPGJt# zAdQsooDW*pzT4?Aq}lw~??r!J4w>|IrVliyTObG=OCPCgJL+-<--pDkgH>_R_2t&s zv7d}_Mw`hQ{=E*i$uMm`+3|pckBZWsYQr9*Q`8_t`P@E|sxwWv$Iv7Zn*Pl}1yLsS9SrHm z{(CyRB~7`OuSDz5l*GomVs-0Va+A*Bxj!nbsEGD(uD0Z%JF9nz*+)q`prl<{gFf$- z^mP+ADAC3!{#5I+qWHqC*OO8fb6Lb<_fSu^h#q!!aPNn5n&3myYA{J)N`Ws)^bUZ$ zMP7fSPVih3uPBnYszksy@}!44t?pGyA90-g^yK+qL&@H?qRw(EPzX!Gw643Vm}^@8 z3R@58(ON9~!s}d9K(Q2JGh{dLl<%^s;p!U939Zce4qd1sSWfNx{fmQhsdKqN?km<% z=X{@P&7=k|QN@t-OTBFGuLMvcgQjdA(-tG3qG)8tOPoD1d8%Bg+KG<_ z_Xx%rJ0x3**k5t-ufOYCyPe4`9aj#ebvTCo8Vs_mO?^1}{523Ll>CTHqF_qfq&TME zKxnQ|!(HBB7_#81&YfIi`0+tJMzpEQFy3syW0k(;L`;irTK&8#}wGTCW8dn=?kck;Iej~y9qfFv*KB;?SNDf@C&DOJWJ zdD$wB0YM}i3N$p}5Zg9?fSZ6+G7cWj=A)ohl4~`TUDjglk1%}Wk}LaSmHE$B@=$lN z!K^?k*hy<}J7IrP`MUn-bNR!ad7R^z8YGn_!*?}Gb~W}TwWaE+>N=CX4kSt@V{d1f zN^>=`_Wm+BC+W-uzVG&rgQkD;p~p(p)l;lLP0O}wP<>V|3PmPxP&NEq_<7kBA{t#^ zErUcGAUCq-H0LTVdqP#2si`xw>Jk-2J=Xdp?db%#)~OJND8Vdw6^!|}^JRdB!l+Js zv3MS!`WW-{OlXsY@jUy$YN)MScjaxRnB-5W{MKb-wFuv?j|8gK%#0^RoN;QoB7nNg zGE4SCPAQ?a&Kg1fi32WO8k_Qqav={kDoy0t?N=sM~zM-2Wk5FYHRI*2a*4{NPTekql6fa8NCMN+t=jg*@2NjKrwk@%z-NN9NIX8wI^pzN1*D%4r zMRi4M^(JsXU~PQ8g; zIlwws)zh#?po@GfShxMR)OQri&l`CH6SJm*->optmIYJ)X9f2XO%UjvCh z3+zaK<@B-kXE9lXB~T)x7r`a2-K?H#1JjGF;PfuFQDDag<8u}C;)E&4HVv!nth?|i zKL&mPvyvlAor44y#!(r9`{R^#3qJ6AS9elpr|(5U66y2ieEOhE*zI5rC5E;VfI@yc zTtB8IGIJel;Y&-@Q5Nl5-+DU<((xhb3cN)8D0Q^BOgpo8ZSyN0v1rk6!F8@wJ$ObG z#o+f{Jf;xKOyCz%me1`Et5Uw^sx<}f&wcuaFn^)UAdeOXAiZorBi+5*K8l9GIdSFi zSGbY8z$3*n`;JsBeYURK0S`v0A=8zSSI;Fb|2k3D4yN(9uG{E4x2yP=g@9${BqGWG zX*IzhoG})#cmOH0yhvhh4VW+OzO9g8CSBT^-%~4x979f?+rKu1p25Hc9JIbwc!BZS z?SH!azW?cpDqb#)V2i6z(^8yKY4y@(!N~#RQu#1U)0Rkde%XPYN*OD zDL$fV_WZ{OhBw4V&f2-zBkwQQM>t=fKR}J9XLg-W{hrvxROm@4e=2mLXdX7BFk%FI zw{7uhI*)O%x;Jp=`K8D6E)(jF-U7d|xRu7`yk#Bz$FyG~>`Q^IcNKk^tj64BABZWH zUJ_DL19wMO@wX&78q-m2qlw|!5jSh+H{A|1mRB&W#JA$4HL=9z5TX>(a-U!``G@sJ zA#bna>O@&Xl-P2sFO;oss=iQ3h~l(HM~?;82Z55TeVclOg^T`g?@b3ouLJ1*qrmTf z)9y{4qI-nX^)iga9e|^UL{^3cn2H}l0o{laei6*rX~7Ng&+@S;seD%3oQj@L@L1Ah zCCH%tMH3$Q(b^{H)tC6%q4rzm z9C%7cgxnRhplbITg*XL3oDo^ihih&PrS%dbA)$+GJlx`;r2s$9X<~0Ok!xJgOf7a% zcCPh>&v7B?XG5qX*CU+tnN@49e7#8y9`-|t{vgPJEZNq={-WgVShKQ=xg8}q{ZTs^pd6g0BUB?q>l!_si`Nc((l+U(+koE z-MZYM4?elww#NjDPb7~K%&;K>Q2+6=1b_u(YqPs+5^r8^ovHL9RJFtYJd{6rR+=d2 zkMHVo?`;~rSU&L~hS(39v`tw4_XnrB=%6;b4mZCp!BvzJ$GEmflFl(l3rRi0CfH0b zW);RU-YLyIeK3wL$8IF9D_<|_DXKML;mqgPJ;~lltyZ7VV&NhAGDPm$nw$8?!mI3q zZe|Yl1aakR02M;<9*XCmagFsxg{_PlyhoZkd$6PkG8TNX`EF`#*f1U^-E}W^Uw71| zRr+#8(Jv%mT)A561J0mSxTqNhwUi}}HC_)8NO`Y{V^pi6Guw|($RIGym;lh$f_Z=7 z!Ec;FzZdop18g&7`QkEg+ffH&SsrLD#-an2*wC}RTB_pWt@FeW@s=~38|Ki1p9YSh zbf9q-u8{oMjyL%r)-63PepW4UnMN+?k0U2!yz^}7`Qi!_Cv`H+KA*8R{Nodtd7>tI zj%)aOsZwy*Pm9y(iWakPcvPpzIu6C<^1Kj|v_M2R9>X)iHK70C2T?`J%LXL zBQ+>se|ZQ2$)E`)XOhqB#b&?=au6vAr>qZ^vHNthw)-%QxfeiF`Lnr!b1h!6dAyi* zFfeb1v(~c!)W}Ez;A7QyR|SMR4VBdeuzEoLNH45z@O{(94|FpsS}59Tdxc9bx3yVG+qDO(9oaa9(4>335Vi7Cku+BK{sp|tCy{{2@PB1j zTj>nWFY!(_+umWaEp1tyTdGz2+g{|Ij^#8b3mDU!20W9THClcK`z=%<|Gc{PI03Fj z7;26dcD7VQPDq>DtQo6L-p4jSs=QeZ!webqdqU%ds{W+P^TWhnJe%~zooI6qj>1tC zffZ1I?fv5y8`2%xp&^N+>mp%fOVKo|5@0>2n6=H=IhDXFgdN@v9wE6{^P!tFM zbf+8>G0FL2AP>WL<&@l2X#HZ9i+;vewO*>)8Eh8zl7D3Q{Kxfm=lsbjeUtMLv8Ijt zZ18~0eNE`s?Qr3rp4~|hb_-Sdc*87Z?+^#2xg_?Hm6o0dXZ7{d9AGGlXBc-J#*AhY zT1mh(ya*=qbnaiKijDX~yuE2~bCDPN)4##U)TQ-H)*s27?sWn7#d;=UZ%CCgbu87U z20_1u?z^xMdYAO;N%a=oXg+SULVz|4IaY13f^MTVRObUl4x8LGQg&(@@MDIZsk*>W z$E>y@aE6~9zm*h+#M4YS?O6YLayz}u$V=EZ^&1HsJ#EW@?*qR^`Z6Y(`~(|{I<*rBBZ<`%Fb+8a(?jXf9Y7qkpULT)JD z)F}F~!25&#Es>vsgyoo^Vj<|`#?&d&8Kg3YmQ&h4C+EDuwpEMV$hIBDKxfRPmRy7* zc#Fy<U_;FKGyy1|FiDo&cjoTeVIZJC_Oa4{jN~-Kew-2|bNwyGu>T z+rG7Dx!R_0GJG%LldnhD`FseSKY|#TgD7}{_U|48KGQP3GN_}HO^1&n+jaS2t~{pZ zK6(pQ9>-gSi|jdyQtQ9HB`jhmr#dmQ$IQI?zcoAPe_tWtOyhJNJ#9I=#$9fj0lNw% zt{I*?=6v{_iPYCq;Cdw7%S0@`ez;h;#(fxTD9f6mtNcwj$jTUrNMPh;4MXPNYqL@k zV|q#nDA!jIT#{yeK>i$g8e976yL8^bX=W%J`zi3{;Tl$u^QIH3U*o{x8s@h!SN0%?_&En4ZW+~9 zK}6aY)ZJ!&k&4Jm{!d02(NB4wlKejz#i0M<@IU}v89{yhj+4?pK zRgn7c|1v?i|Ha{dxc>7(gZ^6=|NQ?RjA&{1zhv`2lKYnuSNONCf+_zy3n{XQW9j{o;y|L4xDIzs#Z6<$n$_5XW# zrjE*WDw~9)+{nuZHpitvl6(wUKfHG9G*qoP*Wch=8{xlR5KNm0urUTV>a(f!c9}@h z?koVP;AvThgllw8Yhd!Ti57>po_aG09!GqqZ$2s1SmpQ~iUcHB6=%*3G>I}xJ{_v` zDGrq>&KW#vwTf5HB|Iv%$|r#3bLH38w^rRE`&64{6jcjWv2?Zlun>=xglw~ z1S@?~+cfaSP`yMi|C}Ysyk%x)oR*6}rV(#fV;TEaD>jvHKTZrds1E!89of6rX~!?+J%Qdbee!7Qykw zNxC$tZDMPPjXkP49s~;p`4gmU;8Fckv9IWhZG4hbnLgsZAY-EnD<6u1qKpWP6*q*O zCQ6P{m&i|}5*W3DML0(-f=oDxbXm&oIUmyX)M*KF?~(_n{U0eP?UM@4mj6u>Fg+$$Wgr>sGK%m zHksq$u9eS8OUQCclHILNRN78#=i#qi&$d$8O6$Ox&}j7>aktX7TV)vXI=VV0bQ|^K zb59?O`-{D85PVXrCsnX4g(R>ek@5*Dy&I=!!WPMJ*tg24`{ zpM<=VMbTkR@nMoWr3k5940q)CYd9o-*}B!prvRLM;w9poX6SdRDvo=LZ0g!*5M4FD zny-u=;!BC)#|A^vzm-ls3Ol~OxafNms$(>hh%DyRz$@~ql_hlHwUwn*0b(?1mnAo+ z$1OXSLJa|{870oA@~r1Ye5Tq8K2pXZ7&C~F#3J{Ha-Ani+Y&xjMi)g3B`bZXNNzWq zjx?2<@%#NDbYJX8Q1PwhqU*I;hH+QpT8pezvGlzwrRQsBye{{W-tDB{1UG1Q;B<0J zB;l=K!X?ra`-&MAl_jz{R1#I%TGi^3h=V#w*2!+xh?h62+%h?#;N!^eHUq?qG@O-x zHfuThk%C|lEQ(k49h4z^YT;JB<}{IXkTVpg)fq3>z-hZh_z^%YBx8b|emjVNi)&Rp z6^sb_fA)56AxbeCAq>fu(L5iPe~!dYx;KomVc>z9m1pi#7KiU&sl~AmEnlxz`7IP7 zU8*aLF0+oj`0IXV2R>iodtpyKj3g&`<_a{(?JfV@90~M}4ziI|#On9zrARp^2|q<8 z4J0M_BZcCM>z-o8tv(JEIPk+X{{(2J9^Vw{ZrtzjU(Gl*=(~hQV4tj0bi}fDwBFjR zi`02#v_5ULd$rVR^aw9{vDSWRUQ&Ze2_h-zc?BZ9Ecd zZ29_-N4LRkT+3f;MX#<+E{DFNF@#M#b{`4&&kZJW{hP*M*|P5p4)|}_Pkxr#AVw*s zaim#XXQdfU2PN9vvAFQNU?&kb?TMBAn672#HIo;4=3l3Yuu;%`$KOhOTI|8`YcJ>jp36!qed*JmWVt)EhhBN6^BOS7b~D+*mK#!oH$h`#^KDmj>& zvT=K@|L7B`>Ooo3se|lN(z)>xAnw&6xiPBQN;)n1d${bJb%j)$SnO@#Fwxk>Cx#Z3 z(lYnjD(YhI%{y_gW2KW5_BRA{)e7hnBGp+Ob=mzPS@?ukvQ0x$0_lPkyZ=HO>er5k zYIrt~#l-^2Dr@A&O*%VxF$Yw-*e9Cu`wt-jVX7}a$nhz%_zWq$th4p><2vj`kTa(M zHh*%Rg#*;qUmYWl!M?nx{9y>NUrgHq7bq+uamjo+q>x_KQ_E<@x+fFH{7Tl3s#Z&3 zB}_}%rsdrKNZ>VkGW}zZSPq3}c|&s+|K_reagWgmJfa74Ug&4@yv=#P!z&X-(EYXC z&0s8g2u$`JBY!41Io8Qw0mKMr3M%0?-w+(bqa?f;7mW|$I{;QWXHDogsf+GeC}u0z ze*krDD<(Q}bp*e?opfhcW1}UvnUPY8kVSveU%Qa%)$c4quRjN~hf#FmNH`%&?Lh_#8%51>ciCt;sZLh?}(8-6tyNwfS#BH6K!B+qVs>Pnwo z_2@Uw2mHciZeWv`jlCGkaNoZiT~zV`(4FP!ofc*2p<{@`jwO3@yEb(6o2S+fAb3Fs z#g?qfA@x6hiw#eTh%)M$gxaOyT4+Lsb<|~}|I%QA+>>o0@j0E-e?_>d@_JxlUHa?L z%M(x+`NA;5yH1Wg-88arBJ}%2x>Z2I`QepC*Z{=LfMlec?BvV=AmZDhdQNK^(yJ^F z+(}$i(t~IDLW#nOIe$9UZ6hXur-`U2p=+-4aalr z6y341$FIC4a}y9~7E*uzkPY&Soh!3wk5wz4oDxOU9K-|kGYW}<*}M=X#Af`YVlm0N zwGW+(otStlx{i1HOMllV(Kr8{gUs18uZV>=O#oieNSl^8^#sm>?~j98UQ(yOFS4i$ z+T2FF0Hyac_A)z;1xE7e#Hugql zEbp0mR$)oXjEv9GEpA&u!!k%`(m>uhSq#3_D<5vi@(mIm-&)XL2FN}P!34e=`$G&I zf@u;}vZ+9tq9g`1nnXBS0=S})Mi{Vrkmj|(5T^a_7MSVteJ-jIDz2j*NG7)S}z9YDF z&oza0EJ`a*7ddy9#$yB59`Sle99#{~yj=WWm{!hQpHCq2F4Njjc4@4B+rsJ!dL9rC zYR(THUJq{XD!SG!haw#=!xqyi2|y*5`Ao_%EeV+pb_4YQ4xJ>tLM>QVT;e$puNhuM}Kv^6HU3DeYGj?dSf|7}Un>0F6JaD(|}2 zg^__?-S+&H$wTTqp=xGZnzz@ZyyaD`Gle5>f|Xgac1MPjuSag#(qM9XZ=I+9v0Pr? z7VY%3CytY^pmQq`B2{r-sXFDgerH!!Z%XeECC#CY>b95G1g zD%C&Ae7o&=TVWpw_oy3wym?<`5&YAb`y*+1}wH~!-ch8d@GYmY&5O$nlZgq zi9hv)k+P5^uDp(W7{m5Vo&tW0yd9>Pn5BN9_Xte&qVN!2u5xyz0bRDLW&MG=*+t)r zMc-o^z3nA;bv;VXs|($|({Vb$%#U|j1)_`6#FlO73nIzb#{$__fkYhOn6mAsjC9Sc zvc1PK#adRDsYC56m=vk+R2xfzg(nEzfLxV35uI~uw%j}qXE+BwCmV4gE#0d16>OKY%iOdFHqis|NZED^^%M(au z(|A~MW+^8ur5(q_ zOm#JV{Xr?6O%iU!L_ANgBnk#O$<7s6`mcLPh$I9g@ChKhgsc`s80SPR zVV_fFHkySp`q4d=&3Qf{SU)j7Q9d`H*7!vtNJ|h2Moq4Ax1R4V@Acikzv}uvF#6?v z4D)3SlP*$R)R$?dCv_(tL^BKK*H=cD0!x-DArOX0FvK)^#i+ z;l&>CI06}k>b6sRh@{!_I;76dILB(1Mlf0Dt!(JuHSAcg+K}yR4|ujM%Vu_q zfTfzO50}Jb*!SG~* zQBY24*JHEG8E2&a{kLlDS?!CpnW~l2&#LcCkHiZ)Bt>o1g3}tNE$++d=Hceb8 z)+@T?Yz|aRL@3QR{S&`cu8^0ng*Yv*UZ(Zyh0b!!3IGjwKn!=txWlQ=jHoki5?VPV z4!DeIw>m#6!bTTD*BMvPdNXmGO^U5czq4D3FrrO_YK5)td19kbmSokuOXyT14*Jws zWZ`c6DdQ)=jwXu9i(p&!=pHG1c*`Du{dw)Q71^9#RA5Rx*Eu=NaH*a_`Wbit%^QME z>Jt}1|H9*u$QmMI%@g?!G047i=Tnl#$sFy#6jy=uQ*9Nl;>nRp=Q*n#85yRS2SQED z!GOJ9VmB7gkSkQ_QjMCIfhqHYg!wFgUfFVogs@EM8uXBde9t)SQJ6H>wOHf%X}Ft$ThC ztrob+VSH&YC5o;#KJqg&Jr*~$t^?&>EL1aaWcbZy>!D#j+w=9_2fCfdaRAMhh)WKX zyvaPshJLs2N-%iZ6qj?vHYb_N)uYKSO6wVI<)w?xD8{b7>OkgmN&pp_?|S7@NdT*@ z>32`hsNz^+gjxFGrD}he$ZLAU*k6d1$pT$>Y1-)_PcwAQWQ*NiKo zdooR!VsVj&E|rOSSgTtNiFLXLR}8D1DFIlj@9$=FI-bj;B}L%^hG{1fG9{fBDcDQ{ z`^-MxN}XwLJm40Kx4j8EJv0~5Bs+1o+=gG1=tI0ag($0A`cb0NdnFIh_198Z(;aIh5 zZ8;!9cU$E?4o&IJ@A%$?e1d&1+qP}nwr$(0e0h7V)!lFJ?!CX>KjAr! z@yzoY*FEPLpWsVbs{9`Y6<@LzkM}N-P0iT&7ks!jLy;d0K-iwZtPV(`J4roREBx7G z`>oNo=dxtp@3L%&-TA(pI{XBgm)3ak(9AWAm`5@|E;<8Sk{{ZgnRDxc=A8M>_3+e; z3`nm(^GOkMg$#iWk{NEj)Hk38Fxh4{pvyP;o(Qqjdk2WU_RQ=*rLasS6h4B7r`ZM#l+fRk)cmr}xoM4zPQMXSF?C zur0Tly@PXwOd3`OYhC_a?rX5p52^>Fe%f1qiHe$bxs_!^dA3z#X%o0^UWqn+pI`eL z(rrHMErhbiuPlrgZ`kr{ML z=SCIJiW#pubK(Npl6I1R;0(e`bjHK*MaU(*k)9$avp@V$A6dt%*A#T4FlK!uj`vlc z^ub8|YT^WPf4FG41H}$$hoyMKE65w)=1qY8_1XjB-RrL@RK12~y7Q5U6>SkYoYET2 zn4E2hoVl1X?^}qn@Bf0Vy#S9s0NhcqPal%Zu7LKUZ=vrhvW!zB0iR~JgFNWO2LA`D z*_Yt%op_c4iw(QmgK&Nn)TP$cEncv5+ao)baY3QVM=5~GoqEg$o z-zYO;yO^bDxjXawD=-2x3R!3{H|mMsRWAMHk}xA)-2VB&0)RW^4MDixb6s_KDrMZG zaq!2=QdehvB?2x{L-s9Qb|JDNqtx0_PU98mPsyd@ZQ%{gR&)vLF4><4zPz z){lYySBGy(LPP)fLG<6>2LGm{q?v=Gk@deg8L4dMf@p-~U6eo~CDKz9+K47=7Dpr3 zn};%Jy|Bc1`2D&9EP6Uqa{h-I zJ?_?X*Lvr)*Z2F1`{nNL50D*>k2AqYzs97@Ff(?kZIc1VacT8=^@{Bp1mi9Gx}ZzJ zN%k&>`E~6MB^DKw zS>I)=59BwIL!j?LE>RRE^zjgWq3n@_QC7wZnGi`wkZsln_uT3n+_|Uk$R+Veg(T%6v)8> zCzq>6aKu*0?ox_bD80yus3RCJp-~u;KzS&pi(>ZS+!hQottT`#t2GZQbdq<_6+o6o ziwps(29zsR^qbRn@(XhV5(Fw$Q1ynEsYW3aG?umeln^pksYMz;v!kwh-sSMq8L0`2 zToIafItBoaHAidAKtCrRwZpfPpO2L087`wbjy3l+A{mu;xJ-~(lDK8RGO549Dl4=zqFz|+|lddbAyVXl6 zw7;E$&;ec-jZHTW>b)h7>@d&(1v+q&9Hgl@lH01a=ep}cEFj?GHT!wd zj{{sjZPM1RTNDp?fphV=s|{>%w3xfcV_LXF+_H-l7o^eF32;K^DVlX}MpddpABx0Z zw+A_NQ{b1lyEPKH3!{rw6ksN9ttbXMHz^Y|M}Z1H0LWcEZ_iFBQEr7Qw&}oiiKL?D z?RG1StW#k*=Jd-ERp^uxJe5%2c)gD=TlTh~1YB0CId`Ntz;gr}d$mVz3eVf(M$}d#IKo-=4-YYl#Yhu|A#V?w!2q-+`Kq9)`_J|(V7BKlgzgnBdtj*DW5gYlg1A+LJy4-Pmy z$7kXCm#YY^&xhL)|ve}$IDU(ni|Pa-K$AoE2r zwGflTlQJV5Ys`_K3-_H-jzbAU%^;a~#>@Op54Bg3gX^%BlSQovgv@rm<=1MWa-vR_ z;d#;cfTnq7jhB>91B6XwXWV|y?3`wQ&lu(X`us!s+v;WMyGP9`h#gtUUff+hvIv^d zV1i<{HzRR|N@G!JJ{SWWniRQflHyI#(RHsNt;wq-ai;17eSU^vwjx&9a&jg=)K89! zD%Y6AI6HABw&Zu-L4)Z;<9=IZTD-XWCS@Vf6a5iVkOFf%YM6Aff zNC|*qzSu7~3u47!&Y>j1K6ms-Rs0GR^m5H}V05RLz()QcSa04n;+OD=^BV$|*PFNi z>S-~#A!AED-(p2hx2OW+xH9(gLM8C@{!sbF_@+^!i%U^1@_fHh7~`Dh+xoV>~R>P}S5KM<+5~#@sY=BLWE+{#_EzqLegOnvROvVrGj{_vC=_ zJ*DEnr;ju+XXVkl3%ftYL<{sA1cFCQ8@EW%FZf(ihZR5iT&0H2T?P9vcKK>A1UVK} z?vN@|>I=QX8y?0~LqUejPY8?X%Z(K4W$J}W(7_`UvE;En(H``4LyxFWC5F;h#F_~E zM_nm+xE%EzOI#{gvrf2UPM-I30*ZQL4arn~LmNS~Yytoh8Db5=&2yKUN@^*vX@^40 zYjDwwHJSzoC>6H6ISqe)hYX(yn)hnjEs`2QiKJQ+%BV55T`>`I2eu|L&UouvjzhG5gSfuj1Ek>@H!a$X@7e zpnZoZTy3sPlAnV{=hC65Ah$(2MC2kefg_Xh1vxFR)ow9UmgpEMmRNY4{KnY;Z*G}8 zS@t+tQ<@nnx1G{Zamz%T>Z_xA<4AGTyZGnysF!9$=(LfiFYPK*kvm7V`c?(Hljp6f zOyC|imTH>qDySgTOge+J0j$S-U1Y|O5Ap8}Q~%Gjvk3ZfceeEGxBy_>T)w%HbTcPD zL^B&Q35n*NP-j2o`(~)d5`=B+KfWah`x~wI;RhS9jrLa=CR1LC_f$ceaOG}V{l%aU z3jOaO(3j zOfhPT$LdaVJx%KIUVi%Yp{H|w{1SO2hCvmAq73E(3bt2xUku{Da7NX_oasZ2k35(+s;lgoz zt8MF->}GgG|4GzG-=Nz8mAfct`Uq#7g9`VD*bnT%9ln>0Ama&6{W`zA#S%IBe#@SI zgAwW(-d)22C(mp4$zkhB#8jifJy(DU6I-h+!WaRQZtzZqFe)Cck9^zVx(5VzJ;r`8cPW1@*|A-nd98X61ANLnV==tE@MeAr>8oiJcO z6@@@0kdcHzYy1>t*MlYi@=^^ah_u&uo@^dcRo-WEle|9xKG8q%t(HfjfN+yv(}LsU zy`Hp9E*qcOU(d6*zkbq%;4%;VY~%77q#G}4q<|j358u+5cZK_T2wJ4!SWu0RZ~Kxc zR&LNnIW#dxX$A~fs?lTtnh$uZ`P{*$zd<<$wP!jTDmpvT*s-B?ra#B+-eB5$p{c3E)TH={yKINEw&QXK`jxBGW zED9WpC`q9E7{vL8Uso4);p*}`)7;WhSV;GhBWgdO$JeC`dxZVEO3RI!F2w?+d6?xM z-S9Rw2*%eyqx^YGqYi5&t301Eu3qw5mxZo!*`do!?u;g5);5j(Qe0{Hn2j>0lQ~m% ziV6~In)<461R!Hr7#j5_$5U~|e%#tu%wcO{4bd<+YYYt}Jgk?YH}PlP zG!|~LXj2%0tuhJ`)3+$Fo3ZXP-sh-lzq;YsT3Z=<6_^o0A`hXo%a9~hF_M}f>jHD~ z!JJ0zrzYZBj}12CDJ+GDDJ<3V%EO6|#tsV1ACp}x`{hV^S}y_;m5g=+_k>Z#Zx#80 z34zZOlp}D`d&~GHoH2u4MG!W;$u*Ctkvw>YEczi+ZAJ9D3lzIs^-6!SF`fr@5tHVf zAKWx;^LIlWQ;TqwkoKZ~abPifqkBSj#dDvFe)Wk#p+}XDtONpKJ*EL|gXZ4|npT2- ziH{I%3vwqf+qt$CSG!B3MMalw@hX(9&y^u#9G}fsTf7vLdSw8!XK*btG(2)9@9(4% zz&cW0{?Qf0Qg=Gw;q{Peme_|gc2oPy>DlOtfO?xl-=?H4hi^r5c~6w z=&=H(Yio>D#r}Fnl9aK6lBWyzX4W6{Qf91i^Hs$TZmsVl+OGELdRwhBOvRkcig}c* z9BAWc8M_XfaM~_|a9+FainLy@t}Re(s}Gi)XYZ6&7epbYp9zIcA*`dM){3kS?G!Ih ztul$8OAy_LK$v7_z6c3j7#IMVeOODNqY&gX!Xx-uQ4j6%r6+{Rt}A-w&&_{1F>SQb zcZ$DHOiQpIKUn|!jgq99wUM5^q@J6NlcR!-v7>~Mo4$>ny`hkiqmjYCr*=rmVhJPt zNz+;Z1`!2I=X)7N23`)1f<$h=CRzqQ= zHmFoCnNu-0HtMh4>2{mLDx-a1`1&|;hlrmLeEK|Z^X7H!QT<-*)AbI}g9m}H2nMw# zO;d&XXsJC^-(;|2;m&2GF7G1$hUl?4xgv4Z;8|yS9z{>1mFgr22GMYqw7XISufrOd z;i&T_j7R5SC7(mzSaILrXMMPbzD!@a5yGd{*CbwL-CFOirxYYN+2YUsv+UB3o_JC- zt4$Olz-&4-C>^zg+6bGxvaaxTN!pT+76o`sAvl4#>W9pka9#-pGxa<+;>n5BrD9wo zwTikmSMEXZl_By=4|wQdJNcZ;MW2UBWx*UZL1^&q_hT z&T3(1rX5uS`*P9Q)1V4hkLP_O&K!vCf7wIv=BIeMvdyoLt=F{+1E@V?#w3!-a;tr!vG% z=;$g@RvS!aS8SUA+fYqxKXux)TSa&I{&ciGqzdqd2b_#jf1JQQh9E)L^!OTu$u#oi z{d&!|aX1Fy)I~Z!Ipt~isT5pt1dn*HQ93qs=umf|F+XYYkC~?2x|+bz3K*=>x8}DOSqUS$ z6&+o6(!x=?Sm=&A9<*d?Y3VIMJBixJY%v||-<3Q*)Xqp#nY#Xd4k;(1-X|&Fd1Ma9 zDjdO2EdS-a2Lug!E4mY4b(y^>xuxB#IE(U=#|fh@lonMifXSC z2D|JSTwui3qsFdR*1qKQ5Qrh0cw;86p5%xC+^HB>2$z()*TYn2^o~%c&ZFmv zh^sp6b71i!ym?^pUjb4ovqzyE%Mr+ip1Mv&@ zRx0d3*I+5N=D4L^+*EoOBf^G5q4U1_Q%19wiN|U_%qvzJLhO#h0{z}5^~UCJVHJ;e z1xE^YMf7}Ar3oPlF@*dp_$81c0{+Kym6IH{dqNt@S+-}advS2C;djiFCxb4cW^KuM z)cj-vzlcy_zcOOOE~DsMBNkjV63l$dJEyvMKE@$CU)V7v$sHV$*nXy^*uG)WeZ-C4 z;+F8~7`=Xz8sGO9jQf=VK<%5h&j^thU=Hs=0&fu%AA;y^-8~y)d2Gykx9!Un76bFn zD69S(j-`n0jxFGjL)dB;eq+m^0_D+9Vpxx;V?RcMm$x+6h%=x6)NJzCHXUqnll1Jn z)~xk=F+ujmn+^o zL>|d#HklFv6Co2?urJu?M=~j@R+JT1G+A(TQUot`5ZPx8tTb?G zg|t8mOVF&U);|*o4!lU}BTY{u8&k?sMhQR&sW+J~qOFqi$D9J;APuT(Ah1$j|J=N1Y zd?=8e!IDm>`>ZGl_!G|hb~KNLf-R;oqu{ZR=-0Yfmhuo`8|u86lm9k>!R z13jCa`Q0xa!jeT2oZ}deGf$=EeGFQjA-1VpQ=HKh9+nJVAvyMTf6lOzkz{<<{+g~V z+aCi-Rcg^<6v%NSnB=$14vQC|K(S`0-ivZ7RG+EsucUg1LS4Rj_otAH9vQPHmOgzb z$LQ!Gp=Ro=35vZirzt}aMT~Unb*3?gzmuuV6&b2wZbE)r-KO697ijDJu6M2!qeCY| z6Sebt?BaaDQ@#xUJ^{N-z%LSEvUn3zh#XL$I^+F0cd0?RpjA?J5<)0@o*Hog>Yn_8 ze29e@>tOlUlEV3W3hiOwqiOoi!vwC51u=~uHapa~TZ%QUk|h*dzcRolMsk_%_h|?4 zBrHQ2fz!p=Pna|ryl+ZMVjluxr$<5N(VUq`Erv;3)uI{_LR;EXoadvQ4I>rR=^VW2 z;y#TI8@00W@9jrYX`67{7J^At$xe4)?E)o}UvB&du@fXge~AbHY31%t<irhsO*Ea7N(%h)c0tq~{ZrK+=%e5paWG7f`K)Kc*3Qm9Mx|=QA4!x*IYkoR*K{anCo|~f zS)^M|TxA@n#pUp8Gi2maD7EbLR9(BxEjgG=61T(^co@C(G6fy{B{8h}7Fxk9)Qpid zjBS##z@Rq}35}&*S>Exq?ne`q_zeFjveeJ20~_cvIs9w z(X{hK%sMCV3`3AuWt;{+gG9&?xafo9>)8a~C$?`y%7~oScv0DbwK5bEax>p$3_$g1 zy3X82_bE^KIznU*^H@K^>V0yK1?X;}J}Vv2prUT*gKOC}sRprZm!EQQI;*xTx3=^( zp<4o6PSkv#u)y}m37`=543Ptngm89s2u4~=AinnlVDZ8ML8PV>k}}9e^Mj|^a26$R zwG#*iTX93g^{EW-Om%GhQI89{q(iBZNRKF3sRL4yljXsw`ihLNB?U%@=XxM4Sgc=a z2Y0c?Y=p;sh6o+MRI5SMJM&Ck!!R9QcEHUKK*6`jYs(DQe|LR8v_*OQw@5p))E^7aBhrSHeh`NOZ7Z; zwgR8Bhzbty7`Wf%wEpzgc3413-_LE|pZ)s#c0t1oCKKzs35)G}Uj834?f%INDLrdF zlmDnQi&R**p67$(UJu{^4b>)Kq3@s6johu_Kxz_O5N1L#2be8ae z3{7|CcgaIJ!u^oz~gz0y5Pb?#1d4n#&!IZskSFs&>qgZf&NW zdlv8B+>Z+uP*I1egF4p)Q5Oaf9#tG!@W@4m^~@@$4xr6b$VESz*Go`z25V$RY?9iQ zAw(~nMr$fd4yndwFyy3wbEDIAvID*cHng1#^goA6Edy6Q5thHm?%+gtW9AJ57Hlo{ z#KE=4PW@a-WfnqbF-fj$2r<x7CG?p!|8fVX z|L!0HP4bFWzcvUIX6d^ICeXIl7eX-Vy-UJYZlA@l+O=21hTQ0WsE@geeVGI}}$$Xn3tC z2gg=N^^diRcrGWs3_@&75>w!VMXmlU6selS1II`#ugntS8m3I{){9U!tu60L3h;hC zX~dl;(y09?%ND}eQg;ZZK?2Vros#%tG#S%4E3d&T=#}^2=e;fvAO!Ww8kruHafOuS zDj+eJP+}fq$?63MMuRbVKKL{NJ*LRC&EF+PDHfI31@YrY3G)9~w)S_4{WCOC1>6%$ z3H?i^YSXfqnu;5Yx-f7qL+Ur4xP0NdVLHv`X22u~J}^}L=Be@e|Ag*4_{l-ab{^vqu0rq*Y8K2*B?IH9``$(F55sm zhDKeW!VtOi-AI!tKSX3aL3 zPrz9SLQW7~TMq2wr;Q@uHhn5)Z1dY|nhHS;7cH>&-`HG&KYz&cQ>3ssd;x1}vKyC| zcV`%cCZ?{8{f#;tD^3K;%+p3-XU(3a=skm?!Q$v_I~ZC3Vy{+3wmGv(Or%5vYVRhp zKq1s9pMXRl>^Ouc@@*n+<_duCK9TL!DTN`wtPd^%G~#LxtmLs>T! z?h-!&`$S2GI`q!br{!2GMlo&9lsDwT>F1?28#()wRf2k5*xFIMNEa-$deE-xDM&X| z;8CmWtI`bWI6iaA-|DGR;wv&&+~77_mUEJ@5Ks^s$0CkFN?a^&PeNQ=M8YJ5o`nie zGDrvgb_w3x{5S}txty!J^~Y4922T$oD63|^Xg1G?;Zt4TBBa*C-dKQ&z_33pwqe4t z&R3hIfvvo`@Dg4GbauD#As}mu>WfDrzE~`T9D$v40#DWvPti8uP{WCG_9E^&rP?`tCH@ zwdvz_%skh<%n;_rwVp=Bm8-8AVHS4S$8uzA*kHlx?|=bf9tm13nDJ3CeQzMZ;l=Hp zG}%)`PUGR2uXW=)>@m#L8ZtCC(`QK}J4+24!RNQazR8q7AB~W8dR5rj8!VMs+5RZw z7F9kmE>J0YY7Mg5B9f+Cp=jGTC}X!2u7;;0W2MG945qf@8`Pine@|ne%?M%h%_S|^ z+eJ2Sz;4v>=}Y9&J}NeMy+bZa5qmHgMeegI>yDrgeSUt#N{jE4_RA8+_Qw;EEZmQI zEA5IAp?k=UHV=048-;tu7fE8ADR1ZqyZta1@W?M&em(pm=ifzMX0l*b&m}JaSBLby zrJZui^@zvl!QP7`b|VR9Q#ItX6-bP&xERgMV8z_dG&UXd?|H*#P{ilQ_HCHR?F)rNp8FT`k{>c9rVQaGa_w zCOyP9iJy513S$*6c1=lr5mnZ-x8fNn?=E?v+(JOD_9W;nAU91@QkYnQ*6x_Z-%qeQ z^COM9gGK%t=swY1nvhZqMvWCT@zx)641f8`-|NonaLB;RTg#ytTK-Z5mbXsVa}aG- zZ^#%)mM@?f6yTBB(7yY8T0kjOR2sX98L6pMbFLz_LVVYjBGEk*gP2O06!Sizpx{C7 z9>z7zpP$eG_v-vWV>kD~ek4$AvIkt+ zr_4q!5Q0CBq45*<&I-?#`6G&YP1@ZvNK4ecGKeen2Mx75;G>qt8~yc=#vAw*QS(Fm zu3XcT_|+U$N3d&Zu$tt%3P^^)CoJ5C=!*u`2jlg*cqXV&% znA1-BR64^YSaEh(hgbZ?gTP0{PJ?)p3*dOXdFPjv{3M2W0D;aV+nYs#mZ>+3B3qjE9!G6gWsx(MhPnA?>Ly*7E$xNY3JDYJb#GwjehZuY zakn8<^5RD5ftRX$J*djl+)J=&oASt+^M3x|Nvgd8awO0(T;(x>*)hG(F(NUB|CtCk zf@vP)d2H+zHEqjI3n^I^xuY#`qbEdmQm;2iwv(o}FGr`R^JUL*n)uVsoA%d}ooB8y zlnzG!a+FpY%4|E3%aUS3q=6@v3#%Ii7qP*Mcc6)4 zM;TcuS)rq&`VT=SmWid77-{W+F-^&1+Fo@{@nc#-s;U@(0SFi=keNVSaa*u6k(b&E z9aL|?TQTLawGX6a`s;A;+0KMS`D28Q;P=%L3$sT6u8||<8%C~!08fl;0TH>|%lJQu zVxKBv@8J+Oq?f4dPsm(cp{e7hauw!Chil>PJUH+N)*pEx$;C!`KJ62ST>>7-+M3heowJ9M`TG;I7YQb}oajG-bM_}VNb*Dh zRd=EeUA-aLd0vl{N%mNhdA1F0c~U8Iqg8lBviYTTO-p&PN;kuWp>_%{$w*xo#{xr_ z37r%QxqnGdaJCwt5~7)mZw#J1$$CdaMoW-V(>PI~AP)M({Xq^jSgp-;Q7@U}N2}b# zE=8OvD>d*79=K8F*jGe0E^t<-3Q4cYkJF|;{Uw%7bSf^U(zdYFvQXu?P(@o}yTo6T8Gg)us=cE! z8s36MYgf`CnbOr4U7!MD+$%SpiEgP;_5>IDhI^4s!41?F?A zy&?F!`;N|Lph;SFupe3&u_d9nk$3qKE=^K+0Ch~OQ=RqC8xF@)tsWoO!?Zt)6qz0A zC0)Je58gE!EEQb44zX<=CLs@-khl`EED|E?f|vxogXbxO+oc>jYYoC>1%rAIst!Ho z2r4kwtWCS(Hg40H?LVw&EDbg*Ipi;vjQFapvhfj{40RJiTeC#9@YjH@(5_0gf@+EI zdf$*FZHLWlYc=Z8ARgo2SOs+2q{7Ci#8iUDp)>|1km5x>lJwo<@wFbQI3a@ouraF0 z&dZ{x?8n-Q@03oWXJJ)qaWMlho)VRmNSSXyZlw^t?0jTt0K zRB%}p?$?_6L-e_Kk0=^XCvhV5HT%)}MFkq7z?C|TM|EXDe1k^s3kRPIU$;Wj=00^n zV-bz%1I?g?gXW0yA|qph<#O@^(1WTTo1yBDu|EMdi9vxJ%BJt3Adj_Qg+w96Le+&qSCa+$Rfbt2ns8EIG`+R^4n|ViJVl z+}mQuju-KMy!v7IyB6Z-M9ZUccb?>zc-JY9%FJ`9rm+ikF?oatm|ewe5Ndv5iNMbK z(EK7Fu-PDxAWf%hiR8TfLwDtT2Rzgt{Stt(UaXYeOf4@I2V- z6Vt0B?u12(YejlOq_RZF6$KuA`%?xywXdG7pMavFs5Zc;B8K^UYq6_iT-UJtr*?`% zxK2|G{SEf-?#`*8|Fro#6yNFlW842wr7it8Y5&9BWhz=ZASxkw(}=Y*by~%jBrZS% zR;5{r3wkaqQ$gn>T7@^Tpy=4JBpd3jR<^Sy@*cq24i)%M(CtHd+xBE1xL%R0h>sS; zrA~4`Z+K{D9cOs_`FKBm|1o9@g=N5o9S|9}0xzwQlz~?P+Md^dLiQYV4t5CArN$Ct zD7ua0xC7oTr(V685XC?@5wp3hZSmSw;ufc;%Dg$kB~o<>(1nT?p|zVD)z&ZTx@J|o zpG2YMHmJhTfsZAooWFL~6hSbX^IOe>Hxe4T&D*~!;)HTci6bAJdRbi@xQp6+j*v}# zA6GO`k84WERa=U!S@|r$VD?eVDJwS~7wll96<7LEG|l%GHWjG}EiN&KMx^HkFxYor z-96UeCpq;Y+ppfn2ZUi&757ww4$92EloR!gBT@h2m>wz-5E4Ox>P(rHD%xfBW($Um z3lts;(1GnFFs;sO^7uAPG-FVHx^cw@p_MymB=U}%bG@CVQT<}a-uT?M69`(69^kTp9)XlYq$Jtd9a;uU*b8rpO-AODA&1m`LeGg9d@dFL z5v8jt%_toT|K;Q!!NU{4&*qh*Hl16|h6_+##ZQ$U(A-ZTgL%JJ!PIjJY1`YJQ~f0;Ek+*NXkMd4JYOP}O4Il^e{i=d z0I43mV68(53Je>z#Q6-F-7o0%sd(zw?S+!X#ro2kB|Y?tDRc%e^sqt|eyLFb?e+XP zF%W{{)(b+%PzHYs(k+;G-vT(T$a20Fucy%-c0YHu$voMVIOmRsi_l2mKWWhtuMu*D>;%$OaDXbfiL9n#j${ZhP$Btg2`SBhgB zJqUk#Rn_^u8h#ICRDNBx<=<%a88F(OVzAPG?i}k(%HdjG7FY_iRgQv)O*OQB>Y=*! z9SbbBJ%N+N*`i48T$A^uT>c)ang;kG(BnObMWY7rGXgh%Oe?`oRnKO`l%O!BDju z(!OZ^g*DincC<&}2$O$-jlKSub32uBdo}y3>+^@~FC{_L{(xgvsjg|^ahAYijV%Dy zQUs2tY zfmRjmN+MyKZBQqTmyCveNl+0C^vj5)ltLao*!|qK<8(gfl8l8^akoPO!0uB<*Wfi4t8H%cKk5BpO@dXD-jI~t|hG*1Oot*e)2|_G8 zKJ0M_mX+{*I-Rar%xd>PZQlnOlmodsW=UO19J;W~m!(3*k1k>waa12Q+W5l_y7x^g zna`(lqYbtM(Fer_m|`QAxlYFQW6m!>f()9H)8ux(T%WTaJ=#Pdc6+&1G2>YL?7+>qiFQGbrGTH@U_XMXOfvVVSR2d_d(NOR&^o9 znC#-;)g6FrKEm*=ZZDa&Z*}hm9YKy_SE~^YZyzPmEp3(&R{op1Z_w-XBtV7$|E}(| zZ*^DuscqO{Y^+tTLJhvzePZU)ZjuNaB^Ofm7ei?jLjE?LzmWZ- z9V2tK7iIw2BBFJbeEQnO5ZDk?1OpVQ&^emQphXkZlOddG3Y&(yr%swpW(oPG3qeQ* zU9gy>85w;7Eu58Q09OPcwvi;GV`aB-3j6uV@eYL>T8ffamO%>d{n)giJmXyoXe1!H z3tR3w$JHJVGhqmo#7{?F3Di9f5neS;>&7{+xkP$Ho`!-&eO>0Dk08|7Bv;}@`8OF9 zw&D;`Lt3rzTR;ML!oDOE3s(WEQ2DuADwHzZS-Lakwb3Q!ZW7~h$Hr%(i)xy%3 za!;$#NP4|~-Eu}$%Cy9@_d&G+>FDB+UPb!*5Qg(6oY`b}7G&ncYpOlp;*ntW333q_ zLPYOFNtDc_4KZZt2UgJ6F@9@%a`xY}P4t(xZ~lw6JJOZ(lm1uQX8f17&1Ba3;JhSY zSbOdE#RFi7 z&B#=nPG{wOAM*M7d;`*jSAy1pLd@D`dZkCDUPsEZaUxD#ll1%@p=#*i5L%aQE< z{)Z!Jx6}Q0BuRgBB(eW+BwpW+Wc}NbVExmPV17FiDg+1a*fxO%(hd3z$aW|LF+RUX zijr03p4{Xv5+PD+^}UTbgWUl89KMdhL>6#Mt13g{oN4G4!-7(5;7_rF_0{{sO z(N;q6&86B1(uD{-gg%%PZ)NKNr^s)ouwh>KUO;Iu;%O!}`)}HgLVfM?CjHhnEec!p zx3+Dxc3lDBy=wZCOw3$`|I&6X4&-9ADcWP2gn^cmE8NPrw#WZJwaxOEC6Ucy7tZDK z2-A1FO4wlB_{8{!w&DE>Z+=r{TK4VW2km|8ah)9?ertO-H5(1T*GuG(+mm3?f~EG2v-Ly#}wWZ zswSBPYSz|J|Mhi_`Hjc-#qaMgPTyCi|8G3WKacH9B^?D!C8RGcgcSrDrUG@zSb57b zJ;8LAN8Uz=TqRR5)flkHZ6gOUlq9Wi51Je*O84FpF`fYvBYg^hUs@=SjWTg+C~YLjX+kzlkAbLWDQy_V^|M;!k; zvhvu?HA4h$A+_^_CC`D0l};OGUyR{maYa+%aVUgV3K>>F?Lm8y7Jj03;a+-ISO}%J zLEF)L)FpjJn?nM>CiyD$EIriEUhr{s)S)HIRQYz}wIZKPJ=#r{=BRmgtO>nQc=%@6 zotV)V2tlUn1S48BX$Mob+!j(ccX)*j^e7(NLGIC6TzeCC5LW468AK?N-T9eSad zJ<%ONL88ixY^szds->po!geec!Mq)~-;{mKi(TXqWiWbd+cbfSQD+Et7EM9mL2`P@ zTEkTFgVN4paaFtq5aXoX!^*f$Jhv4kLW@3`+=X~ zP{a+NmiM*{K~Pyr;JhL~3Zs=Ub>zZmZ977eN7_k0Uq6*IC7TtAb&#*(K59t5cgOx3 z(PFeMUUBvWe5@ST?#zdNFruj$HGsE=Dh|=oJP4T#8Y2vp!*&>NWRCW|qj3(NX00 z(lxD%@GPxpM|AlDwDwdbGy6#Ha!Z~ns(J?)TNfjXi)biJ9 zB9+oagD3-Ozc!nr4-g%vu%lcO_!r7KaA(UYG?1Bd*ZKKA+Yc5r1-F=#B%qsuJj9gz za6X~eYf2=YjkMpCiYt0^hSx}xU_zlWz7#8<=QoX860ZzloC)OoL#Edh_d1BVWZW?% zgK`ZR3enP9&1=x=zG}mnR;c4o(Fpra;2AUW$uV*lp{a3H{Lw;47tmnHpm%>iv64gY z{2oeo_ZN?%Q3uZ;ppAxa{^h|j7?4%EZ|9X4h5xCKEyj&rX`m|OyiA`*>T!m)7_W|P z@P;$xgYD{;)>Yes87ck22YHZ9t|Mx|6?5JKx78m+u3q?l=w+zTwk>8qYy9?z#P&Vdxh4e3+XBuE&8RAP0OJk7uymm6q)Ey|)vW z4=z$4+ek5FJU4ht7dc&VkJ_^T^c4Dsa(5|7rp4S~%m?(}he*pqy&tatKYqaczg)2R z&-)R^fA>fVtKSzakhtRu>@wO0pk;HA*5Hbz=H(G@M+kCjO61oFeBXF#i$@i&B$=Gw zbVP+jxo!YFk@lhxbIWLl;<#O|?58$A-lwN^e!Q{S%j%n2Fv7ehh#3MjX8Wobi_JIWcm@he|3MOUa83mEHrjw5yVltgvtC4|o? z1yG3<4Pqc}r-NFwB$&^US?CwIQW@}=jOW{&VQ2^gB(Hc=r%3HIdRh2{O%v$(bO;*b z8}0)Z?DzLiOI+e^DOr{q(t<5-8J4|LUmlXBu;XaQ0KZR+M(CZvItw8^-VpWBp`dI+ zhRWQ7^58ZU2BcZBU~-?`cp;*J!HFG7Zh*qkeb2YpknE7R}R z#trCOwNgGYH%!Q-{(@y4c#P^b>y%;GX_l#5$O)d?Q5ZMr&NC0&2`5^CB1_D1TQi-K zCiyOO!`?$-~>(l4G$`3}>rP)5ZJ@-PWYWs3a z6RKs(wsx-iGx1ttDw@D^A`>T5s9G!OFbEg%)W%7x^*D|`s9VC*`?UR=$*@VdB%@u@ zVsMV_pPUjc?HzHBQKM*%#B~Qaf^Sqmw2@Oa{dMdLF0JgwNpeE&;snZ|_FnTlAm$LI zL!s6ZdZRAiI||}55Tj!5p|0hn>OW}x8Rxk&m(9f7Gx^6`g*gF(!a*E0WjBm~VnLP- z@WNOIAJOS%s#+*PIA(B!!Bn6f^<(f8R@%00o0Yb0+qNnzZDXfx z+qP}nc4pO=Z=c)I_nznzU;o*$f9{AC>)CUSImejaHi*5|il!{t4ez-$Io=zs&iZM- zylsSF05+CzzGl&wrj^NP1()sj`x|6q!Gdkx>Etu#nm-!m#a(u`ICoK&D2VDH?~{4D;Rpc%))!l4XX@vr!Nx zP<=Dum*!^S_M7Po+`z{ofixHUflj(N*oW(so1EPM)Z6edRjJsZ{*+8L7nfXda_6n2 z{rAYSShgH1PM_`Ol4Gc0spJ*-^&Y=)hdvs7ANwa3_@59tVY*hfnflbA^`hzn59M+Z ztpU-I@>c$;7iH~~t^8l19wLUVWJA?)_Am+FjR?kN5BOnq`STO1tv4Ip-`hYRdzxiN zh@T3=F?@6VUIrMqw8OI18i$R}d4Fl>;F$}Yv4Tj2V$H&f&I!p=7#%K&Zc=xJhQntZ zxDHN*bJM3My1HceYT09G{9Rq{&gJugq62Kvz8m%%8LFBO<#Ue$4--Ci9)al1p z&8Hvp=Uo?kpd`Q!KF%-HSn3;e!@5AEy@tu)wZ!BP<{_<8dTIQC%C}76MxWx1LKkAc zO&b8o$G%$T#Yb6@2T*AADsdvOlH5Z1{roo_N@v~f;UC5#{68|5_5U!|)_#Ez(QngD zb|IMU!k`z^#uUqCOQUp(Co}{I?!=RSQ5MPNAIie~Ls>-+ z=1#=_McK@MD4SUG4`toIDeEEv;XM6K*;4#(%D(>>WoZ|3r5C@1u2ToShY|&J7rrTr zJ682B^-WpB*VR7=fc^k)bJ*nUm|&QY5C{l1nkp{`#hQXBHiU`RDFr)iivosZOc{pI zexJPo5k}Sz?)@<=j`?hi@d#V60XxSK!BngAGf@_-K)0UUhot&QSzf2xIKzs7-U0Mx zEH!em*eHnwPuh^F9$Ft}DEYs2>*OOaIu(pKA@AmVZ1Jyzwnr5!YY0~siVNEnlyhY& z1;+8wu9v%1qVzV=pN)vcvRT+di@J3h4ApDkAagG{dUuo&1Y5K8+u){;h`rc$V`F`tD(bL;Sxnmi2%4FfN=H#8CgB^Ps!2hdWZm3AAAoM+PEe zd%?(B;vwUrhVJjOKeoqXXh+5CNXjkvAECXIXZ1~^n!N*c0@*K|X-XQT_NFbf+;e?g zahdlxulYW|B=!JJ8fy;#hp>D6@XzhA|Fe&t3t zJ7gRWKZ96?Vl%@A1ACQRv>SEMVKEy{Kt(vCu45y4$M0WRLxdMxf zFiq6yISQZcU^EvBXda<)=NT!~f_GZw-L%RwW2%EAm?DN16MIfMW;ulKx%-k%{58GR z0(^L0iA%YLxU5-^(qeA!%{nMp-Z+^UUr~y~A4p{!@1`lNJH|-L9LDu~<0^BG#m%ec zQcXCTHhnl~zh^kQL#LQWy6L{gXi*qwHAU@hmdZrJsEj78|;V*M(WbLX4TQ;4d7!E4)n5?X4Wn=$_4I4$@2G=Fp_#wpEV&uGnSZ>=sEk4BV|J zd~ll=`O>>||7|QfH%9rht|B)B7Y!^LfoahpQj5R-VCW5ZxwcwL*Hi<~Q`bUFOfN0% z#5ShJAv7dY!nW0sIt4}HZ{duCtH1I=LJw~GeubRmrff{dIdtLgloy!fnqyaA?P|_) ziO>*F9krtpX{Ujv4LyNWd)*Manm$K_9VK5L25l-Iz_8|*Z4EtOLFx*%cMjf+pZM8W9W|F!43&>H3T`V>H@2HkDPnO;hwILp)hE zQ30pWrCXd0T&a7-1QX~d%Keqs5EH<5CY_J?I_#BCECCVo+Nj>wveDhYUE~xbZAzi< zQPV(lARw~;;C}gU#rD6hahHar2hI{2-%JW`0%c73=yz)J<|7@TrN_%Owde7 zp4D(+bVg%O8~HeKBUY)zYSi}GXmo5yX-g_yShC>SF-?t*pp=vp7kkTJKwGJ?1YZjT zbbR)#DR|mcTOfLQnJp`}2rl$H%tq^-k=_y7``UuC*l zjU=WxAYwud(Me^!Bo1QnqFU==b~0uVaLNW^#HR3=%MPj8W8}8LbJKM)>x{BnTE-S* zi@Cj@t!B^KR0TOa3v7O={y_1hnBtJ|i;1+7tA(NJuULZZzmA<@yiqgu6 z1Dt+>npNE9%SZ{LLHj6`EA55K8>nqEKE+%*trcj7d~V=9t_q8Z z<+A@_r$x-ozgb4n%*gP%*ymxRm#{iEXxwOqb*>#!tYt}LF1YC6;Zf5}X)ZB6FMl_3 z8xEgbSlJ)(p;d4Q5%9pCz;N9FWKETp_6hw;n1=fSx4?98ZGE>V1N>SWX7hOF#U0R~ zSh9jBb^Nsp@_Ykgz{?5UG68*aAqb8tgV$BRqx^6Hu60}oGsl~>!NOZ_ahjzE5 znO7*htjmx3PH9LA4I@w0K)CKUYhJ=PHgM^Ox$JLStOYje<#Eh69&YcBWjFg6duRhR z`uI1WGJ(eHERm{i@oU{0Bar>c=O{aSgUj_slX`h+9TLq=a?MM^NIP38X!i0`feHj& zT6sD{oDNuT1T-mjF!r+3ezRZB#Y3@+-J$|`>WNa)blR#mf^7&JmPVC@Fyz%Lb$A)R zr&)|^1!N8FQN_ji2vEfs1#5QeZ;KYG8!l*Fn4<`@mxxm_71J48Wk!%k35kV=&Kd?w zJo^o4znRUb&@8dOJq*9SSM=tZ-42SMr{Td;1fHPIy4>7_%lLB7Y~rO^v$TFrf%1o_kFCF5f{o z{tmoY`!mA*QoC($F-JeWL8aUy!_p+UrF2K+lLl(3!(krQLq^)O0e!3ixGOIm)2jwHxN0FYlu$jM4?gL0d*3^#p-66T# z+3u(U#bvRs=w2`C<Ci{e++YRN9UncN*3wVgN@ z3Tf8jv&Y_NMduvaEJ5#yV{9Np=4=`VoM!uS&3&%HaSBXBs_6M#dr3)WZpb@jQCxYe z!?oGt>(%o6H~hR(C~y2Z^(H|C>hS}VzDaz(^25ua9j?}?@ws0Okws^VC=z`{zs8wx z%VZiyR0(2-6<#h^1TKsPrJVkJ)QWsRAhOqHI`apbsP10Vs9|3)6SXyy@G^ ze(~4jV}FVx?DsY*b!n{K02$Ff>`o3*6sGO16{f#w@&`h1SkSN!$qpc>{lYLzmx~iabU!!CcKBUo`eKWb@*hArLvltD zzf=q!|KjEom&#L#Rn|aV-s9fFRl5Bt*3cZ30P5+lLF*)Cd^t?DMeB*z6+7c#9uOlh z*iE*aZ6ggxb<~-E1N73Bh@Je6vG+vsHpbS|LF~QYq}P1!iugH7Bg$njXZ*;B<~}w7 zDIayMvMhD_ZNeBqLs8A7v1OsXx?d=!D>G$o=god-fn2=zpfNS3Im*Z(uOAviKsmW` z-=-$>>%J|!uYpfe_)*?pkcLF>iQCY>@2D~=el&o~(1*)kLG)pYiod8R&1Xg&C6zgH z*U5i9V#&Exhupu}d7ZG(CcUTdM3RQ_0BUW#Epc0ki@qaB0$0Q(;$(r{XC1!_MgdQc z(+3m38$50Bn+4PQb~H3Kb{JO;x39b^HrE#Q!pJm_S*|H`99|?aHOoc(MAA*?`mz*I zOA>mGp4E&`i#q*xi=79Foz-rLIYLvMrhabNBE}6{$PA7Cv zIL#e`PO$&JmDaKd7u#6rb*`w`baZ(VbFFD1m1%h8VEpz_osx$rn42+C!vKSs0m4Y< z^dI*FzRBKWXiZ0s~8Cy%1JkK>iGg#qA#f!$#O=VUizpMz#K$+D6jBGc^WJ zhb*s1rrs>#m^cyK*w#**ylo}C0+1h)8^1ySAU1pifY{_M3|K+;TBVV_@N^Zy#_mH+FOM@= zt~~nMnO7u&8*kTE)>E{E2yaUW8<)}^Vht@YiB1P63BQU#ksEUgRmm%iD7)N?s;w|V z2&?Ov0}JED9Mc5MJ10rup7F?mNk}dSh61LOcF-3uD9*n&wZ*EayC=$(!`cf1-Yu(d zCvy6rOL2bhOzZ`xIf0Jcp9)Li|A{r`hv>FP{%n)`)Z2SdE$5Db&ZdhTvdJ6?q(x-{ zK-06L=~z&=&IaYQ{qr>pRj1Thx70wwFGhbhc&M6%pL-zIbtN5wi=>X0WICeYGQ{WT zcH&cWe^F@C8I-{ujw6IOK18uoDzr#^TM|EuN)p34FU&KI>bO9Owij3Nx2F+NKXFtM zF*A{KDjKi$@hb`LS?R$V?tbE`G*j%~qM!I`UiclU&f3u8yYKx-oM<1M^|_OFb0Q`u zC~L^X+FFON70EsHsC$LXH7)Z?+Fa9P7hrOJ9|T;Qf)g~BZOJL>iHYn^^&y#$afx() z$>hA4c8y{?WIf&Rz1w`ICicFwd(6f&k-9`&+04Sbp>&+JpW+%@A1eGWV`%SjcvP0-FmsW_U2dHtEtNK2l=0h-3DH4 zgT%KQ@#9;y`wxnpf|IG4sgtRlv8kNBiRr(}&|n2w`Tp<5>OzV<4I!Z)F*1WfbhLRi z28ukWEF*3!ooR5wJfJD=wSgBA1>p~nf0AQ!8s+u=S?_GlD{7LiVx#M4uySNZAS zBPl^A!gyk)Cdm}hzZ)z7BJ@6v@bwCqwW^Y@QU|}{pV+MZwwAen5fxoh@o={)g6S^^W?x4c_9uE)?s-PpTZnne3n=Yq5MsEn16eL{4DWd0MN*9 zzkAi+xA<0f6^y~lbXSdyE~mw_rx0#P#l0B(E|}5;0zo%k@*F63ZWkHj($2qJOfBtp z+7gI1j&=uj_46F$!KU2BL|b0pD{lad&_4$RS?Wrqsj(v$H#L=fnVj@-{LjOn*MmQX z`hMEKd{5qz|KDE(|K~82P5*cFhw{ch>ZxwY3;aOUW+zb*Wn-|OfM{(PbVP0uU~zGD zBM)~xj(O-T36tOx;R{&bqZgFO%E*W1j^-2DHD{q%XPq$J1ZG(~=-P7}TAQia(GG*FkwML*}Ig>HDFS&DZBe_xo=s`M@%s{rOLkI~M z_zEwcg+sn-C;gW=UGUJJTV+EZ`RaU$+R zYu3~r(==putxNU9`M!xQWbc;iIPB0wIMwBGk6Bor(^qR+#UyxCcH9(`8-kE5HM&J8 zyq>fU!c}Jo=r@l(>SjW`HMh_#rDKMaYL0lJ<_7bm5cT}`Xrmz>lE@LRTht{;ee@n!Qb)P7Nfdm=A7zgP6XKz6q=)W=rXo{ls@u zR4NuMtwXo;jYT>v)57p_Sr@&z(TGUyYU8v&FyV2Djj&qHDs}fpeF`zWd$p}WeS~P- zXYQsB5+n;N(mW78RPXuUF=hQ98_hPl!{eUSx&gUReP$O`a|Np#9LB#aWcHd-U`z9O7|NSy4yL{)63EJ4({TJ1I6(;0< zFro5^f{LJu_CfHYV1$K7YcrAa?~|mr3a$aTmGg?5i&?^Yjv@ww33kP?>>-djhUu>h z_)a#RKc2qspmu?*Jxwr|t1g`Gi2Jh-^IYS7(K@prQL-$oP4G2C-U;HI%~f5f^e~;o z$4d{>4D;(Y3`euqB+!|Dl_8VI8&g7zk7oRN`0diNFDM-%Wgwi#(@(V%%g`VxKLnf6 z*W;%J3uZl?i3;Ut6&--ziDGB$x6TotQneM6!>`{@I}S$6c*#pmhro4WeAyLdoPOJ9 z(3>27xZ%g(xty&`mlr}7(%DSh?hMFVhs*}Wn(cQP3sx@PxR+Klx}z?zMoFwwNZ`9M z+e2W19csSnP|&07F?n-O^ks;$o$cw%fmMCfM}1gy9FMv;aSrSEe%C2XlV(t7lC5L? zp^%+7`PpuKkCw-RKevfvRIOPCTlZSQlmWj zN7DP-6L+;1GiPoE2`$5Lzcs4inpI|#lZ;NOJG;EFNrq^xZT%gjF7e{nXSp`fJL7LEO6}6p21zd|FW);4tQJ-xO>-CjF!&r57O3A`HwP`_K@1#{h6BDEut$VS4 z*1mil^9&Ya49kwYR#Bf8DI9*zyk#?P9hQr{gk26=E;i?@)?)6VsV)v@1_R1HjaG^k zo$=Wk!gvmfNWPN0fyKg?6iq4DSB8BIiR=8z>oPfHDHGF1Z(SIsv*sYc?X?1cs>yQ_ zMK#YA6y{U>iHwV9zEAs0BIoRly(l?loP;P*jX&3zADt2Ga?5O@TkzR7nt3UjTTU!d zz_%_lD!-`7NfHwVEdTA&tw!3CQ{13`d_S-8oD;(~v*W1QT$$=8GTV|H9^NTw7;HVG z?5~5v%7{2&__O)BXnbtx^fUf3@A^*BX{+# zfkoS4mzT`k=2hLRid}u^gtJ|3%))3c z6p2XD3T_p!3xY8cRkhkcU z`u*R}OxLtoT+Ggu$H#r0Vo|Y`UOccWjWxm2vAhRw%4H_{hPcEcrF$M?#!#gLuh?sKC9V3Vl!20naPFt{E)FNnkwreX9C}X(j$~ z=!&)l4gq}lxbB%-)Rdo&OZe+?G}IU7>^w17nPebe;W0TP(fgjbv$rgE z8={xz9)e6FLjbAJyM*4en`|O$SQ@hMJ7x++y@7t3dIiZJsnrh+_z5(g0`m(St?T>e za0syPKrn-`0A_k1jY% zqDF*R!#QUbM{fzR{!4cppIN^lE}zU|yJnqqbH{T%cdG&_wnM74hdLAWm_L~t{P0XY)X^E2GE4@cGo6{X5DC56M@ew$UBT_c7+ zdXu!6*Gj{P%0Jh6oK5aMfEA0H3#KOudq-?^#z}DQA)_6xc$|ifG!9Rlw38&B_!M2a zZRBuKqHLQrX_sEQ?xm%;OcDwu!1exZ;$9bES+Ft94W(?SlGH|&Ju#|jD_N30oV3?o zToHcu!}$-vR&q;Q{8OBNNI#TH60#l@n~WfpP^D!hn8$5S;A!nU=JE)9MXd2xn&Ff2 z+hH)wee4R|Q+DCD;qzWm)C{Nf)ulAGfzgtlOc}DfG2q*85}V$URP<6BU*wY=L1={} zh}V@Ra^dVqtnKR0YqrtWYQTe&WM zEapatj*u+6uca9T-oYU%qFG4Wd9|C-UE?9aHNMyRrP0ibAC-DN6wz@mT;Ggyax(@i4&^mIt;lHxAWoz|Mf_JU9F?NBnGY(tyIJ5tWR)H1Q$y z(;9y#)qtvc&`C@8*TtKvP>SI@q%=OWCbR0fi6z|oscy>qnwrqghT)uc9MWb$lMPML z486{%htQ*9Fsiu4`2Dx0QzLn6n?n4^5z@U(wE@5BGk$VU#|Ik70|WKk^-^(4{-zHz z2X;RPHEkZoUIn&(+1D7#q}S~$q2j~w$!YBXU#9~@e?6Mv#6g(NzwXNC(1E3l zR(u-u#b6}t)vR>L2`eX+rMse4fxQ5G@c#V18`_sa?HI-Ju*UG82 zhF=2>;r>JTZkOLjJ`SVmsgHA|_r?7nbi8+gl@KQz5BqPX{p*n7Rb9?QUgu~2u4yVj zl*RMW0zX!3Xd+`YFN2D_B^SJ9pEXi3O0~d9!R1KAn9Ladif%;%UvfoZ`jVAPHff4@)jz%KoG&y&VrV0v9>Oh7zQvo@< z7}~g%k)i6Wwb4j@Em%=s78wsh!GJpFU{cSz8Q$QPV1}MzlX~ciwB2ay6Gs<9$7N zfTZxGg=$eFLJx}W6y!it-T{TSJRSk>DAVDy^LSy);`{NLVJbH$iodEL+?h;`Y(9wW z;y^iM5D)I(G6-X^;(N77+djpimr*ir5_L@E<7efaax!0C_YOmVhx$u%}$Anh=iiWN(nS5O1VS{1{Up?ses zp&Bs@PYTmYL9Myz5uGrg9Y2|w!u?o>ne}lg$S3?QnUuQ?G%snuXaWP`f*`}FjLOGt z0wyfF(vTAVwrY^aa8we9xo_HddM;GKINHN@l(k z`MOAO5;@&Qe;1|C>2`l?nSS2*`+vb15cnk^8mtHd$sb(015Nm9;tYYtx;_ zOvu_vLo(S|lN72wZE_7%oE8T`3inv0*h({;6svalh&Opw56X_z%TGHl_!>nC0;&jD z9?^L$C}FMf{9VP^mLg`)FGx4y2$M&VwidSxLky_-`VhypP4UGMFH9&KTd z98rd~#vN#>IzE@fg4G8VB!#E~MHyp~BKo?=UJa&V39?^+&_A65`cjbaT6U7Zx`~Vqd#J-H}{){OyOw> zKK7zvA?N=%W5Zf;{Eck;5P=Etyl|Hy?+Q?nKF*zYd`6oGB{6x8cW()qnr(0~n^Mo2 ztg?x`jE}(&K|>ml#X^%&R^xN_L_Jd#BRV(kGL5kSm{+X(_yJxIlg@4No~Zce!^`2| zz}0f+Y|@`Ri3<{PK}AR^z4dSKjy%ay6MNuIV8i!Dq9;lNus_y{o0N6dao zSolpc-bPt=Ee6hZG8`!Th$-k+{E7EsY|;@$0y%`i(vN^_KLt?b5JQPKJWqHEKA6X@7wVQZ04~x4hx?EuFgn0)$gSQ#XliQcZkU+*RhQcI(l1lV2{&+n3 zjUAp1>{uosqey;j;Z$3vA+* zr+iG%WwDGKFkiaOew+9za_`Sm@31U+IJbCAhX5H|(j(#Sx$JhMfl`g915tt*`b)dC zzsZCmr+kkTN}fJgl7-?!yp zfkwvMvpG2>|A@^+uGFD`-Mg%hFzdX`4>F6?Q+(!zN*FJSa|f-Q(n`32OLzywg=^Oe zm>VYWE`=xyEsk4;FAi@wwbxkg@{d8T^-Y3YUZz-a>Q3_aV-7H^#*cv$?7<1%7KNsv z{=o8*5wmLbQhbGe@Aev{XO!fxiF>M0L0pL&h!$-`VE-Hr|AD4_sA+9bo|E)Nm_%MI zTu631?32oNyWGoKUU{G2Yc$pCGRYc+`vg3{rhF8}z))uqbCHx`n51*M!RA**DH<8{Fu08tayR6 zyMN_Ss2|N>g&H=4+#8ZZS4%UO$DUOs_6S>d<> zlT5&lg&&+@?R!$RcTV%*@dF$$jnj}4KCQCdI~nB~3nF3iMOud~cw|nqeRhr#i_C;= z!MDLH%#6T8*fAFCnuoE4K$7JAQ^7(J>NO=P&rmE#iHFg7y4yI>(Ll%f%wHt^Imv=B zaS^P~wiL@YjafSzN!C!VMYw6k6*afdtbLZ`&4($hT*wSs=A9aqAG!{HzST2OX8RrQ zW26S;;Y{yb&0FrF*)CEb223#6a|c(WGb!vT4pQitptSc_yjbZJ{R%*pfx)Xn@zAhw z9Bvq%ZT2PO0ytK zbX^FdY;Ho9%$yq+*(KqgRB1`tu}1$gkOELQNAB45k7@0H|+D3d_UwKWfW4(fNMWg8fj+45r+YQ5sW3M!6DHB-VSMcz_y=< zX*<|E=*95YEif%IeV=f@sRohE0QDX=FR>5q0g48N%O2I9n2#U&M9u)rU# zCwI&T`1XDl$c;q88_fT#gpy9EI=sF`Uck4=OZuNLm861=tGT7!zm!AYgfY1RM#PX2 z8#+2^&2j411gWqvXL(g5CB@t@=(twG6)dGx1Co)mdn;TIAbe;hM{1&F+)oOYgBt?* z&*wk)&_E-#+5uGHAL}Cg{>S;D-LvG2AaXhL_PWECq^iJXm@4m?`Aq8ZJJ-*O8sK2K zc@lKYtuKKyE+g1w`Cf5?AK_|$G)sKvzFiy_KP#;I2)5gv(8w)qE)K~Or!~Uyf1fkx zHSvHKf!Zq5M3Put&3;5~Ozvo_Sm3wzdR>K_Hol1M$MscXIG|zE3Hyg_iCcbYUz(M5 z%2h~ble_F=-O$6JHd)_=6Ps4iJES=#fAu4+4}J0;aXx5e85l+5v!p$f$2-d)<0GBz zwpjWR^c<)(T0zo4%*Q-PGOa#nRsF48X|h6?#l+fg3I~}I?q7K1=4SgLZz=;vE93X6 zXvRGf00_FITHs3y<{G^g29A(B$vbR>g^|NB96P%gp{d<>L0itO7G637x8dFz=RB;H zy+FP6`L{u6H!(^3?e8JzzVGzs|DgE(14J2l@qe9LQPR#oj<=B>nzyX92(45ToaSOp>;$(*O#+|!mGeY|b7_LgY1CnE{_`mN_sW@f zbxyyV>*;!j1xquNkW0Ro?1#5)=jpDO7JvUwtX@cLMcyJpTaI#1;{{6lw72@L(p7g@ zfLeDgD~_my;C*plIzX}JICa?`a8w*v%CDQLqm`|eJ4tn#Rezx^Td=(ttu=8;3|PE9 zIvcBK=s#6L1ZZb!A{*}uRiF%sGQlrcwrl86LzCnS6d4$5<Q!sHR(L83s*_i+ zSd3SvZ7DcV#(?y5Db}7J8(l27uW2wXTNnSRGDwXE*s;WH0{_cyvRa8@yyUbX6P}NkV5|L_2YZq;0AcYglb6671Qkw6eK|m?G3yRi*pN*mVe>3GugL9tuJ>kZY8p%bQR}oe{ZwZLxYN6G*tx0 zZ)~`Nep+=ZO*2KuLfgzvKnoRyHe;xwE7oz9kFdC7;zv>qnEUx}LoEFSCWV0^K!j-Gy^CY&wN zk9Hb^=`OL$GROt5eEZvpPHPQ5rFs)3qJyTxS^%~L${v5rh+hQF=6V!|v-bVoY z*?PHhS}!>lU(wX+>L>ytG|EE?IbGR zJkd%9%fqzi>A@$j=2oW*GE4o0PJEiRN%sTjap`2#HM2NrvE*?y1*2>o-X+1J@11YHA9ol`V?TgO%uyF{b51#`FCYS6E=S$W*k zfD3xTq0*q2GrD)OJrdwfqP?Fae;#7)3Yht^dsE3iF$VqDnDkQbtbpvLUTebt790DF zjbQNkFk@B9sqXuaoI(Km&7V;C`pqBsk8f+?`wtyh+u3{LeNMTh-Xakk=lp;M)a1TF zW1sWZ3K?pugaYAPyHy{7Cez<5 zFNu@7rb+bi{7b%@6Cg64D)EL)B`>tML6mR*_usl<$`@I6jo)kp`Q9`8ADWl{u<^hD zttG4JdZUP<`cX(W*djv_2a8n(5EfdJ`2kDC&lig>gcP$P77}u6etm~UP@@Z?Pc2O73+&e-X$TuHDWIBfp zm6DI9skTjJLg#&jUzP_r|k z9|+mRFde4zOaiPyni;sv^?u8ttwD^RnbE0!M~SFvA+OMMI+9M(z8#OWy=eJ;zxm(& zxB^fQ*wu-O2qGmkg-#2Sc~M~P2ouhWv0a>}8`08=7)M8{hH2MS933gYfXDI|m)$>% z7;h)Lzvkob5Q?1LG0FetI0IY2`Yytx&?(*&-Nw_#3a$X+t+R%Rly3=xV~YxXSt28k zM5WA!tk&CG%|<_X&K$E7X;lbC7f{{u`tZaR!bkWBj400bBj#)5`Pd#8DB{PwWujd` z=3jqIoel`juy!3;ny@|}W$*5`u!ip<@*P;+f#QKxJVpv2; zY@BlFLSmrxBiXMAD>Pt?u}S*CGQ44`Tc~D7oQV1N-YUx@Te&8@maNzA(^a-YOB>-) z_=D8SxfxF(sZoJSOOe&d?KQ@_>S-!>ZtZW{{5GJ2v{K7dL^OX1ZEZmiK_~eTTofX7 z!c;{xu9Ar@e*y|iZl=8vV(biY?%o6a%Ku&+nY;&O-w>^>JeJ(Rt49GN=0CCh*cb5_ z3HHmkyw_>l3};o_V*`RmzCnV9Q*#%?tF(7Ui262P|JUQ*Efcig5~=f!vBx8YPDE~p z3xCO7Bzvz345Osz39#I5IfBRU%%t@~wB6O%G+5BD1f|DP*>M*b*65eJUlGKz{ZBMh z6pR-GJF2$uCZwMXY3&b~&IR%gBuS?U(%w*RI~cTSr}o6}CE|U=yW{QP zx@#=$lf?=>fVclNDC($x z_ zXr)`PZV?N32h-~;^%Rmw8!AA$R^_N_YDpeqz(8oLF6RvsV8?(lA@~~)`=VxuUKss zui^L$n`ho;NAJR5uRs}=DMK7A$;8U$v&g6z_wbqnzG zgtxi`64rVJ!e~k|CjpZh$8?6pCp2jq7-9zTL6*u==ak z_b10|N+kke^vx~b5zlYMQ%WQ>WSC630!0dCquTXSTMlg*B+#-QMLn4tjtRs>pyWa= zh%%RW7$hNH1*?!*IB6k#VyHb%5dyjo@L7Z-JWO&73?rN}VHJNdc^hWJ^#N~N@4c?# z8GOqPvKjp34*D-R@ON4Nfq57>EZj2nkN?Ih9UB*c$URRhsBc#7f3u4A|BqGwwv8f7 zRq>xV$v<`gvyDd~tKYzxYT!Tx8s<=s*InVHUPq*#7U2{?Nd_5e<105Ssg)wH< zXPL=aTYE_#x@=gky0flhw^f*xSZbI~%>()+XQ;xMN!i)FtgX~o)XVIlx0Df$C9bV1 z@FwQZiw(j&=>}wHls=WxK+rMw-C0?-o|9n{KRnSuS}2|Y*I4Xp6w)1pR@ufHvh|qv zbeY8y4y&;(XX|QqWonw5F1T0H^_-M+E>o-*fIp&jeYvmD_K}8OKSAFF=(VyP>@3@J z8S7v|Og&OD{YHZ(o;}z2GGu>#erN>u@pcU(PHn(3!G<`(g9$5rXG&r^Qg!t+{h%)@ zz=d#7kg9Qt0&ka$0o98z2C8u+Wg23PizgD74k1(HZn@~!ggYnHtPkH|n_@cbE{Pi7 zH-HpZ^NPX5ci>)zR53xDM2!1e@|{05J+B)vQZBO!$A9Sq^)+edD=O$xM6r3^lppHAtJ5A#eDF}x|ir4DY8SPHFEM;1tRjNx<#cVPl zaNUM-@2RufN(oG5Vyyw7YVb@wU`9U^f;y~6yz;3L_bI(Vw#q*6^>it$r^Tyw@CiV` zit%u(D!Ax(&1nUdnI}AThFX{@7po0Q2s8~@Ac{;ch(bFzRo93ngFZQrnR~_@e#dJi z@6$Val?cRpxC}g4oz^R5?!X=?pR}u0s8TC;tlUEZBVfT@kJeb77uA*{h`G=x@f1-> zrm`>B1aPGDmyH$tO#E{CZFt8u)bj#(Clgw{fFBrBK$Bt_zgohknHNSJk@9tlcWyFs z$JNzg`h4D6h%hgLKojkom)#)4G~H{u3<*RR=9Xb_wh6SNq~=N76YFXAA)4|cXvXrG zs}D-#U|T^;@}MO|No4H>KgANEjgL!2kRUzUd{75?{gGms(HHmj2Dm@gVC7MS3m^KX z6{@b&G-fNAw__?d=;A8QxWp?d&(V`FE*fBrEUHvS9-RATwqAUcoN-)_7;^p!<&;FG zNY9^rX{?zspyvDqMk-Z_ zVV_UQClcguS3>uQdEo&(G=f6Zu6L%tl=|7({CAt7%MU>n+VzT`pH4dCa)I65xAF(w zc{m}CDs!kf=7_P(uDQt_3|y>!c-GF?IRfS@iuNmv{+|8M4d+2#)5QrlTveYKxCm}R zUmp}~QMS{V^I6Fj(aMPyB%{2&2MUMCWlDgF>3a*(9n#ngFWc(XMA?7ehV~Cq9%AXZ zK@ov~WQl=*sQ(|4@~;A@NfXKg*WAibPVV!zM#+oKU8zd$&06%W_hg?mPl8yy{dst5tld_SFDoDu!29DK|Q!BU7 z)~k@NFz)foT#TlQcI~6ED%;%s?_2DR_urd8V)|YO$~j;TS()<+L>h^8q5ERX67U&! zCd2rnxGb+0Lodbm!fNdU5;(%eRYa6&-h;bZ;}Qr%9q+MelH!P`mRlsHwmBMSZZr?&lAL3vThXG&GAlz zXPJnsla0P59Cp$?#e5c|vabE3W?<6m(T@RHb>RCWQ-2ClP<~oGzi1sh+Cd^{xlOO- z$ip1Q5hk@L4^pn`;NMD{p-$eWn2bwlPqW|G*q@?-x|@MdGNQwnB}4W=2Xf;jLqZ)l zYFjq2{G7L6=M(cESLvT2jaI4o|0+8Rs3@DSfrA1PQc8zNh=7EYbT>%1l&~zY2$D+( zf`p)?w6rvm(j}lE-Q6hNtsoZPv+rMDUe*Qu9?zcTcy@ks=gyrw@!Xj))>|D*zG%I} zxRsNj zrv=ei)S(p1VGNpS&|TpIK~;r-5kir!S(R ztgUvahE{V#<qbI%ko>X9M}_S^RCYnw#+Eq26xvJK%+{+Yb7~i7%8TYJFb642@+V^L0mm7uUF@x|(}U zh(HuU%!7l`SUKD~60Q@rdAF+@+ZQU;XKEDuy*$QoW8Vvh181OCD6&x%gwRgk8|51} zA}PH}ws+N!`y$40H1xKAhGceFO1J@uOxx6X-C%rEu5<;HT<05AM=EnY$N{`d{8u!ek0%WHO%2 z)gRVM`}&k6LMtg{hSFP8JEUvK1!+q|b>1Kd1DvvxxH`o@?ck17$wHAqwtV}neXx!7BO0| z=ee3&wmZm#MZc<`ugHzLGZBh7C2|DUQams#`YPGq$uu{(bEEzKlBuhC)2x!o* zxwnlW_;TieBsf!VWaq0(0Ax6I82fr7Qc1S2TD*udzqy@K})E1&bH z3=;Fpt#5`uL^VYMD=^wN?+Pk3H`g47=mTOoc&CFmA@{E71!v`IWTg%zusLMs!7J7TV0PjglV8x9o zd%p+u8oQhuOcfyyF+2I%>St+<{A|>>6Z-l3&|t4+ ztOlxo7H4iTQct#xGG5U5VWh-m55l9I86%Y3j?sd-_ZmcMnavkx=N&X%u#aBOi0HhJ zv~v%3mTmEzX-V%NgSs4TZl2!|Vjk>3UZc9cII>+Ga-^lgwOQ6LEk8A9&OfbUY=bj1 zWfnJ(4vRi_s8&S;xUq>KFGDu=RVY|!Y{ zI0*gZXeo~1`6onDCR%08kxg;TagnXp4J2Z&F$G!N-&f9f$)lUo!I9xVhB-YmRk1Z$ zTalHY8xbB!SZY`$k5}(K5Ve|-q8%2zT&xzBKQT5vKJ~D&BzI}M%isdPbCkVKeg~PZ zLaadSRC!`i3v|IC2tSn>`KDP}8^6Ko(3IH{L$zKNZA@u?URtFj6r$0f#qy{+!p#3c)(hI&(YI+;gn$0A9 zexh1(a*N-~z^)WM6Niqu&a4)drbM@w`c1bgsY^a~`4da)4Z8WRVBe17=}+w-8k6r> z?8=gLSd@EtjNyplF=Vk-BZb+EGDiceB9ox%l zUt-fx)|w(k>&b$E`rF+r+rI8io0ZQ=2xFZL_~*4MhFFqtaY#Z`nWAQ~Ejd<{_FUri zQZSkbp{TW`W+_toWM9Y@#)%JY%;9wl0uE6nacz^^ih5&l$7 zzdl?#CI4YhUS3qG4A=>#Bh@|u3A%uW8<_3ch`Vu*PrTCwLUqZdBJxHLP_!@TlguK-BFi+OSQbSbmWv}M#Q1Vwe{yz7AAF5xAv?8i^@cz zR%}Qo`7H*bLe1CHb|9j?PpYT7H_SR7HfpQMa^INgZ=C3d3^>K#;>>FExwg1g7oRt| z0kx-Q!@7IzUO&t-4*qT}JN>s~cRrPOJNW-N;*XlyU+y!SOFaja;I=}jhEt2Qdh@^ySD=PL&mhw@?H`0u%2y}2(8yG1 z^oa|E)I?Xg?!>1LU-7vtO4ACgW$Ng<;ZkinP*qxkmT9gm=VA?OvR(|Hed|k)} zU*U5n!4dWre3?uaqH_<#uW7~I@#d_5t9orGL2HA*WnxF{8@;o|JJZ<;-plkO@~NM#Lz0|j zsGy1F+I@q}{o0vhqND|^ADo-F?ZjG02h|>VUj0mQ#lj{Mi?^pm_3fNZ9fz@5nJ=3wI#ziXB^NE3lM;rCI%g#C|9qoV@X{uHHJX!D)f6e93NyYw?!7|GA2SM?Dl2 zGCQ*<0aEF>g6%t?ASSA-Ju-H*sO(;*>iBKmG~qpSp@MXTSfu16<~q-=i(}p3v20)X z!TXIA<;%I?sfTYfH|yGUoQ<-91=}o^Ja;ssWe>C-qj%aC;c1^OX(+5InvCdk2pS}z z216w-?;F|&vh#CkhU*Jn43~Z&MLADi_IMnUSM?<33+wDc9mB|4Ls9jrs=GOXXH53X zT*eO<%Gye%zma%I68f)-qkh}t`{sr$;(CrJCo4HgI-%y$jDyQws>Xg7v9(5y#ju*e zGd|Qt;a%t(d zdg+?~wqnkLRKF{R@~nUh=KBmP_t4z;Efw46owh{Y-S~`eXs(?bxqshJItL`EVV}-y zs87i4pfM9NOMyDsS5_dB-3R^XEsrv4ZNSE3s|E5f>fs9}*((;i)xTfSryhFAns5iF zCPlk;39}=(_^Gn8F{Lm~d{v=%E!$4;CwzO%>NcZXznR~qNN!@T9 z;^|`{=IiT`^V^`^LyWN3N?C`D;Ln`XAF&7b)H)^!@Djo)UX!m0=3gxLzP?zKeLmqK zuFc#Ghl?K6J}KZ?up+WwOSeVPTe}7UGdFSZ;N|BxO6ZH?wM}_!^xr(cKB131vaQFy zKPog|QZsN_SgTKJu|rX;N2XgLcNbloi-ITTgFw^~4fC@mowiN;h8x<1hlNZJ7PN9& z=AZ#?1nt-na}rCW`h?`6xRmlAdrYFg=-#3ixPiCl)7YWz?IZara%xdt_px-yNXNJw zqpJjdGuoIGHbzg^UIuFpk8AFu`*jyzkRWqkR!Mkdg5vnF>d~OcM|aWd-!Lt|N1|7! z(s^HcR^ZX>JLW3*z{8CxN%37ttjnb*_U=AbiRoFNnwI&T^_BbSE50yXxrRpQ$)hYC zhMu!dLDAAj>R{KYB@(O%vX5`?<3zEqBJBX*{AT zNPm@(v=E577T+)Qo5DJBB$PRwWDXwh9CQ0JI6bPi6x*2oa|N%4(dO--d)gwf+K z2brE3jUGkS`w8=l9qja1oo!9rZF@e8vM5Ha;A`NE=cm64T9@-sQ>`BM*QGwFdVkPy zzJL;Kw5?8Jnl#5`b^C{5WA1Lj2J{GSTR(1~1QP@ZHp~SM;=K8%wFEV=1Jufq4%iLr z2zB`1ib7PRjl+Z_UUPDwRfi{Q2>De=KM^K|^?D{dqaxNQN^XeSV5{1z^@~@Y?=TeD z5>oKBI{CXJ3*%O@jeDgu-kaVIe!iK=J-Ff<+swJ^P+vPWv@xCdgOwK)*5DyZbYn{2&n6PpoiJM>eV}qaD=pM;pmq*J6Wn~JR z4%vXpE7=U374BuI2h3jXk6AnBRlv#mHl>`tQ>2hcvlUtWR_CPz)Jjmin5e&2?M@FP4Ty zP(&&6<6=IP=7_pxM~|$=-EW%yQg$HBjAkLMTRJY-QOV-IE(J$BMVjEAi~sZ<>l>n{ zO}EG4>Q~U+lP4&`hTvu`Q!l_jeTO?c>;(e(??`SaDNxS&4akRtIp5*q$d7oI zFDu?GK=+cpJi)y3h&+nRr)R~}XZ-xfY{nKH=|}O)bF4})X0Gd??+BssHsFbXe2ung z>z;+pru4L=%Y9VTp3lsFtf!rv_L1M!n*tBjj!#RKXev|a%cTj`&qCvJ_;oj%zYiy= zxr{LdGTm#BBK~aoeT1jD=qUPGs!u)n0>d+@&dep<8PqF3Q1_4QFt4=rUAg^|n<u~s@Y2RJo-#7DpH4=ru5R;6Z4K{>?n{ z2SrxV4HkG7y2HF+OD$^dl2>_4^5;@aW!blX9!V`?FQ&ufa*`7p8~gu`vgM~i96A=8*N1K;b*W|FR#pQ=Eif6)?qvY-R1 z8){tU#`8J;g1hyiQ=Puv=g)PeWoj`uGuII4m3C+uijhB*jn6df?R*~H(T9tAVMTg; zwmC06CF6022pmJ+8k~YC^Yfuc#Qr#4Enk&q?T$rq*?5;5Mx?ca_FlcCXg5 z&Q8as#Y)jR!ozVCuL6c7iO3K|vS?ugL*3rQ_;K$Q>E3S0V%{Rj?gZ7v#DlbFt4Vp( z5IeT&Mxhe?!8u6+jP>Y24Fbg{k~&CP4J3H7g9U_5kObpQ2v{d>Ws#PJ+bAd%KjmgO z2E}Mxcn7$#b8S*Uow1sRL_AfeA8;{RvB!C zr$r0}cM~v}#-`KX)NO7k_+@-$lfn0EXkcO?Wp11+^Np#I+oZ!j7vmIJ{-O8w+yfF$ zX4RLa`lb1id8}K4(mR;CH5 z*dpr9=+RX-w|yUuW)sW=BHk)m>G9n9%e!`ZL^G6L5>qSJW617}k20E0`pl<$7_Nqj zXnKYn%?W@zT`x*-L|+4Kz6?TjN=Y@0bIFt8vBl>c*XUIst?!fhEUdY**Y!C6#whOS zh_jtOuh!_goEw{J+sN@A+8hlL-&F~4nhD(-!mixsQY%v8-2SRiJ`q@v<0Dgr9 zbPW{QJ_^2`6-r*rvo)6BBTQ;B?E>lOr#$Eni_vQhqz>uNe_;3qTLnBYAJ0^S>$zqM zTC|CHP4s!9v(I2u@vE7~_cw&QTjC1yY^A1an%oiADhJ@=V9R^-{`+dIA4KLFEJTEdLBDp=Z)Arp2U^J-mrHx zXexKFu^2xur?rp?%|)t?5-r@CBuk6{oqsALOTS8$%GOsC5`k-XYv(#z$!afc!VzlX z)AzPccPWVnsfCBxzu;-}e1m{_AJJ;?cjCQU?ol;Vqhu`{QkNkcnY??Dl*h z$+hvJD%_pZ^hh8i-95b1_3bl1k@umG@DatK#5}G@L}AIkkcaX0uSS@Q_49i&t@WZm zn#^~%ib-Ybo)RXDG}yS}h(Gl)wZWs=TxJ*vvF2w<$+2u53eRdXSr^KW{EE%h&UpyZ zWSYk@go0C(yx3^(f&}mG3?-K{C!y=V4sb&b{8}DvevVi`b64;@{nD4Iay3)EupcF> zgB*GRjxyyj6|WD3%_M5K%Hr}3&2D*p$$fF5a>mCDBV2XeR&49i;EkyFG3{%gRq8w` z^4#yK>-ry)z=jzsmiSQw80G8(1z^?7V!PvHSB(s@S{ z6yGGM6jQW#wfU@okSXhl>$|K)ZV-xY zu02L|S506M*G*mA#oQt4?uD-`>ohc_oYsSlmh9@As-5yu%cfcZ_Dl))7n8v{Jy5A- z^CKrdx_4NbnyK4ydiT-W-W4Qh98|mZPF<>mFjS%xP0&AyU~vd`C8Pd;lDhVTeBZDN z>zS?MxBY}LV%`r0UxUT5{0*-Gk?DqOqYg^9PWFTOhYNOxfcl;SYGgk{jnaTFrCcBm zjt+2&jQXiaXb?92Gdz@Y{QOsGuCKn}V$dK`RQVFPy{!Z(Ec?B~QsM)g}CcbdtYHY;_>2V5{D5F}h`+ECy zhg=GJ;-G0Ui9+u8AJB_ax3zscK2q_0^=*FLUOQLF>}zToeM{X?hWCra^d3!ux50fFM_D^Q!DpIeJ9F@x5w;YM9{ZEtvvy+3U zP}(5I1we<{z=!_~J<8p8GPZ)4Dgrk7>snVhg(fO1Dgc)G@G>a1=uZB!m~!nQGMdMtedhL2y?8k>YshTOXsqE;d9!%DTW7lg1qM&<70Vj%%-P}43QI3FVkL4 zAk|AZp`Vw`=pUVAmgHYl%iwuHE#GaU*bRzKHA^eJk`d>MM@wfVg5JXNn6-Zkjk@}7 z7c}{m!?W*rXk}o7k2wCm+x_!QZ!c--=}1djnCA^mx$~>-8wSB_R64+(f%)sVT$16- z1?Wp-o;aKMvoCX)RJnHRacJqzb5^Jsl)NAMuCVq_IStER#D#Wg6Q39q^9i5#LTcKa zd7dC2!BsnUNRC@bRVcT=lZdW`ajojpS6)tOWn-OI58-w&h_ypYF#y#T03X3K)T?Ck zU(JeHS=l&)P0vv9_#M^Wc$b~?7i(ox)bRS$*E9ORI+ZBOl#dn54b?BmZGXVsmU$Zg zQ^BwQRj^|(&J2EcP?rfiv3-sS#L9A0O3*le)~kx0QCTM-T+t(?%vEJ&C{1Gz(|;R7 z&$*$fthMBGjTm}2-%_#isPJtM^u~Vsq)#EzC`bM2ObwT`$aSPeE$9<+-i`}hh*2jLHnJw!RFXm_3iH!M)qU<%qPlvic76!92s_+AtexyA6E{0C-xa1&Wk zdIjAhK(!HoiaF0vv4*QHSP|l2ZR`lLfYa&+vNG?E99JSZnM!=8m0UrX`uYW%2UN?Zh{!OYVrX(jVrLMuMD1A%- z!lVF)^eYAI`&ZUTNU+Rb1OEfEv1U6f1u!f6`M^?4|4dj|H%y2 zXknTCoAjSq)xV|vldQZzavOW|GcyFX=Kp+PvflZb!r0arWC1=i;pJcH{*lz@WJ1vY zc88t`AU**oMGW{;fk{q4RuDt}8Oj`27&;Qp0|!x!*6iMLAT>Eqzktd8`=onO0h{#H zSS^j6j9E?pn+j$aphNSnN5F5RfzOqH(;y+Gdwm5`{Z>~eHuS->US$N54FC)xKx(oR zEZE)8zp?(^U+1_FVtP99tV&s;-M!?+4umPdUF35ntt5cp2_5(aWX#I&_VT-?fB4y-C*_u(#J zCD%@no>L(vK}{hxvcRE%R$zO?NT;bGhIL#dq%LasI*A0rL=g!GL#kLAyPigLI9$8s z4Ad|>V7stL(_ar@g}|5tA<@wSeBTiQGKNhoG;HpHf6gx875Vz0NDkJrdjK*l;Oy6v z?&TwlkSuQO2<%FC{Z&1`E~bI!@_qC2YX>awF%Zng@Cyojr+bx({tXwgX4`-8Hd_Hb zz$3slootQ3!QY7VAYp7}Wnv7vrw+DvI!(E4DapgrfWu5@g@;15PJvp3?Tv36L+=BA z{1h7?>4BI=0&ZLdDE!qE<$r$v6sWBu)c)sIe|T-G<6`yxh`0buL=#$K8KYxXGy;)ctbO$x9je`6ag{Wbd*V&iM!6iT@Ru(N(+H>~_M zn+GwwLg_|s*}RC^$l23RuK{e2-{dym`fE1uF3k$?Snzepno4Pf zj)R0`0d&SEd%n?~zhxsPlb2yLW1=G=$pO=XlVm0&WQ2Xm|Hj?0^(Ga28z+eAX}%xo zzk!?!kfnk7(MhN0fqoYGbSiA(RZ8r;fevUH1<*44zdi)kquSt~Mb!qIXhFcvzuX8S zM*_pwx$A0b19(3G&vpXeeEI)@|6SKGc#%WKy;nfL{Qwy4vYdch0t0je;}?nl>H381 zzoXxlxQn(7f|bjG!3!JE%TS*{gXs{WCBaS*5EzjfV7NC=ez3FvCNpXrRG~0$n%kRo<^B-OKPMVi?38405!wcRjT~+4OZ59o}CSi~@@M z9O$S{4p{|mA;#LC5 z%xM`ITgU=(o&+X|oDD?K8Nq<0Tl-YF08AH<@+7cD>}(){9tZ}E?PbJ<-NE?gHwlTQ z&ITgrc3{A6Tr%W20BG_XP*vt^AcDRI1}s}%SVsb2#lIC9Dt9&zK?ef^3Rjxu+ydG- z4ba9<8czA`vw=LP8BTz7sevgVBL~oCXipdpoAMu!hz$pMXkC#CSW03ugm2G-YG(p} z$HAK5b@L6cLqLB^zy$Q9d>kGKaloqtGg+{eEh6U*a}aZ#7ioc%NKXMhUO!P_D_?{_ zSbw2mZ+zbYxIhDu7Gcm^mB`Z^0MH$%n3GU8zdu6}v=|ul8UggsofKGM;DE2~%qM?@ zBG%@UFg`zIptel_&vVkDfm2UKYT8=a7@MB9LI9IAtAKPi8(139QUz@DgiiA_PRBYz ztWKGA7)PQoE&?KI0RxAVyr@ouJQ=W!xIHjQK4miZ?Oo%c1Hi)ux-hyE^3@ES#yflJ z6{Q$#44Y>(0rQNLMB8!1MB6`1=9(yI=e7a!X$4kAP7)_RASB8)duRQZe!-C0CqL8F}63A1Umw~8e)q=ADX(p3baqy z63of562=_I13b zNi;$%JJ#P|5eyt)SWDmr1{uJxvVoR%QnNTXe}P4;S*rzOB-m&K=QoRuyYy!$=V_XS zzl{A?Gfwv!C-@62Vp-vDuRezUApSG--@B~gTNnJL#>ZG;vcJG0mKFYj)nn*|D}RI{ zM#5j0b&L!GRvi#n>+yX}$Cqcp7asoFr(-B7(;uM!UIGQrgungfm}$m>kO_Ym4m=S4 zewJe(A=@dy|J>FBPlG?f`j{rhkC68JdDieq`14hdk^3SDk+4@_Kj)for>(-H;ZK=7 zMk`31iazrd75v$U$HWU#rxH(nQ3Zcm*fEV({#4q3&kp- z5ep3;gLaIautSLb=QZvr5oz!;!$)Qv!)Y8&hr{MU2;;Qi@$dml$9PM})A4@}UxLpE zK62+cpEl^}`TR{B4}4DW0W8NkF*~20(;49`DhjB;pSe`8Xg Ao&W#< literal 0 HcmV?d00001 diff --git a/test/project.properties b/test/project.properties new file mode 100755 index 00000000..4bcb2f55 --- /dev/null +++ b/test/project.properties @@ -0,0 +1,11 @@ +# 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 use, +# "ant.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=Google Inc.:Google APIs:14 diff --git a/test/res/drawable-hdpi/ic_launcher.png b/test/res/drawable-hdpi/ic_launcher.png new file mode 100755 index 0000000000000000000000000000000000000000..8074c4c571b8cd19e27f4ee5545df367420686d7 GIT binary patch literal 4147 zcmV-35X|q1P)OwvMs$Q8_8nISM!^>PxsujeDCl4&hPxrxkp%Qc^^|l zp6LqAcf3zf1H4aA1Gv-O6ha)ktct9Y+VA@N^9i;p0H%6v>ZJZYQ`zEa396z-gi{r_ zDz)D=vgRv62GCVeRjK{15j7V@v6|2nafFX6W7z2j1_T0a zLyT3pGTubf1lB5)32>bl0*BflrA!$|_(WD2)iJIfV}37=ZKAC zSe3boYtQ=;o0i>)RtBvsI#iT{0!oF1VFeW`jDjF2Q4aE?{pGCAd>o8Kg#neIh*AMY zLl{;F!vLiem7s*x0<9FKAd6LoPz3~G32P+F+cuGOJ5gcC@pU_?C2fmix7g2)SUaQO$NS07~H)#fn!Q<}KQWtX}wW`g2>cMld+`7Rxgq zChaey66SG560JhO66zA!;sK1cWa2AG$9k~VQY??6bOmJsw9@3uL*z;WWa7(Nm{^TA zilc?y#N9O3LcTo2c)6d}SQl-v-pE4^#wb=s(RxaE28f3FQW(yp$ulG9{KcQ7r>7mQ zE!HYxUYex~*7IinL+l*>HR*UaD;HkQhkL(5I@UwN%Wz504M^d!ylo>ANvKPF_TvA< zkugG5;F6x}$s~J8cnev->_(Ic7%lGQgUi3n#XVo36lUpcS9s z)ympRr7}@|6WF)Ae;D{owN1;aZSR50al9h~?-WhbtKK%bDd zhML131oi1Bu1&Qb$Cp199LJ#;j5d|FhW8_i4KO1OI>}J^p2DfreMSVGY9aFlr&90t zyI2FvxQiKMFviSQeP$Ixh#70qj5O%I+O_I2t2XHWqmh2!1~tHpN3kA4n=1iHj?`@c<~3q^X6_Q$AqTDjBU`|!y<&lkqL|m5tG(b z8a!z&j^m(|;?SW(l*?tZ*{m2H9d&3jqBtXh>O-5e4Qp-W*a5=2NL&Oi62BUM)>zE3 zbSHb>aU3d@3cGggA`C-PsT9^)oy}%dHCaO~nwOrm5E54=aDg(&HR4S23Oa#-a^=}w%g?ZP-1iq8PSjE8jYaGZu z$I)?YN8he?F9>)2d$G6a*zm0XB*Rf&gZAjq(8l@CUDSY1tB#!i> zW$VfG%#SYSiZ};)>pHA`qlfDTEYQEwN6>NNEp+uxuqx({Fgr zjI@!4xRc?vk^9+~eU|mzH__dCDI=xb{Cd}4bELS9xRaS!*FXMwtMR-RR%SLMh0Cjl zencr8#Su<4(%}$yGVBU-HX{18v=yPH*+%^Vtknc>2A;%-~DrYFx^3XfuVgvZ{#1tA== zm3>IzAM2{3Iv_d1XG{P6^tN3|PkJMnjs&CWN7%7_CmjoVakUhsa&dMv==2~^ri?&x zVdv*rnfVyM+I1^Kg*S=23mR@+0T9BWFZUu~@toA8d)fw6be=`Yb6DSX6D?jB%2YT~ z*aHjtIOozfMhA!Jd*?u5_n!SnX>vX`=Ti-1HA4RiE>eI3vTn zz+>Ccf0HX6Ans-ebOB>RJST-Cyr#4XAk+mAlJgdQnoE{^iIN)OcYFSpgJUmXtl@tT z-^ZuUeSj5hSFrQwqX>~EtZ*{>Gi8Bu9_|o06oNtaXP?E936!a@DsvS*tsB@fa6kEA z5GkjwmH?EgpiG&itsB_Tb1NxtFnvxh_s@9KYX1Sttf?AlI~)z zT=6Y7ulx=}<8Scr_UqU-_z)5gPo%050PsbM*ZLno;_-ow&k?FZJtYmb2hPA$LkP)8 z=^d0Q6PImh6Y|QT?{grxj)S=uBKvY2EQUbm@ns9^yKiP~$DcD)c$5Em`zDSScH%iH zVov&m=cMo`1tYwA=!a}vb_ef_{)Q2?FUqn>BR$6phXQRv^1%=YfyE-F$AR4Q?9D!f zCzB^^#td~4u&l~l#rp2QLfe3+_ub9@+|x+m;=2(sQ`s%gO|j$XBb>A7Q(UydipiMw%igcweV#Cr~SP);q>w`bxts_4} znKHg?X==JDkQl3Y>Ckt%`s{n?Nq-1Fw5~%Mq$CAsi-`yu_bKm zxs#QdE7&vgJD%M84f4SNzSDv)S|V?|$!d5a#lhT5>>YWE4NGqa9-fbmV$=)@k&32kdEYetna>=j@0>V8+wRsL;po!3ivVwh<9tn z2S<1u9DAAQ>x1Sn=fk`)At|quvleV($B|#Kap_lB-F^*yV=wZ{9baUu(uXfokr95^ zA*!*W=5a>$2Ps`-F^+qRQT^{*cN>vipT*4!r#p%{(#I7s z0NN94*q?ib$KJjfDI_sjHNdmEVp5wB&j54O#VoFqBwy)gfA$%)4d_X4q${L9Xom2R3xy&ZBSNgt4a1d7K^CDWa9r zVb-_52m}Vp)`9;ZSKd#|U4ZYj5}Gp49{4utST|=c`~(#>KHF6}CCov1iHYw zt{bWo)A@yF2$~c(nR$rSAaFQ$(Wh{vkG1AlutDMw=mM`C`T=X&|Ad9fb5Od}ROt1z zOpczHqrb4Jo^rSCiW#&o(m7jFamnrsTpQb;*h4o8r#$aZ}2RaT-x2u^^ z%u@YyIv$U^u~@9(XGbSwU@fk6SikH>j+D1jQrYTKGJpW%vUT{!d}7THI5&Sa?~MKy zS0-mvMl+BOcroEJ@hN!2H_?coTEJ5Q<;Nd?yx;eIj4{$$E2?YUO|NtNPJ-PdDf;s} zab;}Mz0kbOI}5*w@3gROcnl#5)wQnEhDBfn!Xhy`u>C}*E~vWpO^HS)FC>8^umI=+ z&H;LW6w#;EF`}vQd_9Muru`KnQVPI9U?(sD)&Dg-0j3#(!fNKVZ_GoYH{la~d*1Yh$TI-TL>mI4vpNb@sU2=IZ8vL%AXUx0 zz{K0|nK(yizLHaeW#ZhRfQXoK^}1$=$#1{Yn002ovPDHLkV1n#w+^+xt literal 0 HcmV?d00001 diff --git a/test/res/drawable-ldpi/ic_launcher.png b/test/res/drawable-ldpi/ic_launcher.png new file mode 100755 index 0000000000000000000000000000000000000000..1095584ec21f71cd0afc9e0993aa2209671b590c GIT binary patch literal 1723 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 SjQ;?@Xri@@RficifB)Hi#mm9~ literal 0 HcmV?d00001 diff --git a/test/res/layout/main.xml b/test/res/layout/main.xml new file mode 100755 index 00000000..d3063e06 --- /dev/null +++ b/test/res/layout/main.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/test/res/values/strings.xml b/test/res/values/strings.xml new file mode 100755 index 00000000..010e98e0 --- /dev/null +++ b/test/res/values/strings.xml @@ -0,0 +1,4 @@ + + + CordovaTests + diff --git a/test/res/xml/cordova.xml b/test/res/xml/cordova.xml new file mode 100755 index 00000000..c7b50000 --- /dev/null +++ b/test/res/xml/cordova.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/test/res/xml/plugins.xml b/test/res/xml/plugins.xml new file mode 100755 index 00000000..8829164a --- /dev/null +++ b/test/res/xml/plugins.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/test/src/org/apache/cordova/test/ActivityPlugin.java b/test/src/org/apache/cordova/test/ActivityPlugin.java new file mode 100755 index 00000000..9c260476 --- /dev/null +++ b/test/src/org/apache/cordova/test/ActivityPlugin.java @@ -0,0 +1,81 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import org.apache.cordova.api.LOG; +import org.json.JSONArray; +import org.json.JSONException; + +import android.content.Intent; + +import com.phonegap.api.Plugin; +import com.phonegap.api.PluginResult; + +/** + * This class provides a service. + */ +public class ActivityPlugin extends Plugin { + + static String TAG = "ActivityPlugin"; + + /** + * Constructor. + */ + public ActivityPlugin() { + } + + /** + * Executes the request and returns PluginResult. + * + * @param action The action to execute. + * @param args JSONArry of arguments for the plugin. + * @param callbackId The callback id used when calling back into JavaScript. + * @return A PluginResult object with a status and message. + */ + @Override + public PluginResult execute(String action, JSONArray args, String callbackId) { + PluginResult.Status status = PluginResult.Status.OK; + String result = ""; + + try { + if (action.equals("start")) { + this.startActivity(args.getString(0)); + } + return new PluginResult(status, result); + } catch (JSONException e) { + return new PluginResult(PluginResult.Status.JSON_EXCEPTION); + } + } + + // -------------------------------------------------------------------------- + // LOCAL METHODS + // -------------------------------------------------------------------------- + + public void startActivity(String className) { + try { + Intent intent = new Intent().setClass(this.ctx.getContext(), Class.forName(className)); + LOG.d(TAG, "Starting activity %s", className); + this.ctx.startActivity(intent); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + LOG.e(TAG, "Error starting activity %s", className); + } + } + +} diff --git a/test/src/org/apache/cordova/test/FixWebView.java b/test/src/org/apache/cordova/test/FixWebView.java new file mode 100755 index 00000000..46f155bf --- /dev/null +++ b/test/src/org/apache/cordova/test/FixWebView.java @@ -0,0 +1,43 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.content.Context; +import android.webkit.WebView; + +public class FixWebView extends WebView { + + public FixWebView(Context context) { + super(context); + } + + @Override + public void pauseTimers() { + // Do nothing + } + + /** + * This method is with different signature in order to stop the timers while move application to background + * @param realPause + */ + public void pauseTimers(@SuppressWarnings("unused") boolean realPause) { + super.pauseTimers(); + } + +} diff --git a/test/src/org/apache/cordova/test/backbuttonmultipage.java b/test/src/org/apache/cordova/test/backbuttonmultipage.java new file mode 100755 index 00000000..149501c3 --- /dev/null +++ b/test/src/org/apache/cordova/test/backbuttonmultipage.java @@ -0,0 +1,30 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class backbuttonmultipage extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.loadUrl("file:///android_asset/www/backbuttonmultipage/index.html"); + } +} diff --git a/test/src/org/apache/cordova/test/background.java b/test/src/org/apache/cordova/test/background.java new file mode 100755 index 00000000..2b95a5fc --- /dev/null +++ b/test/src/org/apache/cordova/test/background.java @@ -0,0 +1,34 @@ +/* + 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. + */ +package org.apache.cordova.test; + +import android.os.Bundle; +import android.webkit.WebView; + +import org.apache.cordova.*; + +public class background extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + //super.init(new FixWebView(this), new CordovaWebViewClient(this), new CordovaChromeClient(this)); + super.setBooleanProperty("keepRunning", false); + super.loadUrl("file:///android_asset/www/background/index.html"); + } +} diff --git a/test/src/org/apache/cordova/test/errorurl.java b/test/src/org/apache/cordova/test/errorurl.java new file mode 100755 index 00000000..b30a4441 --- /dev/null +++ b/test/src/org/apache/cordova/test/errorurl.java @@ -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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class errorurl extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.init(); + this.setStringProperty("errorUrl", "file:///android_asset/www/htmlnotfound/error.html"); + super.loadUrl("file:///android_asset/www/htmlnotfound/index.html"); + } +} diff --git a/test/src/org/apache/cordova/test/htmlnotfound.java b/test/src/org/apache/cordova/test/htmlnotfound.java new file mode 100755 index 00000000..4551ca36 --- /dev/null +++ b/test/src/org/apache/cordova/test/htmlnotfound.java @@ -0,0 +1,31 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class htmlnotfound extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.init(); + super.loadUrl("file:///android_asset/www/htmlnotfound/index.html"); + } +} diff --git a/test/src/org/apache/cordova/test/iframe.java b/test/src/org/apache/cordova/test/iframe.java new file mode 100755 index 00000000..de854fc2 --- /dev/null +++ b/test/src/org/apache/cordova/test/iframe.java @@ -0,0 +1,30 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class iframe extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.loadUrl("file:///android_asset/www/iframe/index.html"); + } +} diff --git a/test/src/org/apache/cordova/test/jqmtabbackbutton.java b/test/src/org/apache/cordova/test/jqmtabbackbutton.java new file mode 100755 index 00000000..e2bfeae1 --- /dev/null +++ b/test/src/org/apache/cordova/test/jqmtabbackbutton.java @@ -0,0 +1,30 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class jqmtabbackbutton extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.loadUrl("file:///android_asset/www/jqmtabbackbutton/index.html"); + } +} diff --git a/test/src/org/apache/cordova/test/lifecycle.java b/test/src/org/apache/cordova/test/lifecycle.java new file mode 100755 index 00000000..30c5b8ba --- /dev/null +++ b/test/src/org/apache/cordova/test/lifecycle.java @@ -0,0 +1,30 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class lifecycle extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.loadUrl("file:///android_asset/www/lifecycle/index.html"); + } +} diff --git a/test/src/org/apache/cordova/test/loading.java b/test/src/org/apache/cordova/test/loading.java new file mode 100755 index 00000000..b1b08aea --- /dev/null +++ b/test/src/org/apache/cordova/test/loading.java @@ -0,0 +1,31 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class loading extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.setStringProperty("loadingDialog", "Testing,Loading..."); + super.loadUrl("http://www.google.com"); + } +} diff --git a/test/src/org/apache/cordova/test/menus.java b/test/src/org/apache/cordova/test/menus.java new file mode 100755 index 00000000..06eb9b5c --- /dev/null +++ b/test/src/org/apache/cordova/test/menus.java @@ -0,0 +1,80 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import android.view.ContextMenu; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ContextMenu.ContextMenuInfo; + +import org.apache.cordova.*; +import org.apache.cordova.api.LOG; + +public class menus extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.init(); + super.registerForContextMenu(super.appView); + super.loadUrl("file:///android_asset/www/menus/index.html"); + } + + // Demonstrate how to add your own menus to app + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + int base = Menu.FIRST; + // Group, item id, order, title + menu.add(base, base, base, "Item1"); + menu.add(base, base + 1, base + 1, "Item2"); + menu.add(base, base + 2, base + 2, "Item3"); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + LOG.d("menus", "Item " + item.getItemId() + " pressed."); + this.appView.loadUrl("javascript:alert('Menu " + item.getItemId() + " pressed.')"); + return super.onOptionsItemSelected(item); + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + LOG.d("menus", "onPrepareOptionsMenu()"); + // this.appView.loadUrl("javascript:alert('onPrepareOptionsMenu()')"); + return true; + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo info) { + LOG.d("menus", "onCreateContextMenu()"); + menu.setHeaderTitle("Test Context Menu"); + menu.add(200, 200, 200, "Context Item1"); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + this.appView.loadUrl("javascript:alert('Context Menu " + item.getItemId() + " pressed.')"); + return true; + } + +} diff --git a/test/src/org/apache/cordova/test/splashscreen.java b/test/src/org/apache/cordova/test/splashscreen.java new file mode 100755 index 00000000..e3dc2ea0 --- /dev/null +++ b/test/src/org/apache/cordova/test/splashscreen.java @@ -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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class splashscreen extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.init(); + + // Show splashscreen + this.setIntegerProperty("splashscreen", R.drawable.sandy); + + super.loadUrl("file:///android_asset/www/splashscreen/index.html", 2000); + } +} diff --git a/test/src/org/apache/cordova/test/tests.java b/test/src/org/apache/cordova/test/tests.java new file mode 100755 index 00000000..4d7cba5b --- /dev/null +++ b/test/src/org/apache/cordova/test/tests.java @@ -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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class tests extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.init(); + super.pluginManager.addService("Activity", "org.apache.cordova.test.ActivityPlugin"); + super.loadUrl("file:///android_asset/www/index.html"); + } +} diff --git a/test/src/org/apache/cordova/test/timeout.java b/test/src/org/apache/cordova/test/timeout.java new file mode 100755 index 00000000..31edb8d5 --- /dev/null +++ b/test/src/org/apache/cordova/test/timeout.java @@ -0,0 +1,34 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class timeout extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.init(); + + // Short timeout to cause error + this.setIntegerProperty("loadUrlTimeoutValue", 10); + super.loadUrl("http://www.google.com"); + } +} diff --git a/test/src/org/apache/cordova/test/userwebview.java b/test/src/org/apache/cordova/test/userwebview.java new file mode 100755 index 00000000..8ea4ded1 --- /dev/null +++ b/test/src/org/apache/cordova/test/userwebview.java @@ -0,0 +1,72 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import android.webkit.WebView; +import android.webkit.GeolocationPermissions.Callback; + +import org.apache.cordova.*; +import org.apache.cordova.api.LOG; + +public class userwebview extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.init(new WebView(this), new TestViewClient(this), new TestChromeClient(this)); + super.loadUrl("file:///android_asset/www/userwebview/index.html"); + } + + public class TestChromeClient extends CordovaChromeClient { + public TestChromeClient(DroidGap arg0) { + super(arg0); + LOG.d("userwebview", "TestChromeClient()"); + } + + @Override + public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) { + LOG.d("userwebview", "onGeolocationPermissionsShowPrompt(" + origin + ")"); + super.onGeolocationPermissionsShowPrompt(origin, callback); + callback.invoke(origin, true, false); + } + } + + /** + * This class can be used to override the GapViewClient and receive notification of webview events. + */ + public class TestViewClient extends CordovaWebViewClient { + public TestViewClient(DroidGap arg0) { + super(arg0); + LOG.d("userwebview", "TestViewClient()"); + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + LOG.d("userwebview", "shouldOverrideUrlLoading(" + url + ")"); + return super.shouldOverrideUrlLoading(view, url); + } + + @Override + public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { + LOG.d("userwebview", "onReceivedError: Error code=" + errorCode + " Description=" + description + " URL=" + failingUrl); + super.onReceivedError(view, errorCode, description, failingUrl); + } + } + +} diff --git a/test/src/org/apache/cordova/test/whitelist.java b/test/src/org/apache/cordova/test/whitelist.java new file mode 100755 index 00000000..dc39db4e --- /dev/null +++ b/test/src/org/apache/cordova/test/whitelist.java @@ -0,0 +1,51 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import android.webkit.WebView; + +import org.apache.cordova.*; +import org.apache.cordova.api.LOG; + +public class whitelist extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.init(new WebView(this), new TestViewClient(this), new CordovaChromeClient(this)); + super.loadUrl("file:///android_asset/www/whitelist/index.html"); + } + + /** + * This class can be used to override the GapViewClient and receive notification of webview events. + */ + public class TestViewClient extends CordovaWebViewClient { + + public TestViewClient(DroidGap arg0) { + super(arg0); + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + LOG.d("whitelist", "shouldOverrideUrlLoading(" + url + ")"); + LOG.d("whitelist", "originalUrl=" + view.getOriginalUrl()); + return super.shouldOverrideUrlLoading(view, url); + } + } +} diff --git a/test/src/org/apache/cordova/test/xhr.java b/test/src/org/apache/cordova/test/xhr.java new file mode 100755 index 00000000..402e0ad2 --- /dev/null +++ b/test/src/org/apache/cordova/test/xhr.java @@ -0,0 +1,30 @@ +/* + 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. +*/ +package org.apache.cordova.test; + +import android.os.Bundle; +import org.apache.cordova.*; + +public class xhr extends DroidGap { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + super.loadUrl("file:///android_asset/www/xhr/index.html"); + } +} From 700ae50e9b2f48088495606e062757ebea46ae8d Mon Sep 17 00:00:00 2001 From: macdonst Date: Fri, 30 Mar 2012 15:29:26 -0400 Subject: [PATCH 06/11] CB-321: Media API: 'mediaSuccess' callback param to new Media() is called soon after new obj created --- framework/assets/js/cordova.android.js | 84 +++++++++++++------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/framework/assets/js/cordova.android.js b/framework/assets/js/cordova.android.js index 5ab3ac5e..ad185138 100644 --- a/framework/assets/js/cordova.android.js +++ b/framework/assets/js/cordova.android.js @@ -2901,7 +2901,7 @@ Media.get = function(id) { * Start or resume playing audio file. */ Media.prototype.play = function(options) { - exec(this.successCallback, this.errorCallback, "Media", "startPlayingAudio", [this.id, this.src, options]); + exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]); }; /** @@ -3512,8 +3512,9 @@ function Device() { this.cordova = null; var me = this; - this.getInfo( - function(info) { + + channel.onCordovaReady.subscribeOnce(function() { + me.getInfo(function(info) { me.available = true; me.platform = info.platform; me.version = info.version; @@ -3521,11 +3522,11 @@ function Device() { me.uuid = info.uuid; me.cordova = info.cordova; channel.onCordovaInfoReady.fire(); - }, - function(e) { + },function(e) { me.available = false; utils.alert("[ERROR] Error initializing Cordova: " + e); }); + }); } /** @@ -4498,46 +4499,47 @@ var exec = require('cordova/exec'), channel = require('cordova/channel'); var NetworkConnection = function () { - this.type = null; - this._firstRun = true; - this._timer = null; - this.timeout = 500; + this.type = null; + this._firstRun = true; + this._timer = null; + this.timeout = 500; - var me = this; + var me = this; - this.getInfo( - function (info) { - me.type = info; - if (info === "none") { - // set a timer if still offline at the end of timer send the offline event - me._timer = setTimeout(function(){ - cordova.fireDocumentEvent("offline"); - me._timer = null; - }, me.timeout); - } else { - // If there is a current offline event pending clear it - if (me._timer !== null) { - clearTimeout(me._timer); - me._timer = null; - } - cordova.fireDocumentEvent("online"); + channel.onCordovaReady.subscribeOnce(function() { + me.getInfo(function (info) { + me.type = info; + if (info === "none") { + // set a timer if still offline at the end of timer send the offline event + me._timer = setTimeout(function(){ + cordova.fireDocumentEvent("offline"); + me._timer = null; + }, me.timeout); + } else { + // If there is a current offline event pending clear it + if (me._timer !== null) { + clearTimeout(me._timer); + me._timer = null; } + cordova.fireDocumentEvent("online"); + } - // should only fire this once - if (me._firstRun) { - me._firstRun = false; - channel.onCordovaConnectionReady.fire(); - } - }, - function (e) { - // If we can't get the network info we should still tell Cordova - // to fire the deviceready event. - if (me._firstRun) { - me._firstRun = false; - channel.onCordovaConnectionReady.fire(); - } - console.log("Error initializing Network Connection: " + e); - }); + // should only fire this once + if (me._firstRun) { + me._firstRun = false; + channel.onCordovaConnectionReady.fire(); + } + }, + function (e) { + // If we can't get the network info we should still tell Cordova + // to fire the deviceready event. + if (me._firstRun) { + me._firstRun = false; + channel.onCordovaConnectionReady.fire(); + } + console.log("Error initializing Network Connection: " + e); + }); + }); }; /** From 5fa77e97bd72c72da523357bf87a0667eefffffc Mon Sep 17 00:00:00 2001 From: macdonst Date: Fri, 30 Mar 2012 16:28:04 -0400 Subject: [PATCH 07/11] CB-163: contactFindOptions.filter does not work as expected on Android --- framework/src/org/apache/cordova/ContactAccessor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/framework/src/org/apache/cordova/ContactAccessor.java b/framework/src/org/apache/cordova/ContactAccessor.java index de515e9f..12669ce4 100644 --- a/framework/src/org/apache/cordova/ContactAccessor.java +++ b/framework/src/org/apache/cordova/ContactAccessor.java @@ -84,7 +84,8 @@ public abstract class ContactAccessor { map.put("displayName", true); } else if (key.startsWith("name")) { - map.put("name", true); + map.put("displayName", true); + map.put("name", true); } else if (key.startsWith("nickname")) { map.put("nickname", true); From a37d0699db783d09d6a311c6367a10255e9479e4 Mon Sep 17 00:00:00 2001 From: Bryce Curtis Date: Mon, 2 Apr 2012 11:34:57 -0500 Subject: [PATCH 08/11] [CB-423] Problem displaying patch-9 splash screen. --- framework/src/org/apache/cordova/CordovaChromeClient.java | 3 +++ framework/src/org/apache/cordova/CordovaWebViewClient.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/framework/src/org/apache/cordova/CordovaChromeClient.java b/framework/src/org/apache/cordova/CordovaChromeClient.java index e9f8f93e..2344c511 100755 --- a/framework/src/org/apache/cordova/CordovaChromeClient.java +++ b/framework/src/org/apache/cordova/CordovaChromeClient.java @@ -216,6 +216,9 @@ public class CordovaChromeClient extends WebChromeClient { // Cordova JS has initialized, so show webview // (This solves white flash seen when rendering HTML) else if (reqOk && defaultValue != null && defaultValue.equals("gap_init:")) { + if (ctx.splashscreen != 0) { + ctx.root.setBackgroundResource(0); + } ctx.appView.setVisibility(View.VISIBLE); ctx.spinnerStop(); result.confirm("OK"); diff --git a/framework/src/org/apache/cordova/CordovaWebViewClient.java b/framework/src/org/apache/cordova/CordovaWebViewClient.java index 5eb24064..6bddfc35 100755 --- a/framework/src/org/apache/cordova/CordovaWebViewClient.java +++ b/framework/src/org/apache/cordova/CordovaWebViewClient.java @@ -229,6 +229,9 @@ public class CordovaWebViewClient extends WebViewClient { Thread.sleep(2000); ctx.runOnUiThread(new Runnable() { public void run() { + if (ctx.splashscreen != 0) { + ctx.root.setBackgroundResource(0); + } ctx.appView.setVisibility(View.VISIBLE); ctx.spinnerStop(); } From 0577b4bf5db1f4e1420a1a906bf7333a7f459bc1 Mon Sep 17 00:00:00 2001 From: macdonst Date: Tue, 3 Apr 2012 13:02:25 -0400 Subject: [PATCH 09/11] CB-426: camera.getPicture ignores mediaType in 1.5 --- framework/src/org/apache/cordova/CameraLauncher.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/framework/src/org/apache/cordova/CameraLauncher.java b/framework/src/org/apache/cordova/CameraLauncher.java index 03cf1fb9..ba5d9243 100755 --- a/framework/src/org/apache/cordova/CameraLauncher.java +++ b/framework/src/org/apache/cordova/CameraLauncher.java @@ -31,8 +31,6 @@ import org.apache.cordova.api.Plugin; import org.apache.cordova.api.PluginResult; import org.json.JSONArray; import org.json.JSONException; -import org.json.JSONObject; - import android.app.Activity; import android.content.ContentValues; @@ -115,6 +113,7 @@ public class CameraLauncher extends Plugin { this.targetWidth = args.getInt(3); this.targetHeight = args.getInt(4); this.encodingType = args.getInt(5); + this.mediaType = args.getInt(6); if (srcType == CAMERA) { this.takePicture(destType, encodingType); From e213772f98975bf265bccff59f8c356b99c76f62 Mon Sep 17 00:00:00 2001 From: macdonst Date: Tue, 3 Apr 2012 13:09:31 -0400 Subject: [PATCH 10/11] Updating cordova.android.js for CB-421 and CB-426 --- framework/assets/js/cordova.android.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/framework/assets/js/cordova.android.js b/framework/assets/js/cordova.android.js index ad185138..edbee030 100644 --- a/framework/assets/js/cordova.android.js +++ b/framework/assets/js/cordova.android.js @@ -1116,10 +1116,14 @@ cameraExport.getPicture = function(successCallback, errorCallback, options) { if (typeof options.encodingType == "number") { encodingType = options.encodingType; } - // TODO: parse MediaType + + var mediaType = Camera.MediaType.PICTURE; + if (typeof options.mediaType == "number") { + mediaType = options.mediaType; + } // TODO: enable allow edit? - exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType]); + exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType, mediaType]); } module.exports = cameraExport; @@ -1997,10 +2001,15 @@ Entry.prototype.remove = function(successCallback, errorCallback) { * @param errorCallback {Function} called with a FileError */ Entry.prototype.getParent = function(successCallback, errorCallback) { + var win = typeof successCallback !== 'function' ? null : function(result) { + var DirectoryEntry = require('cordova/plugin/DirectoryEntry'); + var entry = new DirectoryEntry(result.name, result.fullPath); + successCallback(entry); + }; var fail = typeof errorCallback !== 'function' ? null : function(code) { errorCallback(new FileError(code)); }; - exec(successCallback, fail, "File", "getParent", [this.fullPath]); + exec(win, fail, "File", "getParent", [this.fullPath]); }; module.exports = Entry; From 04aa6d3c38bc53103d0a89b17fd28ad37222c460 Mon Sep 17 00:00:00 2001 From: macdonst Date: Wed, 4 Apr 2012 13:03:39 -0400 Subject: [PATCH 11/11] CB-438: File metadata.modificationTime returns an invalid date --- framework/src/org/apache/cordova/FileUtils.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/framework/src/org/apache/cordova/FileUtils.java b/framework/src/org/apache/cordova/FileUtils.java index 9334543c..b2aa990d 100755 --- a/framework/src/org/apache/cordova/FileUtils.java +++ b/framework/src/org/apache/cordova/FileUtils.java @@ -142,8 +142,7 @@ public class FileUtils extends Plugin { return new PluginResult(status, obj); } else if (action.equals("getMetadata")) { - JSONObject obj = getMetadata(args.getString(0)); - return new PluginResult(status, obj); + return new PluginResult(status, getMetadata(args.getString(0))); } else if (action.equals("getFileMetadata")) { JSONObject obj = getFileMetadata(args.getString(0)); @@ -764,21 +763,17 @@ public class FileUtils extends Plugin { * Look up metadata about this entry. * * @param filePath to entry - * @return a Metadata object + * @return a long * @throws FileNotFoundException - * @throws JSONException */ - private JSONObject getMetadata(String filePath) throws FileNotFoundException, JSONException { + private long getMetadata(String filePath) throws FileNotFoundException { File file = createFileObject(filePath); if (!file.exists()) { throw new FileNotFoundException("Failed to find file in getMetadata"); } - JSONObject metadata = new JSONObject(); - metadata.put("modificationTime", file.lastModified()); - - return metadata; + return file.lastModified(); } /**